feat: add local workspace review slash command
Add /review command with high-signal diff review instructions Expose workspace review prompts in Magic Prompts settings Show /review in command autocomplete with OpenChamber command metadata
This commit is contained in:
@@ -1563,6 +1563,28 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (commandName === 'review' && currentSessionId) {
|
||||||
|
try {
|
||||||
|
await sessionActions.waitForConnectionOrThrow();
|
||||||
|
const visibleText = await renderMagicPrompt('session.review.visible');
|
||||||
|
const instructionsText = await renderMagicPrompt('session.review.instructions');
|
||||||
|
await sendMessage(
|
||||||
|
visibleText,
|
||||||
|
currentProviderId,
|
||||||
|
currentModelId,
|
||||||
|
currentAgentName,
|
||||||
|
[],
|
||||||
|
agentMentionName,
|
||||||
|
[{ text: instructionsText, synthetic: true }],
|
||||||
|
currentVariant,
|
||||||
|
inputMode,
|
||||||
|
);
|
||||||
|
scrollToBottom?.({ instant: true, force: true });
|
||||||
|
} catch (error) {
|
||||||
|
toast.error(error instanceof Error ? error.message : 'Failed to review changes');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect all attachments for error recovery
|
// Collect all attachments for error recovery
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { RiCommandLine, RiFileLine, RiFlashlightLine, RiRefreshLine, RiScissorsLine, RiTerminalBoxLine, RiArrowGoBackLine, RiArrowGoForwardLine } from '@remixicon/react';
|
import { RiCommandLine, RiFileLine, RiFlashlightLine, RiRefreshLine, RiScissorsLine, RiTerminalBoxLine, RiArrowGoBackLine, RiArrowGoForwardLine, RiSearchEyeLine } from '@remixicon/react';
|
||||||
import { cn, fuzzyMatch } from '@/lib/utils';
|
import { cn, fuzzyMatch } from '@/lib/utils';
|
||||||
import { useSessionUIStore } from '@/sync/session-ui-store';
|
import { useSessionUIStore } from '@/sync/session-ui-store';
|
||||||
import { useSessionMessages } from '@/sync/sync-context';
|
import { useSessionMessages } from '@/sync/sync-context';
|
||||||
@@ -122,6 +122,10 @@ export const CommandAutocomplete = React.forwardRef<CommandAutocompleteHandle, C
|
|||||||
? [{ id: 'openchamber:summary', name: 'summary', source: 'openchamber' as const, description: 'Non-destructive session summary. Optional topic hint after the command.', isOpenChamber: true }]
|
? [{ id: 'openchamber:summary', name: 'summary', source: 'openchamber' as const, description: 'Non-destructive session summary. Optional topic hint after the command.', isOpenChamber: true }]
|
||||||
: []
|
: []
|
||||||
),
|
),
|
||||||
|
...(hasSession
|
||||||
|
? [{ id: 'openchamber:review', name: 'review', source: 'openchamber' as const, description: 'Review current workspace changes for high-signal issues only.', isOpenChamber: true }]
|
||||||
|
: []
|
||||||
|
),
|
||||||
];
|
];
|
||||||
const allCommands = [...builtInCommands, ...customCommands];
|
const allCommands = [...builtInCommands, ...customCommands];
|
||||||
|
|
||||||
@@ -162,6 +166,10 @@ export const CommandAutocomplete = React.forwardRef<CommandAutocompleteHandle, C
|
|||||||
? [{ id: 'openchamber:summary', name: 'summary', source: 'openchamber' as const, description: 'Non-destructive session summary. Optional topic hint after the command.', isOpenChamber: true }]
|
? [{ id: 'openchamber:summary', name: 'summary', source: 'openchamber' as const, description: 'Non-destructive session summary. Optional topic hint after the command.', isOpenChamber: true }]
|
||||||
: []
|
: []
|
||||||
),
|
),
|
||||||
|
...(hasSession
|
||||||
|
? [{ id: 'openchamber:review', name: 'review', source: 'openchamber' as const, description: 'Review current workspace changes for high-signal issues only.', isOpenChamber: true }]
|
||||||
|
: []
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
const filtered = (searchQuery
|
const filtered = (searchQuery
|
||||||
@@ -234,6 +242,8 @@ export const CommandAutocomplete = React.forwardRef<CommandAutocompleteHandle, C
|
|||||||
return <RiArrowGoForwardLine className="h-3.5 w-3.5 text-orange-500" />;
|
return <RiArrowGoForwardLine className="h-3.5 w-3.5 text-orange-500" />;
|
||||||
case 'compact':
|
case 'compact':
|
||||||
return <RiScissorsLine className="h-3.5 w-3.5 text-purple-500" />;
|
return <RiScissorsLine className="h-3.5 w-3.5 text-purple-500" />;
|
||||||
|
case 'review':
|
||||||
|
return <RiSearchEyeLine className="h-3.5 w-3.5 text-blue-500" />;
|
||||||
case 'test':
|
case 'test':
|
||||||
case 'build':
|
case 'build':
|
||||||
case 'run':
|
case 'run':
|
||||||
|
|||||||
@@ -131,6 +131,14 @@ const PROMPT_PAGE_MAP: Record<string, PromptPageConfig> = {
|
|||||||
{ id: 'session.summary.instructions', title: 'Instructions' },
|
{ id: 'session.summary.instructions', title: 'Instructions' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
'session.review': {
|
||||||
|
title: 'Workspace Review',
|
||||||
|
description: 'Prompts used by the /review slash command: visible user message + hidden instructions. Reviews current workspace changes for high-signal issues only.',
|
||||||
|
blocks: [
|
||||||
|
{ id: 'session.review.visible', title: 'Visible Prompt' },
|
||||||
|
{ id: 'session.review.instructions', title: 'Instructions' },
|
||||||
|
],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const hasOwn = (input: Record<string, string>, key: string) => Object.prototype.hasOwnProperty.call(input, key);
|
const hasOwn = (input: Record<string, string>, key: string) => Object.prototype.hasOwnProperty.call(input, key);
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ export const MagicPromptsSidebar: React.FC<MagicPromptsSidebarProps> = ({ onItem
|
|||||||
group: 'Session',
|
group: 'Session',
|
||||||
items: [
|
items: [
|
||||||
{ id: 'session.summary', title: 'Session Summary' },
|
{ id: 'session.summary', title: 'Session Summary' },
|
||||||
|
{ id: 'session.review', title: 'Workspace Review' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
] as const;
|
] as const;
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ export type MagicPromptId =
|
|||||||
| 'plan.implement.visible'
|
| 'plan.implement.visible'
|
||||||
| 'plan.implement.instructions'
|
| 'plan.implement.instructions'
|
||||||
| 'session.summary.visible'
|
| 'session.summary.visible'
|
||||||
| 'session.summary.instructions';
|
| 'session.summary.instructions'
|
||||||
|
| 'session.review.visible'
|
||||||
|
| 'session.review.instructions';
|
||||||
|
|
||||||
export interface MagicPromptDefinition {
|
export interface MagicPromptDefinition {
|
||||||
id: MagicPromptId;
|
id: MagicPromptId;
|
||||||
@@ -506,6 +508,56 @@ Formatting:
|
|||||||
|
|
||||||
Respond in the same language the user used most in the conversation.`,
|
Respond in the same language the user used most in the conversation.`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'session.review.visible',
|
||||||
|
title: 'Workspace Review Visible Prompt',
|
||||||
|
group: 'Session',
|
||||||
|
description: 'Visible user message sent by the /review command.',
|
||||||
|
template: 'Review the changes made in this workspace.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'session.review.instructions',
|
||||||
|
title: 'Workspace Review Instructions',
|
||||||
|
group: 'Session',
|
||||||
|
description: 'Hidden instructions attached to the /review command. Reviews current workspace changes for high-signal issues only.',
|
||||||
|
template: `
|
||||||
|
Report only real, high-signal issues introduced by these changes.
|
||||||
|
|
||||||
|
The diff is the source of truth. Use the local repo only as ancillary context when you need to validate a specific claim or check an applicable rule.
|
||||||
|
|
||||||
|
Focus on:
|
||||||
|
- runtime bugs
|
||||||
|
- incorrect logic
|
||||||
|
- broken assumptions in the changed code
|
||||||
|
- clear regressions introduced by the changes
|
||||||
|
- missing implementations across affected modules or targets when the diff clearly introduced the gap
|
||||||
|
- clear CLAUDE.md or AGENTS.md violations that apply to the changed files
|
||||||
|
|
||||||
|
Do not report:
|
||||||
|
- pre-existing issues unrelated to the diff
|
||||||
|
- pedantic nitpicks a senior engineer would not flag
|
||||||
|
- issues a linter would catch
|
||||||
|
- subjective style preferences not explicitly required by CLAUDE.md or AGENTS.md
|
||||||
|
- speculative concerns or anything you cannot verify with high confidence
|
||||||
|
- missing tests or coverage gaps unless an applicable CLAUDE.md or AGENTS.md explicitly requires them for the changed area
|
||||||
|
- rules mentioned in CLAUDE.md or AGENTS.md but explicitly silenced in the code
|
||||||
|
|
||||||
|
Validation pass:
|
||||||
|
- Before reporting an issue, re-check it against the diff plus only the local context you actually needed to read.
|
||||||
|
- For CLAUDE.md or AGENTS.md violations, verify the rule applies to the affected file path and cite the exact rule.
|
||||||
|
- If you are not certain an issue is real, omit it.
|
||||||
|
|
||||||
|
Output:
|
||||||
|
- If no high-signal issues are found, respond with exactly: No high-signal issues found.
|
||||||
|
- Otherwise, return a concise numbered list.
|
||||||
|
- For each issue include:
|
||||||
|
- short title
|
||||||
|
- why it is a real problem
|
||||||
|
- affected file path
|
||||||
|
- category: bug or rule violation
|
||||||
|
|
||||||
|
Keep the review concise and practical.`,
|
||||||
|
},
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
const MAGIC_PROMPT_DEFINITION_BY_ID = new Map<MagicPromptId, MagicPromptDefinition>(
|
const MAGIC_PROMPT_DEFINITION_BY_ID = new Map<MagicPromptId, MagicPromptDefinition>(
|
||||||
|
|||||||
Reference in New Issue
Block a user