agent-canvas 0.2.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +42 -17
  2. package/bin/agent-canvas.js +7 -7
  3. package/bin/agent-canvas.ts +48 -37
  4. package/bin/lib/commands/daemon.ts +46 -43
  5. package/bin/lib/commands/exec.ts +100 -100
  6. package/bin/lib/commands/fetch.ts +15 -15
  7. package/bin/lib/commands/install.ts +36 -36
  8. package/bin/lib/commands/instructions.ts +51 -51
  9. package/bin/lib/commands/push.ts +115 -97
  10. package/bin/lib/commands/review.ts +190 -0
  11. package/bin/lib/commands/watch.ts +24 -24
  12. package/bin/lib/config.ts +12 -12
  13. package/bin/lib/daemon-lifecycle.ts +47 -51
  14. package/bin/lib/helpers.ts +82 -76
  15. package/bin/lib/instructions/app-review.md +88 -0
  16. package/bin/lib/instructions/component-checklist.md +7 -5
  17. package/bin/lib/instructions/component-custom.md +20 -14
  18. package/bin/lib/instructions/component-diff.md +4 -3
  19. package/bin/lib/instructions/component-item.md +18 -8
  20. package/bin/lib/instructions/component-markdown.md +4 -2
  21. package/bin/lib/instructions/component-mermaid.md +12 -6
  22. package/bin/lib/instructions/component-multichoice.md +6 -2
  23. package/bin/lib/instructions/component-note.md +1 -1
  24. package/bin/lib/instructions/component-priority.md +1 -1
  25. package/bin/lib/instructions/component-rangeinput.md +9 -2
  26. package/bin/lib/instructions/component-secretinput.md +12 -11
  27. package/bin/lib/instructions/component-svg.md +62 -16
  28. package/bin/lib/instructions/component-table.md +6 -6
  29. package/bin/lib/instructions/component-usefeedback.md +8 -8
  30. package/bin/lib/instructions/component-userinput.md +6 -2
  31. package/bin/lib/instructions/flow-feature.md +22 -5
  32. package/bin/lib/instructions/flow-plan.md +5 -5
  33. package/bin/lib/instructions/flow-runbook.md +28 -25
  34. package/bin/lib/instructions/overview.md +27 -18
  35. package/bin/lib/instructions/theming.md +5 -0
  36. package/daemon/build.ts +171 -152
  37. package/daemon/client/App.tsx +1205 -1077
  38. package/daemon/client/CompareView.tsx +478 -458
  39. package/daemon/client/FileBrowser.tsx +241 -203
  40. package/daemon/client/FileViewer.tsx +220 -211
  41. package/daemon/client/OverviewView.tsx +283 -267
  42. package/daemon/client/ReviewerIdentityDialog.tsx +72 -71
  43. package/daemon/client/RevisionSelect.tsx +111 -95
  44. package/daemon/client/SessionSwitcher.tsx +81 -81
  45. package/daemon/client/ShareDialog.tsx +211 -212
  46. package/daemon/client/apiSchemas.ts +78 -0
  47. package/daemon/client/canvas-runtime.ts +1 -1
  48. package/daemon/client/clientApi.ts +194 -206
  49. package/daemon/client/components/SecretInput.tsx +138 -138
  50. package/daemon/client/components/index.ts +2 -2
  51. package/daemon/client/domDiff.ts +341 -333
  52. package/daemon/client/errorMessage.ts +3 -0
  53. package/daemon/client/exportMarkdown.ts +222 -201
  54. package/daemon/client/lcs.ts +19 -14
  55. package/daemon/client/shareCrypto.ts +57 -57
  56. package/daemon/client/unifiedDiff.ts +660 -649
  57. package/daemon/dist/annotations-runtime.js +1 -1
  58. package/daemon/dist/client.css +2 -2
  59. package/daemon/dist/client.js +77 -80
  60. package/daemon/dist/components.js +59 -59
  61. package/daemon/dist/preact-compat.js +1 -1
  62. package/daemon/dist/review.js +361 -0
  63. package/daemon/dist/runtime.js +1 -1
  64. package/daemon/langMap.ts +24 -6
  65. package/daemon/review-widget/anchor.ts +187 -0
  66. package/daemon/review-widget/client.ts +95 -0
  67. package/daemon/review-widget/index.tsx +36 -0
  68. package/daemon/review-widget/markup.ts +71 -0
  69. package/daemon/review-widget/screenshot.ts +91 -0
  70. package/daemon/review-widget/source.ts +103 -0
  71. package/daemon/review-widget/styles.css +359 -0
  72. package/daemon/review-widget/text-modules.d.ts +4 -0
  73. package/daemon/review-widget/tsconfig.json +16 -0
  74. package/daemon/review-widget/widget.tsx +436 -0
  75. package/daemon/src/components.ts +3 -3
  76. package/daemon/src/handlers/api.ts +330 -328
  77. package/daemon/src/handlers/files.ts +112 -106
  78. package/daemon/src/handlers/static.ts +47 -46
  79. package/daemon/src/handlers/uploads.ts +61 -56
  80. package/daemon/src/paths.ts +13 -10
  81. package/daemon/src/remote-feedback.ts +192 -192
  82. package/daemon/src/review/markdown.ts +52 -0
  83. package/daemon/src/review/model.ts +132 -0
  84. package/daemon/src/review/proxy.ts +177 -0
  85. package/daemon/src/review/server.ts +199 -0
  86. package/daemon/src/review/store.ts +151 -0
  87. package/daemon/src/server.ts +127 -86
  88. package/daemon/src/share.ts +163 -169
  89. package/daemon/src/stubFetch.ts +7 -0
  90. package/daemon/tsconfig.json +19 -19
  91. package/package.json +47 -47
  92. package/skills/canvas/SKILL.md +5 -1
  93. package/bin/lib/commands/exec.test.ts +0 -27
  94. package/bin/lib/helpers.test.ts +0 -79
  95. package/daemon/src/files-api.test.ts +0 -78
  96. package/daemon/src/remote-feedback.test.ts +0 -165
  97. package/daemon/src/secrets-api.test.ts +0 -123
  98. package/daemon/src/share-e2e.test.ts +0 -277
  99. package/daemon/src/share.test.ts +0 -289
@@ -5,36 +5,42 @@ Renders a Mermaid diagram. Supports flowchart, sequence, ER, gantt, pie, and mor
5
5
  ## Usage
6
6
 
7
7
  ```jsx
8
- <Mermaid>{`
8
+ <Mermaid>
9
+ {`
9
10
  graph TD
10
11
  A[Client] -->|HTTP| B(API Gateway)
11
12
  B --> C{Auth?}
12
13
  C -->|Valid| D[Service]
13
14
  C -->|Invalid| E[401 Response]
14
- `}</Mermaid>
15
+ `}
16
+ </Mermaid>
15
17
  ```
16
18
 
17
19
  ### Sequence diagram
18
20
 
19
21
  ```jsx
20
- <Mermaid>{`
22
+ <Mermaid>
23
+ {`
21
24
  sequenceDiagram
22
25
  Client->>+API: POST /login
23
26
  API->>+DB: Find user
24
27
  DB-->>-API: User record
25
28
  API-->>-Client: JWT token
26
- `}</Mermaid>
29
+ `}
30
+ </Mermaid>
27
31
  ```
28
32
 
29
33
  ### ER diagram
30
34
 
31
35
  ```jsx
32
- <Mermaid>{`
36
+ <Mermaid>
37
+ {`
33
38
  erDiagram
34
39
  USER ||--o{ ORDER : places
35
40
  ORDER ||--|{ LINE-ITEM : contains
36
41
  PRODUCT ||--o{ LINE-ITEM : "ordered in"
37
- `}</Mermaid>
42
+ `}
43
+ </Mermaid>
38
44
  ```
39
45
 
40
46
  For complex diagrams, prefer Mermaid over raw SVG. Use raw `<svg>` only when Mermaid can't express what you need.
@@ -12,8 +12,12 @@ Multi-select checkboxes.
12
12
  ## Usage
13
13
 
14
14
  ```jsx
15
- <MultiChoice id="affected-areas" label="Which areas need changes?" required
16
- options={["Models", "API", "Frontend", "Tests"]} />
15
+ <MultiChoice
16
+ id="affected-areas"
17
+ label="Which areas need changes?"
18
+ required
19
+ options={['Models', 'API', 'Frontend', 'Tests']}
20
+ />
17
21
  ```
18
22
 
19
23
  Appears in feedback as: `[affected-areas]: Models, API, Tests`
@@ -6,6 +6,6 @@ Softer than Callout. For asides, context, non-critical info.
6
6
 
7
7
  ```jsx
8
8
  <Note>
9
- This pattern is also used in the payment service — see src/payments/auth.ts.
9
+ This pattern is also used in the payment service — see src/payments/auth.ts.
10
10
  </Note>
11
11
  ```
@@ -10,6 +10,6 @@ Inline badge. Use inside Item labels or body text.
10
10
 
11
11
  ```jsx
12
12
  <Item label="Fix the race condition">
13
- <Priority level="high" /> This causes data corruption under load.
13
+ <Priority level="high" /> This causes data corruption under load.
14
14
  </Item>
15
15
  ```
@@ -15,6 +15,13 @@ Slider for numeric ranges or scales.
15
15
  ## Usage
16
16
 
17
17
  ```jsx
18
- <RangeInput id="effort-tolerance" label="How much refactoring is acceptable?"
19
- min={1} max={5} minLabel="Minimal changes" maxLabel="Full rewrite OK" required />
18
+ <RangeInput
19
+ id="effort-tolerance"
20
+ label="How much refactoring is acceptable?"
21
+ min={1}
22
+ max={5}
23
+ minLabel="Minimal changes"
24
+ maxLabel="Full rewrite OK"
25
+ required
26
+ />
20
27
  ```
@@ -16,17 +16,18 @@ The value stays outside normal canvas response state. It is not written to `loca
16
16
 
17
17
  ```jsx
18
18
  <Section title="Create an API token">
19
- <Item id="open-settings" label="1. Open token settings">
20
- Open the service's token settings. Create a token with the minimum scopes needed for this task.
21
- </Item>
22
-
23
- <SecretInput
24
- id="service-token"
25
- label="2. Paste the new token"
26
- env="SERVICE_TOKEN"
27
- placeholder="Paste token"
28
- required
29
- />
19
+ <Item id="open-settings" label="1. Open token settings">
20
+ Open the service's token settings. Create a token with the minimum scopes
21
+ needed for this task.
22
+ </Item>
23
+
24
+ <SecretInput
25
+ id="service-token"
26
+ label="2. Paste the new token"
27
+ env="SERVICE_TOKEN"
28
+ placeholder="Paste token"
29
+ required
30
+ />
30
31
  </Section>
31
32
  ```
32
33
 
@@ -6,25 +6,71 @@ For custom visuals that Mermaid can't express, write `<svg>` directly. Use CSS v
6
6
 
7
7
  ```jsx
8
8
  <svg viewBox="0 0 400 200" style={{ width: '100%', maxWidth: 400 }}>
9
- <rect x="10" y="10" width="120" height="50" rx="8"
10
- fill="var(--color-accent-blue-muted)" stroke="var(--color-accent-blue)" strokeOpacity="0.3" />
11
- <text x="70" y="40" textAnchor="middle" fill="var(--color-text-primary)" fontSize="13"
12
- fontFamily="var(--font-body)">API Gateway</text>
9
+ <rect
10
+ x="10"
11
+ y="10"
12
+ width="120"
13
+ height="50"
14
+ rx="8"
15
+ fill="var(--color-accent-blue-muted)"
16
+ stroke="var(--color-accent-blue)"
17
+ strokeOpacity="0.3"
18
+ />
19
+ <text
20
+ x="70"
21
+ y="40"
22
+ textAnchor="middle"
23
+ fill="var(--color-text-primary)"
24
+ fontSize="13"
25
+ fontFamily="var(--font-body)"
26
+ >
27
+ API Gateway
28
+ </text>
13
29
 
14
- <line x1="130" y1="35" x2="180" y2="35" stroke="var(--color-text-tertiary)" strokeWidth="1.5"
15
- markerEnd="url(#arrow)" />
30
+ <line
31
+ x1="130"
32
+ y1="35"
33
+ x2="180"
34
+ y2="35"
35
+ stroke="var(--color-text-tertiary)"
36
+ strokeWidth="1.5"
37
+ markerEnd="url(#arrow)"
38
+ />
16
39
 
17
- <rect x="180" y="10" width="120" height="50" rx="8"
18
- fill="var(--color-accent-green-muted)" stroke="var(--color-accent-green)" strokeOpacity="0.3" />
19
- <text x="240" y="40" textAnchor="middle" fill="var(--color-text-primary)" fontSize="13"
20
- fontFamily="var(--font-body)">Auth Service</text>
40
+ <rect
41
+ x="180"
42
+ y="10"
43
+ width="120"
44
+ height="50"
45
+ rx="8"
46
+ fill="var(--color-accent-green-muted)"
47
+ stroke="var(--color-accent-green)"
48
+ strokeOpacity="0.3"
49
+ />
50
+ <text
51
+ x="240"
52
+ y="40"
53
+ textAnchor="middle"
54
+ fill="var(--color-text-primary)"
55
+ fontSize="13"
56
+ fontFamily="var(--font-body)"
57
+ >
58
+ Auth Service
59
+ </text>
21
60
 
22
- <defs>
23
- <marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6"
24
- orient="auto-start-reverse">
25
- <path d="M 0 0 L 10 5 L 0 10 z" fill="var(--color-text-tertiary)" />
26
- </marker>
27
- </defs>
61
+ <defs>
62
+ <marker
63
+ id="arrow"
64
+ viewBox="0 0 10 10"
65
+ refX="9"
66
+ refY="5"
67
+ markerWidth="6"
68
+ markerHeight="6"
69
+ orient="auto-start-reverse"
70
+ >
71
+ <path d="M 0 0 L 10 5 L 0 10 z" fill="var(--color-text-tertiary)" />
72
+ </marker>
73
+ </defs>
28
74
  </svg>
29
75
  ```
30
76
 
@@ -11,11 +11,11 @@ Simple data table.
11
11
 
12
12
  ```jsx
13
13
  <Table
14
- headers={["Endpoint", "Method", "Auth"]}
15
- rows={[
16
- ["/users", "GET", "Required"],
17
- ["/users/:id", "PUT", "Owner only"],
18
- ["/health", "GET", "None"],
19
- ]}
14
+ headers={['Endpoint', 'Method', 'Auth']}
15
+ rows={[
16
+ ['/users', 'GET', 'Required'],
17
+ ['/users/:id', 'PUT', 'Owner only'],
18
+ ['/health', 'GET', 'None'],
19
+ ]}
20
20
  />
21
21
  ```
@@ -19,15 +19,15 @@ Registers on mount, updates on change, unregisters on unmount.
19
19
 
20
20
  ```jsx
21
21
  function ProConList() {
22
- const [pros, setPros] = React.useState(["Fast builds"]);
23
- const [cons, setCons] = React.useState(["New runtime"]);
22
+ const [pros, setPros] = React.useState(['Fast builds'])
23
+ const [cons, setCons] = React.useState(['New runtime'])
24
24
 
25
- useFeedback(
26
- "pro-con",
27
- `**Pros:** ${pros.join(", ")}\n**Cons:** ${cons.join(", ")}`,
28
- { label: "Pro/Con Analysis" },
29
- );
25
+ useFeedback(
26
+ 'pro-con',
27
+ `**Pros:** ${pros.join(', ')}\n**Cons:** ${cons.join(', ')}`,
28
+ { label: 'Pro/Con Analysis' },
29
+ )
30
30
 
31
- return <div>{/* UI for managing pros/cons */}</div>;
31
+ return <div>{/* UI for managing pros/cons */}</div>
32
32
  }
33
33
  ```
@@ -12,6 +12,10 @@ Free text input.
12
12
  ## Usage
13
13
 
14
14
  ```jsx
15
- <UserInput id="constraints" label="Any constraints I should know about?"
16
- placeholder="e.g. must work with existing Redis setup" required />
15
+ <UserInput
16
+ id="constraints"
17
+ label="Any constraints I should know about?"
18
+ placeholder="e.g. must work with existing Redis setup"
19
+ required
20
+ />
17
21
  ```
@@ -44,11 +44,28 @@ If the user selects interview areas, push follow-up canvases with deep questions
44
44
 
45
45
  ```jsx
46
46
  <Section title="Backend Deep Dive">
47
- <UserInput id="data-shape" label="Describe the data shape / entities involved" required />
48
- <Choice id="mutation-pattern" label="How should mutations work?"
49
- options={["Sync — mutate and return", "Async — queue and process", "Event-driven — publish and react"]} />
50
- <UserInput id="invariants" label="What business rules / invariants must always hold?" />
51
- <UserInput id="existing-patterns" label="Any existing patterns in the codebase I should follow?" />
47
+ <UserInput
48
+ id="data-shape"
49
+ label="Describe the data shape / entities involved"
50
+ required
51
+ />
52
+ <Choice
53
+ id="mutation-pattern"
54
+ label="How should mutations work?"
55
+ options={[
56
+ 'Sync — mutate and return',
57
+ 'Async — queue and process',
58
+ 'Event-driven — publish and react',
59
+ ]}
60
+ />
61
+ <UserInput
62
+ id="invariants"
63
+ label="What business rules / invariants must always hold?"
64
+ />
65
+ <UserInput
66
+ id="existing-patterns"
67
+ label="Any existing patterns in the codebase I should follow?"
68
+ />
52
69
  </Section>
53
70
  ```
54
71
 
@@ -96,11 +96,11 @@ Push AFTER implementation is complete. Always do this, even briefly. **After pus
96
96
 
97
97
  ## Skipping & Combining
98
98
 
99
- | Situation | Action |
100
- |---|---|
99
+ | Situation | Action |
100
+ | ---------------------------------------------- | -------------------------------------- |
101
101
  | User said "just do it" with clear instructions | Implement directly, push summary after |
102
- | Simple change (< 3 files) | Probably skip canvas entirely |
103
- | User explicitly says "don't plan, just code" | Implement, push summary |
104
- | Mid-flow user says "looks good, go ahead" | Skip remaining review rounds |
102
+ | Simple change (< 3 files) | Probably skip canvas entirely |
103
+ | User explicitly says "don't plan, just code" | Implement, push summary |
104
+ | Mid-flow user says "looks good, go ahead" | Skip remaining review rounds |
105
105
 
106
106
  **Always push a summary after implementation** (unless trivially small) **and watch for feedback** — the user may want to respond with follow-ups or corrections.
@@ -12,31 +12,34 @@ Give the user ordered, concrete steps. Include the exact destination, required p
12
12
 
13
13
  ```jsx
14
14
  <Section title="Connect the service">
15
- <Callout type="info">
16
- Complete these steps in order. The token value will stay outside agent feedback and model context.
17
- </Callout>
18
-
19
- <Item id="open-token-page" label="1. Open token settings" status="todo">
20
- Open https://service.example/settings/tokens while signed in to the target account.
21
- </Item>
22
-
23
- <Item id="create-token" label="2. Create a scoped token" status="todo">
24
- Name it for this task. Grant only read:projects and write:deployments. Set the shortest practical expiry.
25
- </Item>
26
-
27
- <SecretInput
28
- id="service-token"
29
- label="3. Paste the token"
30
- env="SERVICE_TOKEN"
31
- required
32
- />
33
-
34
- <Choice
35
- id="target-confirmation"
36
- label="Which environment did you configure?"
37
- options={["Staging", "Production"]}
38
- required
39
- />
15
+ <Callout type="info">
16
+ Complete these steps in order. The token value will stay outside agent
17
+ feedback and model context.
18
+ </Callout>
19
+
20
+ <Item id="open-token-page" label="1. Open token settings" status="todo">
21
+ Open https://service.example/settings/tokens while signed in to the target
22
+ account.
23
+ </Item>
24
+
25
+ <Item id="create-token" label="2. Create a scoped token" status="todo">
26
+ Name it for this task. Grant only read:projects and write:deployments. Set the
27
+ shortest practical expiry.
28
+ </Item>
29
+
30
+ <SecretInput
31
+ id="service-token"
32
+ label="3. Paste the token"
33
+ env="SERVICE_TOKEN"
34
+ required
35
+ />
36
+
37
+ <Choice
38
+ id="target-confirmation"
39
+ label="Which environment did you configure?"
40
+ options={['Staging', 'Production']}
41
+ required
42
+ />
40
43
  </Section>
41
44
  ```
42
45
 
@@ -17,17 +17,17 @@ Use the **Write** tool to create `.jsx` files in `${TMPDIR:-/tmp}/agent-canvas/<
17
17
  // ${TMPDIR:-/tmp}/agent-canvas/<session-id>/plan.jsx
18
18
 
19
19
  <Section title="Authentication Redesign">
20
- A proposal to replace session-based auth with JWT tokens.
20
+ A proposal to replace session-based auth with JWT tokens.
21
21
 
22
- <Item id="current" label="Current state" badge="context" badgeVariant="info">
23
- The app uses express-session with Redis store.
24
- <FilePreview path="src/auth/session.ts" lines={[1, 45]} />
25
- </Item>
22
+ <Item id="current" label="Current state" badge="context" badgeVariant="info">
23
+ The app uses express-session with Redis store.
24
+ <FilePreview path="src/auth/session.ts" lines={[1, 45]} />
25
+ </Item>
26
26
 
27
- <Item id="proposal" label="Proposed change" badge="proposal">
28
- Switch to stateless JWT with refresh token rotation.
29
- <Callout type="warning">This will invalidate all existing sessions.</Callout>
30
- </Item>
27
+ <Item id="proposal" label="Proposed change" badge="proposal">
28
+ Switch to stateless JWT with refresh token rotation.
29
+ <Callout type="warning">This will invalidate all existing sessions.</Callout>
30
+ </Item>
31
31
  </Section>
32
32
  ```
33
33
 
@@ -35,7 +35,7 @@ Components are auto-available — no imports needed. The file can be a JSX fragm
35
35
 
36
36
  **Content is JSX, not markdown.** Children of components are plain JSX text and nested components — NOT markdown. If you want to render markdown (lists, bold, headings, etc.), use the `<Markdown>` component explicitly. Raw `**bold**` or `- list items` in JSX children will render as literal text.
37
37
 
38
- **JSX escaping rules.** Content is in a JSX context. You MUST escape: `<` as `{'<'}` or `&lt;`, `>` as `{'>'}` or `&gt;`, `{` as `{'{'}` and `}` as `{'}'}`. This is critical when writing code snippets, type signatures like `Option<String>`, or any text containing angle brackets. Alternatively, put such content inside `<CodeBlock>` or `<Markdown>` which handle escaping for you.
38
+ **JSX escaping rules.** Content is in a JSX context. You MUST escape: `<` as `{'<'}` or `&lt;`, `>` as `{'>'}` or `&gt;`, `{` as `{'{'}` and `}` as `{'}'}`. This is critical when writing code snippets, type signatures like `Option<String>`, or any text containing angle brackets. Alternatively, put such content inside `<CodeBlock>` or `<Markdown>` which handle escaping for you.
39
39
 
40
40
  ### 2. Push
41
41
 
@@ -48,6 +48,7 @@ bunx agent-canvas push ${TMPDIR:-/tmp}/agent-canvas/<session-id>/ --session <ses
48
48
  All `*.jsx` files in the directory are pushed as a snapshot. Each file appears as a separate tab. **Always show the `browserUrl` from the output to the user.**
49
49
 
50
50
  Options:
51
+
51
52
  - `--label <text>` — revision label shown in the UI
52
53
  - `--response <text>` — short banner explaining how you addressed prior feedback (2-4 sentences, focus on "why" not "what")
53
54
 
@@ -123,9 +124,11 @@ All components are globally available in canvas JSX — no imports needed. For i
123
124
  **Never hardcode hex colors** — use CSS variables: `var(--color-text-primary)`, `var(--color-bg-surface)`, `var(--color-accent-blue)`, etc.
124
125
 
125
126
  ### Layout
127
+
126
128
  - **Section** — top-level collapsible grouping with serif heading. Props: `title`, `collapsed`
127
129
 
128
130
  ### Content
131
+
129
132
  - **Item** — primary content block (tasks, findings, requirements). Props: `id`, `label`, `badge`, `badgeVariant`, `status`
130
133
  - **CodeBlock** — syntax-highlighted code. Props: `language`
131
134
  - **FilePreview** — project file preview. Props: `path`, `lines` ([start, end])
@@ -140,6 +143,7 @@ All components are globally available in canvas JSX — no imports needed. For i
140
143
  - **Priority** — inline priority badge. Props: `level` (high/medium/low)
141
144
 
142
145
  ### Interactive (User Input)
146
+
143
147
  - **Choice** — single-select radio group. Props: `id`, `label`, `options`, `required`
144
148
  - **MultiChoice** — multi-select checkboxes. Props: `id`, `label`, `options`, `required`
145
149
  - **UserInput** — free text input. Props: `id`, `label`, `placeholder`, `required`
@@ -147,6 +151,7 @@ All components are globally available in canvas JSX — no imports needed. For i
147
151
  - **RangeInput** — numeric slider. Props: `id`, `label`, `min`, `max`, `minLabel`, `maxLabel`, `required`
148
152
 
149
153
  ### Advanced
154
+
150
155
  - **useFeedback** — hook for custom components to contribute computed data to feedback
151
156
  - **Custom components** — use `export default function Canvas()` module format to define helpers
152
157
 
@@ -174,17 +179,21 @@ Agent needs the user to complete manual steps? → RUNBOOK flow
174
179
 
175
180
  **Adapt dynamically**: flows are guidelines, not rigid pipelines. Skip or combine phases when appropriate:
176
181
 
177
- | Situation | Action |
178
- |---|---|
179
- | User gave a detailed spec | Skip to PLAN (skip discovery + requirements) |
180
- | User said "just do it" with clear instructions | Implement directly, push summary after |
181
- | Simple change (< 3 files) | Probably skip canvas entirely |
182
- | User explicitly says "don't plan, just code" | Implement, push summary |
183
- | Mid-flow user says "looks good, go ahead" | Skip remaining review rounds |
184
- | Discovery reveals it's trivial | Collapse remaining phases into one canvas |
182
+ | Situation | Action |
183
+ | ---------------------------------------------- | -------------------------------------------- |
184
+ | User gave a detailed spec | Skip to PLAN (skip discovery + requirements) |
185
+ | User said "just do it" with clear instructions | Implement directly, push summary after |
186
+ | Simple change (< 3 files) | Probably skip canvas entirely |
187
+ | User explicitly says "don't plan, just code" | Implement, push summary |
188
+ | Mid-flow user says "looks good, go ahead" | Skip remaining review rounds |
189
+ | Discovery reveals it's trivial | Collapse remaining phases into one canvas |
185
190
 
186
191
  **Always push a summary after implementation** unless the change was trivially small (1-2 file edit).
187
192
 
193
+ ## Review Mode
194
+
195
+ To collect comments on a running application instead of a canvas, read `bunx agent-canvas instructions app-review`.
196
+
188
197
  ## Flow Execution Pattern
189
198
 
190
199
  1. **Determine flow** from user intent
@@ -5,6 +5,7 @@ Canvas supports light/dark themes. **Never hardcode hex colors** — use CSS var
5
5
  ## CSS Variables
6
6
 
7
7
  ### Text
8
+
8
9
  - `--color-text-primary` — main text
9
10
  - `--color-text-secondary` — supporting text
10
11
  - `--color-text-tertiary` — meta text, labels
@@ -12,6 +13,7 @@ Canvas supports light/dark themes. **Never hardcode hex colors** — use CSS var
12
13
  - `--color-text-inverse` — text on dark backgrounds
13
14
 
14
15
  ### Backgrounds
16
+
15
17
  - `--color-bg-base` — page background
16
18
  - `--color-bg-surface` — card/section background
17
19
  - `--color-bg-elevated` — floating elements
@@ -19,17 +21,20 @@ Canvas supports light/dark themes. **Never hardcode hex colors** — use CSS var
19
21
  - `--color-bg-input` — form input background
20
22
 
21
23
  ### Accents
24
+
22
25
  - `--color-accent-green`, `--color-accent-green-muted`
23
26
  - `--color-accent-amber`, `--color-accent-amber-muted`
24
27
  - `--color-accent-red`, `--color-accent-red-muted`
25
28
  - `--color-accent-blue`, `--color-accent-blue-muted`
26
29
 
27
30
  ### Borders
31
+
28
32
  - `--color-border-subtle` — light separators
29
33
  - `--color-border-medium` — visible borders
30
34
  - `--color-border-hover` — interactive hover state
31
35
 
32
36
  ### Fonts
37
+
33
38
  - `--font-heading` — section headings (Instrument Serif)
34
39
  - `--font-body` — body text (Inter)
35
40
  - `--font-mono` — code (JetBrains Mono)