feat: add craft-goal session starter and command

Adds /craft-goal autocomplete and chat handling for starting a Goal crafting session.
Introduces new Magic Prompts content and localized labels/descriptions for Goal crafting.
Migrates desktop draft starters to include Craft a Goal once and persists the migration marker.
This commit is contained in:
Bohdan Triapitsyn
2026-07-12 10:58:58 +03:00
parent e8be7ef55b
commit a0bdcae54c
30 changed files with 210 additions and 3 deletions
+30 -2
View File
@@ -1255,7 +1255,7 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
const availableSkills = useSkillsStore((s) => s.skills);
const knownSlashNames = React.useMemo(() => {
const names = new Set<string>([
'init', 'review', 'undo', 'redo', 'timeline', 'compact', 'summary', 'workspace-review', 'plan-feature', 'catch-up', 'debug', 'weigh', 'explore',
'init', 'review', 'undo', 'redo', 'timeline', 'compact', 'summary', 'workspace-review', 'plan-feature', 'craft-goal', 'catch-up', 'debug', 'weigh', 'explore',
]);
if (!isMobile && !isVSCodeRuntime()) names.add('handoff-review');
for (const command of availableCommands) names.add(command.name.toLowerCase());
@@ -2165,6 +2165,32 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
}
return;
}
else if (commandName === 'craft-goal' && (currentSessionId || newSessionDraftOpen)) {
try {
await sessionActions.waitForConnectionOrThrow();
const idea = normalizedCommand.replace(/^\/craft-goal\b/i, '').trim();
const visibleText = await renderMagicPrompt('session.craftGoal.visible', {
idea_block: idea ? `\n\nHere is my initial idea:\n${idea}` : '',
});
const instructionsText = await renderMagicPrompt('session.craftGoal.instructions');
await sendMessage(
visibleText,
providerIdToSend,
modelIdToSend,
agentNameToSend,
[],
agentMentionName,
[{ text: instructionsText, synthetic: true }],
variantToSend,
inputMode,
sendMessageOptions,
);
scrollToBottom?.();
} catch (error) {
toast.error(error instanceof Error ? error.message : t('chat.chatInput.toast.craftGoalFailed'));
}
return;
}
else if (commandName === 'catch-up' && (currentSessionId || newSessionDraftOpen)) {
try {
await sessionActions.waitForConnectionOrThrow();
@@ -2388,7 +2414,9 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
// The text goes straight into the submit (see SubmitOptions.presetText)
// instead of through the composer input — the collapsed mobile pill has
// no mounted textarea to stage it in.
void handleSubmitRef.current({ presetText: text });
const draft = (textareaRef.current?.value ?? messageRef.current).trim();
const presetText = draft ? `${text}\n${draft}` : text;
void handleSubmitRef.current({ presetText });
}, []);
// Dictation: insert the transcript inline; optionally submit immediately.
@@ -166,6 +166,10 @@ export const CommandAutocomplete = React.forwardRef<CommandAutocompleteHandle, C
? [{ id: 'openchamber:plan-feature', name: 'plan-feature', source: 'openchamber' as const, description: t('chat.commandAutocomplete.command.featurePlanDescription'), isOpenChamber: true }]
: []
),
...(canStartSessionCommand
? [{ id: 'openchamber:craft-goal', name: 'craft-goal', source: 'openchamber' as const, description: t('chat.commandAutocomplete.command.craftGoalDescription'), isOpenChamber: true }]
: []
),
...(canStartSessionCommand
? [{ id: 'openchamber:catch-up', name: 'catch-up', source: 'openchamber' as const, description: t('chat.commandAutocomplete.command.catchUpDescription'), isOpenChamber: true }]
: []
@@ -235,6 +239,10 @@ export const CommandAutocomplete = React.forwardRef<CommandAutocompleteHandle, C
? [{ id: 'openchamber:plan-feature', name: 'plan-feature', source: 'openchamber' as const, description: t('chat.commandAutocomplete.command.featurePlanDescription'), isOpenChamber: true }]
: []
),
...(canStartSessionCommand
? [{ id: 'openchamber:craft-goal', name: 'craft-goal', source: 'openchamber' as const, description: t('chat.commandAutocomplete.command.craftGoalDescription'), isOpenChamber: true }]
: []
),
...(canStartSessionCommand
? [{ id: 'openchamber:catch-up', name: 'catch-up', source: 'openchamber' as const, description: t('chat.commandAutocomplete.command.catchUpDescription'), isOpenChamber: true }]
: []
@@ -148,6 +148,14 @@ const PROMPT_PAGE_MAP: Record<string, PromptPageConfig> = {
{ id: 'session.plan.instructions', titleKey: 'settings.magicPrompts.page.block.instructions' },
],
},
'session.craftGoal': {
titleKey: 'settings.magicPrompts.page.group.sessionCraftGoal.title',
descriptionKey: 'settings.magicPrompts.page.group.sessionCraftGoal.description',
blocks: [
{ id: 'session.craftGoal.visible', titleKey: 'settings.magicPrompts.page.block.visiblePrompt' },
{ id: 'session.craftGoal.instructions', titleKey: 'settings.magicPrompts.page.block.instructions' },
],
},
'session.catchup': {
titleKey: 'settings.magicPrompts.page.group.sessionCatchUp.title',
descriptionKey: 'settings.magicPrompts.page.group.sessionCatchUp.description',
@@ -49,6 +49,7 @@ export const MagicPromptsSidebar: React.FC<MagicPromptsSidebarProps> = ({ onItem
{ id: 'session.summary', titleKey: 'settings.magicPrompts.sidebar.item.sessionSummary' },
{ id: 'session.review', titleKey: 'settings.magicPrompts.sidebar.item.sessionWorkspaceReview' },
{ id: 'session.plan', titleKey: 'settings.magicPrompts.sidebar.item.sessionFeaturePlan' },
{ id: 'session.craftGoal', titleKey: 'settings.magicPrompts.sidebar.item.sessionCraftGoal' },
{ id: 'session.catchup', titleKey: 'settings.magicPrompts.sidebar.item.sessionCatchUp' },
{ id: 'session.debug', titleKey: 'settings.magicPrompts.sidebar.item.sessionDebug' },
{ id: 'session.weigh', titleKey: 'settings.magicPrompts.sidebar.item.sessionWeigh' },
+1
View File
@@ -674,6 +674,7 @@ export interface SettingsPayload {
pwaAppName?: string;
mobileKeyboardMode?: 'native' | 'resize-content';
draftStarters?: DraftStarterRef[];
draftStartersCraftGoalAdded?: boolean;
[key: string]: unknown;
}
+2
View File
@@ -198,6 +198,8 @@ export type DesktopSettings = {
sttLanguage?: string;
// Global draft welcome starters (pinned commands/skills), persisted to settings.json
draftStarters?: DraftStarterRef[];
// One-time migration marker: Craft a Goal was offered in the starter row.
draftStartersCraftGoalAdded?: boolean;
};
type DesktopBridgeGlobal = {
+1
View File
@@ -27,6 +27,7 @@ export const BUILTIN_STARTERS: readonly BuiltInStarter[] = [
{ name: 'catch-up', icon: 'history', labelKey: 'chat.draftPresets.catchup.label', command: '/catch-up' },
{ name: 'weigh', icon: 'scales-3', labelKey: 'chat.draftPresets.weigh.label', command: '/weigh' },
{ name: 'plan-feature', icon: 'survey', labelKey: 'chat.draftPresets.plan.label', command: '/plan-feature' },
{ name: 'craft-goal', icon: 'target', labelKey: 'chat.draftPresets.craftGoal.label', command: '/craft-goal' },
{ name: 'debug', icon: 'bug', labelKey: 'chat.draftPresets.debug.label', command: '/debug' },
{ name: 'review', icon: 'search-eye', labelKey: 'chat.draftPresets.review.label', command: '/workspace-review' },
];
@@ -231,6 +231,9 @@ export const settingsDict = {
'settings.magicPrompts.sidebar.item.sessionWorkspaceReview': 'Workspace Review',
'settings.magicPrompts.sidebar.item.sessionExplore': 'Codebase Tour',
'settings.magicPrompts.sidebar.item.sessionFeaturePlan': 'Feature Planning',
'settings.magicPrompts.sidebar.item.sessionCraftGoal': 'Goal Crafting',
'settings.magicPrompts.page.group.sessionCraftGoal.title': 'Goal Crafting',
'settings.magicPrompts.page.group.sessionCraftGoal.description': 'Prompts used by the /craft-goal slash command: visible user message + hidden instructions. Turns an idea or task into a clear, evidence-verifiable Goal through guided discovery.',
'settings.magicPrompts.sidebar.item.sessionCatchUp': 'Catch Up',
'settings.magicPrompts.sidebar.item.sessionDebug': 'Debugging',
'settings.magicPrompts.sidebar.item.sessionWeigh': 'Weigh Options',
+3
View File
@@ -1742,6 +1742,7 @@ export const dict = {
'chat.draftPresets.catchup.label': 'Catch me up',
'chat.draftPresets.weigh.label': 'Weigh my options',
'chat.draftPresets.plan.label': 'Start feature planning',
'chat.draftPresets.craftGoal.label': 'Craft a Goal',
'chat.draftPresets.debug.label': 'Debug an issue',
'chat.draftPresets.review.label': 'Review my changes',
'chat.draftStarters.add': 'Add a starter',
@@ -1813,6 +1814,8 @@ export const dict = {
'chat.commandAutocomplete.command.workspaceReviewDescription': 'Review the workspace diff for intent, correctness, and adequacy, graded by severity.',
'chat.commandAutocomplete.command.handoffReviewDescription': 'Create or reuse a separate review session from a generated handoff.',
'chat.commandAutocomplete.command.featurePlanDescription': 'Start a guided, back-and-forth planning session for a new feature.',
'chat.commandAutocomplete.command.craftGoalDescription': 'Turn an idea or task into a clear, verifiable Goal.',
'chat.chatInput.toast.craftGoalFailed': 'Failed to start Goal crafting',
'chat.commandAutocomplete.command.catchUpDescription': 'Re-establish context: what you were doing and where to pick up.',
'chat.commandAutocomplete.command.debugDescription': 'Guided root-cause investigation for a bug before proposing a fix.',
'chat.commandAutocomplete.command.weighDescription': 'Weigh 2-3 approaches with trade-offs and a recommendation before you commit.',
@@ -198,6 +198,9 @@ export const settingsDict = {
"settings.magicPrompts.sidebar.item.sessionWorkspaceReview": "Revisión del espacio de trabajo",
"settings.magicPrompts.sidebar.item.sessionExplore": "Recorrido del código",
"settings.magicPrompts.sidebar.item.sessionFeaturePlan": "Planificación de funciones",
"settings.magicPrompts.sidebar.item.sessionCraftGoal": "Creación de Goal",
"settings.magicPrompts.page.group.sessionCraftGoal.title": "Creación de Goal",
"settings.magicPrompts.page.group.sessionCraftGoal.description": "Prompts usados por el comando /craft-goal: mensaje visible del usuario + instrucciones ocultas. Convierte una idea o tarea en un Goal claro y verificable mediante un diálogo guiado.",
"settings.magicPrompts.sidebar.item.sessionCatchUp": "Ponerse al día",
"settings.magicPrompts.sidebar.item.sessionDebug": "Depuración",
"settings.magicPrompts.sidebar.item.sessionWeigh": "Comparar enfoques",
+3
View File
@@ -1720,6 +1720,7 @@ export const dict: Record<I18nKey, string> = {
"chat.draftPresets.catchup.label": "Catch me up",
"chat.draftPresets.weigh.label": "Weigh my options",
"chat.draftPresets.plan.label": "Start feature planning",
"chat.draftPresets.craftGoal.label": "Crear un Goal",
"chat.draftPresets.debug.label": "Debug an issue",
"chat.draftPresets.review.label": "Review my changes",
"chat.draftStarters.add": "Add a starter",
@@ -1791,6 +1792,8 @@ export const dict: Record<I18nKey, string> = {
"chat.commandAutocomplete.command.workspaceReviewDescription": "Revisa el diff del espacio de trabajo en intención, corrección y adecuación, con hallazgos por severidad.",
"chat.commandAutocomplete.command.handoffReviewDescription": "Crea o reutiliza una sesión de revisión separada a partir de un handoff generado.",
"chat.commandAutocomplete.command.featurePlanDescription": "Inicia una sesión de planificación guiada e interactiva para una nueva función.",
"chat.commandAutocomplete.command.craftGoalDescription": "Convierte una idea o tarea en un Goal claro y verificable.",
"chat.chatInput.toast.craftGoalFailed": "No se pudo iniciar la creación del Goal",
"chat.commandAutocomplete.command.catchUpDescription": "Recupera el contexto: qué estabas haciendo y por dónde continuar.",
"chat.commandAutocomplete.command.debugDescription": "Investigación guiada de la causa raíz de un error antes de proponer una solución.",
"chat.commandAutocomplete.command.weighDescription": "Compara 2-3 enfoques con sus ventajas y desventajas y una recomendación antes de decidir.",
@@ -1768,6 +1768,9 @@ export const settingsDict = {
'settings.openchamber.tunnel.notAvailable.dependencyNotFound': '{dependency} est introuvable.',
'settings.magicPrompts.sidebar.item.sessionExplore': 'Tour du codebase',
'settings.magicPrompts.sidebar.item.sessionFeaturePlan': 'Planification de fonctionnalité',
'settings.magicPrompts.sidebar.item.sessionCraftGoal': 'Création de Goal',
'settings.magicPrompts.page.group.sessionCraftGoal.title': 'Création de Goal',
'settings.magicPrompts.page.group.sessionCraftGoal.description': 'Prompts utilisés par la commande slash /craft-goal : message utilisateur visible + instructions masquées. Transforme une idée ou une tâche en Goal clair et vérifiable grâce à une exploration guidée.',
'settings.magicPrompts.sidebar.item.sessionCatchUp': 'Rattrapage',
'settings.magicPrompts.sidebar.item.sessionDebug': 'Débogage',
'settings.magicPrompts.sidebar.item.sessionWeigh': 'Comparer les options',
+3
View File
@@ -2718,6 +2718,7 @@ export const dict = {
'chat.draftPresets.catchup.label': 'Me remettre à niveau',
'chat.draftPresets.weigh.label': 'Comparer mes options',
'chat.draftPresets.plan.label': 'Lancer la planification de fonctionnalité',
'chat.draftPresets.craftGoal.label': 'Créer un Goal',
'chat.draftPresets.debug.label': 'Déboguer un problème',
'chat.draftPresets.review.label': 'Revoir mes modifications',
'chat.draftStarters.add': 'Ajouter un démarrage',
@@ -2729,6 +2730,8 @@ export const dict = {
'chat.draftStarters.remove': 'Retirer',
'chat.commandAutocomplete.command.handoffReviewDescription': 'Créer ou réutiliser une session de revue séparée à partir dun handoff généré.',
'chat.commandAutocomplete.command.featurePlanDescription': 'Lancer une session guidée et interactive de planification pour une nouvelle fonctionnalité.',
'chat.commandAutocomplete.command.craftGoalDescription': 'Transformer une idée ou une tâche en Goal clair et vérifiable.',
'chat.chatInput.toast.craftGoalFailed': 'Impossible de démarrer la création du Goal',
'chat.commandAutocomplete.command.catchUpDescription': 'Rétablir le contexte : ce que vous faisiez et où reprendre.',
'chat.commandAutocomplete.command.debugDescription': 'Investigation guidée de la cause racine dun bug avant de proposer une correction.',
'chat.commandAutocomplete.command.weighDescription': 'Comparer 2 à 3 approches avec compromis et recommandation avant de vous engager.',
@@ -231,6 +231,9 @@ export const settingsDict = {
'settings.magicPrompts.sidebar.item.sessionWorkspaceReview': 'Workspace レビュー',
'settings.magicPrompts.sidebar.item.sessionExplore': 'コードベースツアー',
'settings.magicPrompts.sidebar.item.sessionFeaturePlan': '機能計画',
'settings.magicPrompts.sidebar.item.sessionCraftGoal': 'Goal の作成',
'settings.magicPrompts.page.group.sessionCraftGoal.title': 'Goal の作成',
'settings.magicPrompts.page.group.sessionCraftGoal.description': '/craft-goal スラッシュコマンドで使用するプロンプト: 表示ユーザーメッセージ + 非表示指示。ガイド付き対話でアイデアやタスクを明確で証拠により検証可能な Goal に変換します。',
'settings.magicPrompts.sidebar.item.sessionCatchUp': 'キャッチアップ',
'settings.magicPrompts.sidebar.item.sessionDebug': 'デバッグ',
'settings.magicPrompts.sidebar.item.sessionWeigh': '選択肢の比較',
+3
View File
@@ -1738,6 +1738,7 @@ export const dict: Record<I18nKey, string> = {
'chat.draftPresets.catchup.label': '状況を把握',
'chat.draftPresets.weigh.label': '選択肢を比較検討',
'chat.draftPresets.plan.label': '機能の計画を開始',
'chat.draftPresets.craftGoal.label': 'Goal を作成',
'chat.draftPresets.debug.label': '問題をデバッグ',
'chat.draftPresets.review.label': '変更をレビュー',
'chat.draftStarters.add': 'スターターを追加',
@@ -1809,6 +1810,8 @@ export const dict: Record<I18nKey, string> = {
'chat.commandAutocomplete.command.workspaceReviewDescription': 'ワークスペースの差分を意図、正確性、妥当性について重大度で評価。',
'chat.commandAutocomplete.command.handoffReviewDescription': '生成されたハンドオフから別のレビューセッションを作成または再利用。',
'chat.commandAutocomplete.command.featurePlanDescription': '新機能のガイド付き対話型計画セッションを開始。',
'chat.commandAutocomplete.command.craftGoalDescription': 'アイデアやタスクを明確で検証可能な Goal に変換します。',
'chat.chatInput.toast.craftGoalFailed': 'Goal の作成を開始できませんでした',
'chat.commandAutocomplete.command.catchUpDescription': 'コンテキストを再確立: 何をしていたか、どこから再開するか。',
'chat.commandAutocomplete.command.debugDescription': '修正を提案する前に、バグのガイド付き根本原因調査。',
'chat.commandAutocomplete.command.weighDescription': 'トレードオフと推奨事項を含む2~3のアプローチを比較検討してからコミット。',
@@ -198,6 +198,9 @@ export const settingsDict = {
'settings.magicPrompts.sidebar.item.sessionWorkspaceReview': '워크스페이스 리뷰',
'settings.magicPrompts.sidebar.item.sessionExplore': '코드베이스 둘러보기',
'settings.magicPrompts.sidebar.item.sessionFeaturePlan': '기능 계획',
'settings.magicPrompts.sidebar.item.sessionCraftGoal': 'Goal 만들기',
'settings.magicPrompts.page.group.sessionCraftGoal.title': 'Goal 만들기',
'settings.magicPrompts.page.group.sessionCraftGoal.description': '/craft-goal slash command에서 사용하는 프롬프트입니다: 표시 사용자 메시지 + 숨겨진 지침. 가이드 대화를 통해 아이디어나 작업을 명확하고 증거로 검증 가능한 Goal로 만듭니다.',
'settings.magicPrompts.sidebar.item.sessionCatchUp': '따라잡기',
'settings.magicPrompts.sidebar.item.sessionDebug': '디버깅',
'settings.magicPrompts.sidebar.item.sessionWeigh': '옵션 비교',
+3
View File
@@ -1744,6 +1744,7 @@ export const dict: Record<I18nKey, string> = {
'chat.draftPresets.catchup.label': 'Catch me up',
'chat.draftPresets.weigh.label': 'Weigh my options',
'chat.draftPresets.plan.label': 'Start feature planning',
'chat.draftPresets.craftGoal.label': 'Goal 만들기',
'chat.draftPresets.debug.label': 'Debug an issue',
'chat.draftPresets.review.label': 'Review my changes',
'chat.draftStarters.add': 'Add a starter',
@@ -1815,6 +1816,8 @@ export const dict: Record<I18nKey, string> = {
'chat.commandAutocomplete.command.workspaceReviewDescription': '워크스페이스 diff의 의도, 정확성, 적절성을 검토하고 심각도별로 분류합니다.',
'chat.commandAutocomplete.command.handoffReviewDescription': '생성된 인수인계로 별도의 리뷰 세션을 만들거나 재사용합니다.',
'chat.commandAutocomplete.command.featurePlanDescription': '새 기능을 위한 대화형 가이드 계획 세션을 시작합니다.',
'chat.commandAutocomplete.command.craftGoalDescription': '아이디어나 작업을 명확하고 검증 가능한 Goal로 만듭니다.',
'chat.chatInput.toast.craftGoalFailed': 'Goal 만들기를 시작하지 못했습니다',
'chat.commandAutocomplete.command.catchUpDescription': '맥락을 다시 파악합니다: 무엇을 하고 있었고 어디서 이어서 할지.',
'chat.commandAutocomplete.command.debugDescription': '수정안을 제시하기 전에 버그의 근본 원인을 단계적으로 조사합니다.',
'chat.commandAutocomplete.command.weighDescription': '결정하기 전에 2~3가지 접근 방식을 장단점과 함께 비교하고 추천을 제시합니다.',
@@ -353,6 +353,9 @@ export const settingsDict = {
'settings.magicPrompts.sidebar.item.sessionWorkspaceReview': 'Przegląd obszaru roboczego',
'settings.magicPrompts.sidebar.item.sessionExplore': 'Przegląd bazy kodu',
'settings.magicPrompts.sidebar.item.sessionFeaturePlan': 'Planowanie funkcji',
'settings.magicPrompts.sidebar.item.sessionCraftGoal': 'Tworzenie Goal',
'settings.magicPrompts.page.group.sessionCraftGoal.title': 'Tworzenie Goal',
'settings.magicPrompts.page.group.sessionCraftGoal.description': 'Prompty używane przez polecenie /craft-goal: widoczna wiadomość użytkownika + ukryte instrukcje. Przekształca pomysł lub zadanie w jasny, oparty na dowodach Goal poprzez prowadzoną rozmowę.',
'settings.magicPrompts.sidebar.item.sessionCatchUp': 'Nadrobienie kontekstu',
'settings.magicPrompts.sidebar.item.sessionDebug': 'Debugowanie',
'settings.magicPrompts.sidebar.item.sessionWeigh': 'Rozważanie opcji',
+3
View File
@@ -639,6 +639,7 @@ export const dict: Record<I18nKey, string> = {
'chat.draftPresets.catchup.label': 'Catch me up',
'chat.draftPresets.weigh.label': 'Weigh my options',
'chat.draftPresets.plan.label': 'Start feature planning',
'chat.draftPresets.craftGoal.label': 'Utwórz Goal',
'chat.draftPresets.debug.label': 'Debug an issue',
'chat.draftPresets.review.label': 'Review my changes',
'chat.draftStarters.add': 'Add a starter',
@@ -709,6 +710,8 @@ export const dict: Record<I18nKey, string> = {
'chat.commandAutocomplete.command.workspaceReviewDescription': 'Sprawdź diff obszaru roboczego pod kątem zamiaru, poprawności i adekwatności — ze znaleziskami według wagi.',
'chat.commandAutocomplete.command.handoffReviewDescription': 'Utwórz lub użyj ponownie osobnej sesji przeglądu z wygenerowanego handoffu.',
'chat.commandAutocomplete.command.featurePlanDescription': 'Rozpocznij prowadzoną, interaktywną sesję planowania nowej funkcji.',
'chat.commandAutocomplete.command.craftGoalDescription': 'Przekształć pomysł lub zadanie w jasny, weryfikowalny Goal.',
'chat.chatInput.toast.craftGoalFailed': 'Nie udało się rozpocząć tworzenia Goal',
'chat.commandAutocomplete.command.catchUpDescription': 'Przywróć kontekst: nad czym pracowałeś i od czego kontynuować.',
'chat.commandAutocomplete.command.debugDescription': 'Prowadzone badanie pierwotnej przyczyny błędu przed zaproponowaniem poprawki.',
'chat.commandAutocomplete.command.weighDescription': 'Rozważ 2-3 podejścia z kompromisami i rekomendacją, zanim się zdecydujesz.',
@@ -198,6 +198,9 @@ export const settingsDict = {
"settings.magicPrompts.sidebar.item.sessionWorkspaceReview": "Revisão do workspace",
"settings.magicPrompts.sidebar.item.sessionExplore": "Tour do código",
"settings.magicPrompts.sidebar.item.sessionFeaturePlan": "Planejamento de funcionalidade",
"settings.magicPrompts.sidebar.item.sessionCraftGoal": "Criação de Goal",
"settings.magicPrompts.page.group.sessionCraftGoal.title": "Criação de Goal",
"settings.magicPrompts.page.group.sessionCraftGoal.description": "Prompts usados pelo comando /craft-goal: mensagem visível do usuário + instruções ocultas. Transforma uma ideia ou tarefa em um Goal claro e verificável por meio de descoberta guiada.",
"settings.magicPrompts.sidebar.item.sessionCatchUp": "Retomada de contexto",
"settings.magicPrompts.sidebar.item.sessionDebug": "Depuração",
"settings.magicPrompts.sidebar.item.sessionWeigh": "Comparar abordagens",
@@ -1720,6 +1720,7 @@ export const dict: Record<I18nKey, string> = {
"chat.draftPresets.catchup.label": "Catch me up",
"chat.draftPresets.weigh.label": "Weigh my options",
"chat.draftPresets.plan.label": "Start feature planning",
"chat.draftPresets.craftGoal.label": "Criar um Goal",
"chat.draftPresets.debug.label": "Debug an issue",
"chat.draftPresets.review.label": "Review my changes",
"chat.draftStarters.add": "Add a starter",
@@ -1791,6 +1792,8 @@ export const dict: Record<I18nKey, string> = {
"chat.commandAutocomplete.command.workspaceReviewDescription": "Revisa o diff do workspace quanto a intenção, correção e adequação, com achados por severidade.",
"chat.commandAutocomplete.command.handoffReviewDescription": "Crie ou reutilize uma sessão separada de revisão a partir de um handoff gerado.",
"chat.commandAutocomplete.command.featurePlanDescription": "Inicie uma sessão de planejamento guiada e interativa para uma nova funcionalidade.",
"chat.commandAutocomplete.command.craftGoalDescription": "Transforme uma ideia ou tarefa em um Goal claro e verificável.",
"chat.chatInput.toast.craftGoalFailed": "Não foi possível iniciar a criação do Goal",
"chat.commandAutocomplete.command.catchUpDescription": "Retome o contexto: o que você estava fazendo e por onde continuar.",
"chat.commandAutocomplete.command.debugDescription": "Investigação guiada da causa raiz de um bug antes de propor uma correção.",
"chat.commandAutocomplete.command.weighDescription": "Compare 2-3 abordagens com seus prós e contras e uma recomendação antes de decidir.",
@@ -198,6 +198,9 @@ export const settingsDict = {
"settings.magicPrompts.sidebar.item.sessionWorkspaceReview": "Огляд робочого простору",
"settings.magicPrompts.sidebar.item.sessionExplore": "Огляд кодової бази",
"settings.magicPrompts.sidebar.item.sessionFeaturePlan": "Планування фічі",
"settings.magicPrompts.sidebar.item.sessionCraftGoal": "Формування Goal",
"settings.magicPrompts.page.group.sessionCraftGoal.title": "Формування Goal",
"settings.magicPrompts.page.group.sessionCraftGoal.description": "Промпти для команди /craft-goal: видиме повідомлення користувача + приховані інструкції. Через кероване дослідження перетворює ідею або завдання на чіткий Goal, підтверджуваний доказами.",
"settings.magicPrompts.sidebar.item.sessionCatchUp": "Повернення в контекст",
"settings.magicPrompts.sidebar.item.sessionDebug": "Дебаг",
"settings.magicPrompts.sidebar.item.sessionWeigh": "Зважування варіантів",
+3
View File
@@ -1720,6 +1720,7 @@ export const dict: Record<I18nKey, string> = {
"chat.draftPresets.catchup.label": "Повернутись у контекст",
"chat.draftPresets.weigh.label": "Зважити варіанти",
"chat.draftPresets.plan.label": "Розпочати планування фічі",
"chat.draftPresets.craftGoal.label": "Сформувати Goal",
"chat.draftPresets.debug.label": "Дебаг проблеми",
"chat.draftPresets.review.label": "Переглянути мої зміни",
"chat.draftStarters.add": "Додати стартер",
@@ -1791,6 +1792,8 @@ export const dict: Record<I18nKey, string> = {
"chat.commandAutocomplete.command.workspaceReviewDescription": "Перевірити diff робочого простору на намір, коректність і адекватність — зі знахідками за рівнем критичності.",
"chat.commandAutocomplete.command.handoffReviewDescription": "Створити або повторно використати окрему сесію ревʼю зі згенерованого handoff.",
"chat.commandAutocomplete.command.featurePlanDescription": "Розпочати покрокову діалогову сесію планування нової фічі.",
"chat.commandAutocomplete.command.craftGoalDescription": "Перетворити ідею або завдання на чіткий Goal, який можна перевірити.",
"chat.chatInput.toast.craftGoalFailed": "Не вдалося розпочати формування Goal",
"chat.commandAutocomplete.command.catchUpDescription": "Повернутись у контекст: над чим працювали і звідки продовжити.",
"chat.commandAutocomplete.command.debugDescription": "Кероване дослідження першопричини бага перед тим, як пропонувати фікс.",
"chat.commandAutocomplete.command.weighDescription": "Зважити 2-3 підходи з trade-offs і рекомендацією перш ніж братися до роботи.",
@@ -198,6 +198,9 @@ export const settingsDict = {
'settings.magicPrompts.sidebar.item.sessionWorkspaceReview': '工作区审查',
'settings.magicPrompts.sidebar.item.sessionExplore': '代码库导览',
'settings.magicPrompts.sidebar.item.sessionFeaturePlan': '功能规划',
'settings.magicPrompts.sidebar.item.sessionCraftGoal': '创建 Goal',
'settings.magicPrompts.page.group.sessionCraftGoal.title': '创建 Goal',
'settings.magicPrompts.page.group.sessionCraftGoal.description': '由 /craft-goal 斜杠命令使用的提示词:可见用户消息 + 隐藏说明。通过引导式探索将想法或任务转化为清晰且有证据可验证的 Goal。',
'settings.magicPrompts.sidebar.item.sessionCatchUp': '快速回顾',
'settings.magicPrompts.sidebar.item.sessionDebug': '调试',
'settings.magicPrompts.sidebar.item.sessionWeigh': '权衡方案',
@@ -1708,6 +1708,7 @@ export const dict: Record<I18nKey, string> = {
'chat.draftPresets.catchup.label': 'Catch me up',
'chat.draftPresets.weigh.label': 'Weigh my options',
'chat.draftPresets.plan.label': 'Start feature planning',
'chat.draftPresets.craftGoal.label': '创建 Goal',
'chat.draftPresets.debug.label': 'Debug an issue',
'chat.draftPresets.review.label': 'Review my changes',
'chat.draftStarters.add': 'Add a starter',
@@ -1779,6 +1780,8 @@ export const dict: Record<I18nKey, string> = {
'chat.commandAutocomplete.command.workspaceReviewDescription': '审查工作区 diff 的意图、正确性与充分性,并按严重程度分级。',
'chat.commandAutocomplete.command.handoffReviewDescription': '根据生成的交接内容创建或复用独立的审查会话。',
'chat.commandAutocomplete.command.featurePlanDescription': '为新功能开始一次引导式的来回规划会话。',
'chat.commandAutocomplete.command.craftGoalDescription': '将想法或任务转化为清晰且可验证的 Goal。',
'chat.chatInput.toast.craftGoalFailed': '无法开始创建 Goal',
'chat.commandAutocomplete.command.catchUpDescription': '重新进入上下文:你之前在做什么、从哪里继续。',
'chat.commandAutocomplete.command.debugDescription': '在提出修复方案前,引导式地排查 bug 的根本原因。',
'chat.commandAutocomplete.command.weighDescription': '在动手前,权衡 2-3 种方案的利弊并给出推荐。',
@@ -195,6 +195,9 @@
'settings.magicPrompts.sidebar.item.sessionWorkspaceReview': '工作區審查',
'settings.magicPrompts.sidebar.item.sessionExplore': '程式碼庫導覽',
'settings.magicPrompts.sidebar.item.sessionFeaturePlan': '功能規劃',
'settings.magicPrompts.sidebar.item.sessionCraftGoal': '建立 Goal',
'settings.magicPrompts.page.group.sessionCraftGoal.title': '建立 Goal',
'settings.magicPrompts.page.group.sessionCraftGoal.description': '由 /craft-goal 斜線命令使用的提示詞:可見使用者訊息 + 隱藏說明。透過引導式探索將想法或任務轉化為清晰且有證據可驗證的 Goal。',
'settings.magicPrompts.sidebar.item.sessionCatchUp': '快速回顧',
'settings.magicPrompts.sidebar.item.sessionDebug': '除錯',
'settings.magicPrompts.sidebar.item.sessionWeigh': '權衡方案',
@@ -1712,6 +1712,7 @@ export const dict: Record<I18nKey, string> = {
'chat.draftPresets.catchup.label': 'Catch me up',
'chat.draftPresets.weigh.label': 'Weigh my options',
'chat.draftPresets.plan.label': 'Start feature planning',
'chat.draftPresets.craftGoal.label': '建立 Goal',
'chat.draftPresets.debug.label': 'Debug an issue',
'chat.draftPresets.review.label': 'Review my changes',
'chat.draftStarters.add': 'Add a starter',
@@ -1783,6 +1784,8 @@ export const dict: Record<I18nKey, string> = {
'chat.commandAutocomplete.command.workspaceReviewDescription': '審查工作區 diff 的意圖、正確性與充分性,並依嚴重程度分級。',
'chat.commandAutocomplete.command.handoffReviewDescription': '根據生成的交接內容建立或重用獨立的審查會話。',
'chat.commandAutocomplete.command.featurePlanDescription': '為新功能開始一次引導式的來回規劃工作階段。',
'chat.commandAutocomplete.command.craftGoalDescription': '將想法或任務轉化為清晰且可驗證的 Goal。',
'chat.chatInput.toast.craftGoalFailed': '無法開始建立 Goal',
'chat.commandAutocomplete.command.catchUpDescription': '重新進入上下文:你之前在做什麼、從哪裡繼續。',
'chat.commandAutocomplete.command.debugDescription': '在提出修復方案前,引導式地排查 bug 的根本原因。',
'chat.commandAutocomplete.command.weighDescription': '在動手前,權衡 2-3 種方案的利弊並給出推薦。',
+69
View File
@@ -37,6 +37,8 @@ export type MagicPromptId =
| 'session.implementationResponseToReviewer.visible'
| 'session.plan.visible'
| 'session.plan.instructions'
| 'session.craftGoal.visible'
| 'session.craftGoal.instructions'
| 'session.catchup.visible'
| 'session.catchup.instructions'
| 'session.debug.visible'
@@ -719,6 +721,73 @@ Run this as a dialogue, not a one-shot answer.
6. When everything is settled, produce the final implementation plan: a clear, ordered breakdown of the work, the files and areas affected, the decisions that were made (and why), known risks, and any remaining assumptions flagged explicitly. The plan must reflect the user's actual answers never fill gaps with guesses.
Respond in the same language the user uses.`,
},
{
id: 'session.craftGoal.visible',
title: 'Goal Crafting Visible Prompt',
group: 'Session',
description: 'Visible user message sent by the /craft-goal command.',
placeholders: [
{ key: 'idea_block', description: 'Optional initial task or idea supplied after the command.' },
],
template: `Help me turn an idea or task into a clear, verifiable Goal.{{idea_block}}`,
},
{
id: 'session.craftGoal.instructions',
title: 'Goal Crafting Instructions',
group: 'Session',
description: 'Hidden instructions attached to the /craft-goal command. Guides discovery and produces a ready-to-use Goal objective.',
template: `The user wants help turning a task, idea, or desired outcome into a strong Goal for an autonomous, multi-turn working session.
A Goal is a persistent completion contract, not an implementation plan and not a larger one-shot prompt. Help the user define what "done" means clearly enough that another agent can work toward it, verify it against evidence, continue through uncertain intermediate steps, and stop honestly when completion is blocked.
Run this as a guided dialogue, not a one-shot answer.
1. Start from the user's intent. If the visible message includes an initial idea, use it immediately. Otherwise ask what they want to accomplish. Do not ask them to formulate the Goal themselves.
2. Investigate before asking when context is available. For repository work, inspect relevant code, tests, scripts, documentation, and conventions when that would answer questions or expose constraints. Do not ask for information that can be determined reliably from the workspace.
3. Decide whether a Goal is appropriate. Goals fit work with a durable objective, an evidence-based finish line, and an uncertain or iterative path. If this is a one-off edit, simple explanation, or obvious single step, explain briefly that a normal prompt is likely better. Continue crafting a Goal if the user still wants one.
4. Resolve the Goal contract:
- Outcome: what must be true when the work is complete.
- Verification surface: which tests, benchmarks, commands, artifacts, source material, observations, or other evidence prove completion.
- Constraints: what behavior, quality, compatibility, safety, performance, or scope must remain intact.
- Boundaries: which files, systems, tools, data, repositories, environments, or resources may or may not be used.
- Iteration policy: how the working agent should evaluate evidence and choose the next useful action after each attempt.
- Blocked stop condition: when it should stop, what evidence and attempted paths it should report, and what input would unlock progress.
5. Ask only necessary questions, in batches of at most 3. Prefer concrete, decision-oriented questions. Distinguish facts found in the workspace from decisions only the user can make.
6. Do not over-prescribe the path. Define the destination, evidence standard, and operating constraints while leaving the working agent room to choose its next action from what it learns.
7. Do not invent precision. Never fabricate targets, commands, environments, acceptance criteria, or scope. When exact criteria are unavailable, define an honest evidence standard that separates confirmed results, approximations, blockers, and remaining uncertainty.
8. Do not implement the task. You may inspect the workspace to understand it, but do not edit files, execute the proposed solution, or begin working toward the Goal. This session's deliverable is the Goal itself.
9. Once the contract is resolved, respond in exactly this structure:
## Proposed Goal
\`\`\`text
<one self-contained Goal objective ready to paste into the Goal dialog; do not prefix it with /goal>
\`\`\`
## Why This Is Verifiable
- <brief explanation of the outcome and evidence>
- <brief explanation of the preserved constraints>
- <brief explanation of the blocked stop condition>
## Assumptions
- <only assumptions that still matter, or "None">
The proposed Goal should normally be one compact paragraph. Keep enough operational detail to make completion auditable, but remove conversational history, rationale, repetition, and implementation details that are not part of the completion contract.
Do not activate, execute, or claim completion of the proposed Goal. End by inviting the user to revise it or use it in the Goal dialog.
Respond in the same language the user uses.`,
},
{
+2
View File
@@ -205,6 +205,7 @@ describe('updateDesktopSettings', () => {
recentModels: [{ providerID: 'google', modelID: 'gemini-pro' }],
recentAgents: ['build', 'plan'],
recentEfforts: { 'anthropic/claude-haiku-4': ['high', 'default'] },
draftStartersCraftGoalAdded: true,
} satisfies SettingsPayload;
registerSettingsApi(async () => ({}), async () => ({ settings, source: 'web' }));
@@ -243,6 +244,7 @@ describe('updateDesktopSettings', () => {
expect(saveCalls).toHaveLength(1);
expect(saveCalls[0]).toEqual({
draftStartersCraftGoalAdded: true,
favoriteModels: [{ providerID: 'anthropic', modelID: 'claude-haiku-4' }],
hiddenModels: [{ providerID: 'openai', modelID: 'gpt-5' }],
collapsedModelProviders: ['openai'],
+28 -1
View File
@@ -595,10 +595,27 @@ const applyDesktopUiPreferences = (settings: DesktopSettings) => {
store.setFontSize(settings.fontSize);
}
if (Array.isArray(settings.draftStarters)) {
const nextStarters = sanitizeStarterRefs(settings.draftStarters);
let nextStarters = sanitizeStarterRefs(settings.draftStarters);
if (settings.draftStartersCraftGoalAdded !== true && !nextStarters.some((starter) => starter.type === 'command' && starter.name === 'craft-goal')) {
const planIndex = nextStarters.findIndex((starter) => starter.type === 'command' && starter.name === 'plan-feature');
const insertAt = planIndex >= 0 ? planIndex + 1 : nextStarters.length;
nextStarters = [
...nextStarters.slice(0, insertAt),
{ type: 'command', name: 'craft-goal' },
...nextStarters.slice(insertAt),
];
}
if (JSON.stringify(store.globalDraftStarters) !== JSON.stringify(nextStarters)) {
store.setGlobalDraftStarters(nextStarters);
}
if (settings.draftStartersCraftGoalAdded !== true) {
settings.draftStarters = nextStarters;
settings.draftStartersCraftGoalAdded = true;
}
} else if (settings.draftStartersCraftGoalAdded !== true) {
// The built-in default already contains Craft a Goal; only persist the marker
// so removing it later remains a durable user choice.
settings.draftStartersCraftGoalAdded = true;
}
if (typeof settings.terminalFontSize === 'number' && Number.isFinite(settings.terminalFontSize) && settings.terminalFontSize !== store.terminalFontSize) {
store.setTerminalFontSize(settings.terminalFontSize);
@@ -789,6 +806,9 @@ const sanitizeWebSettings = (payload: unknown): DesktopSettings | null => {
if (Array.isArray(candidate.draftStarters)) {
result.draftStarters = sanitizeStarterRefs(candidate.draftStarters);
}
if (typeof candidate.draftStartersCraftGoalAdded === 'boolean') {
result.draftStartersCraftGoalAdded = candidate.draftStartersCraftGoalAdded;
}
if (typeof candidate.showReasoningTraces === 'boolean') {
result.showReasoningTraces = candidate.showReasoningTraces;
}
@@ -1366,6 +1386,7 @@ export const syncDesktopSettings = async (): Promise<void> => {
// a TypeError from writing to a contextBridge-protected global) doesn't
// prevent server settings from reaching the Zustand store.
const applySettings = async (settings: DesktopSettings) => {
const shouldPersistCraftGoalMigration = settings.draftStartersCraftGoalAdded !== true;
try {
persistToLocalStorage(settings);
} catch (error) {
@@ -1377,6 +1398,12 @@ export const syncDesktopSettings = async (): Promise<void> => {
} catch (error) {
console.warn('applyDesktopUiPreferences failed:', error);
}
if (shouldPersistCraftGoalMigration) {
await updateDesktopSettings({
...(settings.draftStarters ? { draftStarters: settings.draftStarters } : {}),
draftStartersCraftGoalAdded: true,
});
}
dispatchSettingsSynced(settings);
};