feat: add /weigh approach-comparison command to draft welcome

Add /weigh as a draft chip and command for the moment before planning —
when you know what to build but not how. Its hidden prompt investigates
the code, then lays out 2-3 genuinely distinct approaches with trade-offs
(complexity, risk, blast radius, effort) and a clear recommendation,
without writing a plan or code.

Follows the established command pattern: visible + hidden magic prompts
wired into command autocomplete, the submit handler, draft preset chips,
and the Magic Prompts settings page, with i18n across all locales. Adds a
scales-3 icon to the sprite.
This commit is contained in:
Bohdan Triapitsyn
2026-05-30 02:04:32 +03:00
parent d524842935
commit b09c6b7047
22 changed files with 120 additions and 1 deletions
+24 -1
View File
@@ -101,6 +101,7 @@ type DraftPreset = {
const DRAFT_PRESETS: readonly DraftPreset[] = [
{ id: 'explore', icon: 'compass-3', labelKey: 'chat.draftPresets.explore.label', promptKey: 'chat.draftPresets.explore.prompt' },
{ id: 'catchup', icon: 'history', labelKey: 'chat.draftPresets.catchup.label', command: '/catch-up' },
{ id: 'weigh', icon: 'scales-3', labelKey: 'chat.draftPresets.weigh.label', command: '/weigh' },
{ id: 'plan', icon: 'survey', labelKey: 'chat.draftPresets.plan.label', command: '/plan-feature' },
{ id: 'debug', icon: 'bug', labelKey: 'chat.draftPresets.debug.label', command: '/debug' },
{ id: 'review', icon: 'search-eye', labelKey: 'chat.draftPresets.review.label', command: '/workspace-review' },
@@ -1123,7 +1124,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',
'init', 'review', 'undo', 'redo', 'timeline', 'compact', 'summary', 'workspace-review', 'plan-feature', 'catch-up', 'debug', 'weigh',
]);
for (const command of availableCommands) names.add(command.name.toLowerCase());
for (const skill of availableSkills) names.add(skill.name.toLowerCase());
@@ -2017,6 +2018,28 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
}
return;
}
else if (commandName === 'weigh' && (currentSessionId || newSessionDraftOpen)) {
try {
await sessionActions.waitForConnectionOrThrow();
const visibleText = await renderMagicPrompt('session.weigh.visible');
const instructionsText = await renderMagicPrompt('session.weigh.instructions');
await sendMessage(
visibleText,
providerIdToSend,
modelIdToSend,
agentNameToSend,
[],
agentMentionName,
[{ text: instructionsText, synthetic: true }],
variantToSend,
inputMode,
);
scrollToBottom?.();
} catch (error) {
toast.error(error instanceof Error ? error.message : t('chat.chatInput.toast.weighFailed'));
}
return;
}
}
const currentSessionDirectory = currentSessionId
@@ -164,6 +164,10 @@ export const CommandAutocomplete = React.forwardRef<CommandAutocompleteHandle, C
? [{ id: 'openchamber:debug', name: 'debug', source: 'openchamber' as const, description: t('chat.commandAutocomplete.command.debugDescription'), isOpenChamber: true }]
: []
),
...(canStartSessionCommand
? [{ id: 'openchamber:weigh', name: 'weigh', source: 'openchamber' as const, description: t('chat.commandAutocomplete.command.weighDescription'), isOpenChamber: true }]
: []
),
];
const allCommands = [...builtInCommands, ...customCommands, ...skillCommands];
@@ -221,6 +225,10 @@ export const CommandAutocomplete = React.forwardRef<CommandAutocompleteHandle, C
? [{ id: 'openchamber:debug', name: 'debug', source: 'openchamber' as const, description: t('chat.commandAutocomplete.command.debugDescription'), isOpenChamber: true }]
: []
),
...(canStartSessionCommand
? [{ id: 'openchamber:weigh', name: 'weigh', source: 'openchamber' as const, description: t('chat.commandAutocomplete.command.weighDescription'), isOpenChamber: true }]
: []
),
];
const filtered = (searchQuery