From 8d1a6772c847234df6e0e669d4f35a6bebcc8f55 Mon Sep 17 00:00:00 2001 From: elkaix Date: Mon, 17 Aug 2026 05:43:09 -0400 Subject: [PATCH] feat(web): add starter suggestions to the empty conversation screen The empty session showed only a blank composer. It now offers four starter prompts below the hero text. A click fills the composer for editing and does not send the message. --- .changeset/web-empty-suggestions.md | 5 + .../src/components/ConversationPane.vue | 66 +++++- .../src/i18n/locales/en/suggestions.ts | 22 ++ apps/pythinker-web/src/i18n/locales/index.ts | 2 + .../test/empty-suggestions.test.ts | 194 ++++++++++++++++++ 5 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 .changeset/web-empty-suggestions.md create mode 100644 apps/pythinker-web/src/i18n/locales/en/suggestions.ts create mode 100644 apps/pythinker-web/test/empty-suggestions.test.ts diff --git a/.changeset/web-empty-suggestions.md b/.changeset/web-empty-suggestions.md new file mode 100644 index 00000000..7aff4b08 --- /dev/null +++ b/.changeset/web-empty-suggestions.md @@ -0,0 +1,5 @@ +--- +'@pymodel/pythinker-code': minor +--- + +Add starter suggestions to the empty conversation screen in the web UI. Each suggestion fills the composer for editing and does not send the message. diff --git a/apps/pythinker-web/src/components/ConversationPane.vue b/apps/pythinker-web/src/components/ConversationPane.vue index cddb00c1..94b39c88 100644 --- a/apps/pythinker-web/src/components/ConversationPane.vue +++ b/apps/pythinker-web/src/components/ConversationPane.vue @@ -162,6 +162,7 @@ function pickWorkspace(id: string): void { const { t } = useI18n(); const idleMascotSrc = useApngRestart('/brand/mascot-idle.png'); +const starterSuggestionKeys = ['explainRepository', 'suggestFirstTask', 'runChecks', 'reviewWorkingTree'] as const; // The align toggle was removed with its UI (6e50cb7) — reading layout is // always centered now. Drop the old persisted preference so users who once @@ -185,6 +186,10 @@ function loadComposerForEdit(value: string): void { (dockedComposerRef.value ?? emptyComposerRef.value)?.loadForEdit(value); } +function loadSuggestion(key: (typeof starterSuggestionKeys)[number]): void { + loadComposerForEdit(t(`suggestions.${key}.prompt`)); +} + function handleCopyConversationCopied(): void { copyConversationCopied.value = true; if (copyConversationCopiedTimer !== null) clearTimeout(copyConversationCopiedTimer); @@ -820,6 +825,19 @@ defineExpose({ loadComposerForEdit }); {{ t('composer.emptyConversationTitle') }} {{ t('composer.emptyConversation') }} +
+ +