SLOPSHOPPER

chimaera-review-demo

No-model review-planning demo for inspecting Chimaera's native Mod UI

newpanecommand
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · chimaera-review-demo
│ ┃ Review planner ✕ › fix the failing auth test and add an audit log call │ ┃ EXAMPLE · REVIEW PLANNING │ ┃ Prepare a focused review ⏺ Read(src/auth.ts) │ ┃ Demo data and a manual checklist. No code ⎿ Read 6 lines │ ┃ has been inspected. ⏺ Update(src/auth.ts) │ ┃ ⎿ Added 2 lines, removed 1 line │ ┃ Review scope: Chat composer: draft handling ⏺ Bash(bun test) │ ┃ ⎿ 3 pass, 1 fail │ ┃ Focus: Correctness and failure paths ▾ │ ┃ ● Done. refresh now rejects expired claims and logs an audit event. │ ┃ [ View example diff ] │ ┃ ✻ Worked for 42s · done 4:20 PM │ ┃ Preparation checklist 0 of 3 preparation ste │ ┃ › /chimaera-review-demo │ ┃ 01 Confirm the scope [ │ ┃ Name the behavior and files to inspect. │ ┃ │ ┃ 02 Choose the edge cases │ ┃ Consider reconnects, cancellation, and fo │ ┃ changes. │ ┃ │ ┃ 03 Plan verification [ │ ┃ Decide which checks would support the │ ┃ review. │ ┃ │ ┃ [ Prepare review prompt ] [ Reset checklist ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts

Draws

Pane · Review planner
EXAMPLE · REVIEW PLANNING Prepare a focused review Demo data and a manual checklist. No code has been inspected. Review scope: Chat composer: draft handling and keyboard foc Focus: Correctness and failure paths ▾ [ View example diff ] Preparation checklist 0 of 3 preparation steps checked 01 Confirm the scope [ Check ] Name the behavior and files to inspect. 02 Choose the edge cases [ C Consider reconnects, cancellation, and focus changes. 03 Plan verification [ Check ] Decide which checks would support the review. [ Prepare review prompt ] [ Reset checklist ] Preparing a prompt only updates the draft. Nothing is sent.
Pane · Example diff
EXAMPLE · ILLUSTRATIVE DIFF Returning focus to the composer A static example for inspecting the diff layout. This is not a repository change or a review finding. 0 --- a/example/composer-focus.ts 0 +++ b/example/composer-focus.ts 1 function restoreComposerFocus(composer, pane) { 2 - composer.focus(); 3 - pane.focused = true; 2 + if (pane.contains(document.activeElement)) { 3 + composer.focus({ preventScroll: true }); 4 + } 5 + pane.focused = false; 6 } Review question: when should closing a pane return focus to the composer? [ Back to review planner ]
README

Review planner demo Mod

A separate, realistic fixture for inspecting Chimaera's native Mod layout and controls. Its scope is example data; its checkmarks record manual preparation. It never reads files, runs checks, calls tools, or requests a model turn.

Two panes open when a surface attaches: Review planner and Example diff. The diff is static illustrative content, not a real repository change or a finding. Its native Code element uses format: 'diff'. Switch panes using the tabs or their navigation buttons, and close/reopen them to inspect the host UI.

In the planner, change the scope and review focus, check or undo the three preparation steps, and reset the checklist. Prepare review prompt appends an unsent prompt to the composer, preserving any draft already there. It reports whether that draft update succeeded. Do not send the prepared prompt during a no-model UI inspection.

State lasts for the Claude process, including pane close/reopen and surface reattach. Restarting Claude restores the example values.

Launch

From the repository root, load this fixture only for the disposable session:

claude --plugin-dir "$PWD/crates/chimaera-agent/tests/fixtures/claude-mod-review"

For a Chimaera isolated preview, point that preview's Claude executable setting at a temporary wrapper that forwards its arguments to the installed Claude binary with this --plugin-dir. Keep the wrapper and setting in the preview's disposable state; do not install or enable the fixture globally. Use a new Claude chat so the process picks up the plugin.

Available immediate commands, neither of which starts a model turn:

  • /chimaera-review-demo opens the pane with its current state.
  • /chimaera-review-demo-diff opens the illustrative diff pane.
  • /chimaera-review-demo-reset restores the scope, focus, and checklist, then opens the pane.

Validation uses the installed native plugin engine without a model request:

claude plugin validate crates/chimaera-agent/tests/fixtures/claude-mod-review

This fixture is for live UI inspection. The independent claude-mod fixture remains the native protocol smoke fixture.

Source 1 files
hooks/register.js 127 lines
1const PANE = 'chimaera-review-demo';
2const DIFF_PANE = 'chimaera-review-example-diff';
3const INITIAL_SCOPE = 'Chat composer: draft handling and keyboard focus';
4const EXAMPLE_DIFF = [
5  '--- a/example/composer-focus.ts',
6  '+++ b/example/composer-focus.ts',
7  '@@ -1,4 +1,6 @@',
8  ' function restoreComposerFocus(composer, pane) {',
9  '-  composer.focus();',
10  '-  pane.focused = true;',
11  '+  if (pane.contains(document.activeElement)) {',
12  '+    composer.focus({ preventScroll: true });',
13  '+  }',
14  '+  pane.focused = false;',
15  ' }',
16].join('\n');
17const ITEMS = [
18  { id: 'scope', title: 'Confirm the scope', detail: 'Name the behavior and files to inspect.' },
19  { id: 'edges', title: 'Choose the edge cases', detail: 'Consider reconnects, cancellation, and focus changes.' },
20  { id: 'checks', title: 'Plan verification', detail: 'Decide which checks would support the review.' },
21];
22const LENSES = [
23  { value: 'correctness', label: 'Correctness and failure paths' },
24  { value: 'usability', label: 'Usability and accessibility' },
25  { value: 'lifecycle', label: 'State and lifecycle' },
26];
27let scope = INITIAL_SCOPE;
28let lens = 'correctness';
29let checked = new Set();
30let feedback = '';
31
32function progress() { return checked.size + ' of ' + ITEMS.length + ' preparation steps checked'; }
33function redraw($) { $.ui.invalidate('ui.render'); }
34async function open($) {
35  await $.ui.open({ id: PANE, title: 'Review planner', closeOnEscape: true });
36}
37async function openDiff($) {
38  await $.ui.open({ id: DIFF_PANE, title: 'Example diff', closeOnEscape: true });
39}
40function reviewPrompt() {
41  const selectedLens = LENSES.find((item) => item.value === lens).label;
42  return [
43    'Please review: ' + (scope.trim() || 'the scope I specify before sending this prompt') + '.',
44    'Focus: ' + selectedLens + '.',
45    '',
46    'Look for concrete bugs and missing edge cases. Explain each finding with its location, impact, and a way to verify it.',
47    'Distinguish checks you actually ran from checks you recommend. If there are no findings, say what you inspected and what remains unverified.',
48    '',
49    'Preparation checklist (manually selected in the demo):',
50    ...ITEMS.map((item) => '- [' + (checked.has(item.id) ? 'x' : ' ') + '] ' + item.title),
51    '',
52    'This prompt came from a UI demo. The demo has not inspected code or run tests; these checkmarks record preparation only.',
53  ].join('\n');
54}
55
56export function register(on) {
57  on('session.start', async ($, e, next) => {
58    await $.command.register({ name: 'chimaera-review-demo', description: 'Open the example review planner (no model call)', immediate: true });
59    await $.command.register({ name: 'chimaera-review-demo-diff', description: 'Open an illustrative diff (no model call)', immediate: true });
60    await $.command.register({ name: 'chimaera-review-demo-reset', description: 'Restore the review planner example data (no model call)', immediate: true });
61    return next(e);
62  });
63  on('session.attach', async ($, e, next) => { await openDiff($); await open($); return next(e); });
64  on('command.run', { command: 'chimaera-review-demo' }, async ($) => { await open($); return {}; });
65  on('command.run', { command: 'chimaera-review-demo-diff' }, async ($) => { await openDiff($); return {}; });
66  on('command.run', { command: 'chimaera-review-demo-reset' }, async ($) => {
67    scope = INITIAL_SCOPE; lens = 'correctness'; checked = new Set(); feedback = '';
68    redraw($); await open($); return {};
69  });
70  on('ui.render', { component: 'Pane' }, ($, e, next) => {
71    if (e.requestId === DIFF_PANE) {
72      const { Box, Text, Code, Button } = $.ui.resolve(e);
73      return Box({ flexDirection: 'column', gap: 1, children: [
74        Box({ flexDirection: 'column', children: [
75          Text({ dimColor: true, children: ['EXAMPLE · ILLUSTRATIVE DIFF'] }),
76          Text({ bold: true, children: ['Returning focus to the composer'] }),
77          Text({ dimColor: true, children: ['A static example for inspecting the diff layout. This is not a repository change or a review finding.'] }),
78        ] }),
79        Code({ source: EXAMPLE_DIFF, path: 'example/composer-focus.ts', language: 'typescript', format: 'diff' }),
80        Text({ children: ['Review question: when should closing a pane return focus to the composer?'] }),
81        Button({ key: 'back-to-planner', label: 'Back to review planner', onPress: () => open($) }),
82      ] });
83    }
84    if (e.requestId !== PANE) return next(e);
85    const { Box, Text, Button, Input, Select } = $.ui.resolve(e);
86    const setScope = (text) => { scope = text.slice(0, 240); feedback = ''; redraw($); };
87    return Box({ flexDirection: 'column', gap: 1, children: [
88      Box({ flexDirection: 'column', children: [
89        Text({ dimColor: true, children: ['EXAMPLE · REVIEW PLANNING'] }),
90        Text({ bold: true, children: ['Prepare a focused review'] }),
91        Text({ dimColor: true, children: ['Demo data and a manual checklist. No code has been inspected.'] }),
92      ] }),
93      Input({ key: 'review-scope', label: 'Review scope', value: scope, placeholder: 'What should the review cover?', onInput: setScope, onSubmit: setScope }),
94      Select({ key: 'review-lens', label: 'Focus', value: lens, options: LENSES, onSelect: (value) => {
95        if (LENSES.some((item) => item.value === value)) lens = value;
96        feedback = ''; redraw($);
97      } }),
98      Button({ key: 'view-example-diff', label: 'View example diff', dimColor: true, onPress: () => openDiff($) }),
99      Box({ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', gap: 1, children: [
100        Text({ bold: true, children: ['Preparation checklist'] }),
101        Text({ dimColor: true, children: [progress()] }),
102      ] }),
103      ...ITEMS.map((item, index) => Box({ flexDirection: 'row', alignItems: 'center', gap: 1, children: [
104        Box({ flexShrink: 0, children: [Text({ color: checked.has(item.id) ? 'green' : 'gray', children: [checked.has(item.id) ? '✓' : String(index + 1).padStart(2, '0')] })] }),
105        Box({ flexDirection: 'column', flexGrow: 1, children: [
106          Text({ bold: true, children: [item.title] }),
107          Text({ dimColor: true, children: [item.detail] }),
108        ] }),
109        Button({ key: 'check-' + item.id, label: checked.has(item.id) ? 'Undo' : 'Check', onPress: () => {
110          if (checked.has(item.id)) checked.delete(item.id); else checked.add(item.id);
111          feedback = ''; redraw($);
112        } }),
113      ] })),
114      Box({ flexDirection: 'row', flexWrap: 'wrap', gap: 1, children: [
115        Button({ key: 'prepare-review', label: 'Prepare review prompt', onPress: async () => {
116          const box = await $.prompt.read();
117          const result = await $.prompt.fill({ text: (box.text ? '\n\n' : '') + reviewPrompt(), mode: 'append' });
118          feedback = result.isFilled ? 'Review prompt added to the composer. Check it before sending.' : 'The composer could not accept the draft. Return to it and try again.';
119          redraw($);
120        } }),
121        Button({ key: 'reset-checklist', label: 'Reset checklist', dimColor: true, onPress: () => { checked = new Set(); feedback = ''; redraw($); } }),
122      ] }),
123      Text({ dimColor: true, children: [feedback || 'Preparing a prompt only updates the draft. Nothing is sent.'] }),
124    ] });
125  });
126}
127