agent-canvas 0.1.16 → 0.1.18
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.
- package/bin/agent-canvas.ts +3 -0
- package/bin/lib/commands/install.ts +7 -7
- package/bin/lib/commands/instructions.ts +66 -0
- package/bin/lib/instructions/component-callout.md +27 -0
- package/bin/lib/instructions/component-checklist.md +17 -0
- package/bin/lib/instructions/component-choice.md +27 -0
- package/bin/lib/instructions/component-codeblock.md +24 -0
- package/bin/lib/instructions/component-custom.md +34 -0
- package/bin/lib/instructions/component-diff.md +18 -0
- package/bin/lib/instructions/component-filepreview.md +15 -0
- package/bin/lib/instructions/component-image.md +17 -0
- package/bin/lib/instructions/component-item.md +43 -0
- package/bin/lib/instructions/component-markdown.md +33 -0
- package/bin/lib/instructions/component-mermaid.md +40 -0
- package/bin/lib/instructions/component-multichoice.md +19 -0
- package/bin/lib/instructions/component-note.md +11 -0
- package/bin/lib/instructions/component-priority.md +15 -0
- package/bin/lib/instructions/component-rangeinput.md +20 -0
- package/bin/lib/instructions/component-section.md +22 -0
- package/bin/lib/instructions/component-svg.md +31 -0
- package/bin/lib/instructions/component-table.md +21 -0
- package/bin/lib/instructions/component-usefeedback.md +33 -0
- package/bin/lib/instructions/component-userinput.md +17 -0
- package/bin/lib/instructions/flow-decision.md +53 -0
- package/bin/lib/instructions/flow-explain.md +47 -0
- package/bin/lib/instructions/flow-feature.md +188 -0
- package/bin/lib/instructions/flow-plan.md +106 -0
- package/bin/lib/instructions/flow-review.md +60 -0
- package/bin/lib/instructions/overview.md +173 -0
- package/bin/lib/instructions/theming.md +50 -0
- package/daemon/client/AnnotationSidebar.tsx +40 -20
- package/daemon/client/App.tsx +8 -1
- package/daemon/dist/client.js +35 -35
- package/daemon/src/compiler.ts +1 -0
- package/daemon/src/handlers/api.ts +3 -1
- package/daemon/src/server.ts +1 -1
- package/daemon/src/websocket.ts +62 -1
- package/package.json +1 -1
- package/skills/canvas/SKILL.md +9 -194
- package/skills/canvas/components.md +0 -403
- package/skills/canvas/flows.md +0 -406
package/bin/agent-canvas.ts
CHANGED
|
@@ -5,12 +5,14 @@ import { handleFetch } from "./lib/commands/fetch.ts";
|
|
|
5
5
|
import { handleWatch } from "./lib/commands/watch.ts";
|
|
6
6
|
import { handleDaemon } from "./lib/commands/daemon.ts";
|
|
7
7
|
import { handleInstall } from "./lib/commands/install.ts";
|
|
8
|
+
import { handleInstructions } from "./lib/commands/instructions.ts";
|
|
8
9
|
|
|
9
10
|
function printUsage() {
|
|
10
11
|
console.error(`agent-canvas — Interactive visual canvas for Claude Code
|
|
11
12
|
|
|
12
13
|
Commands:
|
|
13
14
|
agent-canvas install [local|global] Install skill for Claude Code
|
|
15
|
+
agent-canvas instructions [topic] Show usage instructions (for AI agents)
|
|
14
16
|
agent-canvas push <file.jsx> Push a canvas, open browser
|
|
15
17
|
agent-canvas fetch [--session <id>] Check for feedback (returns immediately)
|
|
16
18
|
agent-canvas watch [--session <id>] Wait for user feedback (blocks until submitted)
|
|
@@ -38,6 +40,7 @@ async function main() {
|
|
|
38
40
|
case "push": return handlePush(rest);
|
|
39
41
|
case "fetch": return handleFetch(rest);
|
|
40
42
|
case "watch": return handleWatch(rest);
|
|
43
|
+
case "instructions": return handleInstructions(rest);
|
|
41
44
|
case "install": return handleInstall(rest);
|
|
42
45
|
case "daemon": return handleDaemon(rest);
|
|
43
46
|
default:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parseArgs } from "util";
|
|
2
|
-
import { existsSync, mkdirSync, cpSync } from "fs";
|
|
2
|
+
import { existsSync, mkdirSync, cpSync, unlinkSync } from "fs";
|
|
3
3
|
import { join } from "path";
|
|
4
4
|
import { homedir } from "os";
|
|
5
5
|
import { PACKAGE_ROOT } from "../config.ts";
|
|
@@ -35,12 +35,12 @@ export async function handleInstall(args: string[]) {
|
|
|
35
35
|
const skillTarget = join(targetBase, "skills", "canvas");
|
|
36
36
|
mkdirSync(skillTarget, { recursive: true });
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
cpSync(join(PACKAGE_ROOT, "skills", "canvas", "SKILL.md"), join(skillTarget, "SKILL.md"));
|
|
39
|
+
|
|
40
|
+
// Clean up files from older versions
|
|
41
|
+
for (const old of ["components.md", "flows.md"]) {
|
|
42
|
+
const p = join(skillTarget, old);
|
|
43
|
+
if (existsSync(p)) unlinkSync(p);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
console.log(` Skill installed to ${skillTarget}`);
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { existsSync, readFileSync, readdirSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { PACKAGE_ROOT } from "../config.ts";
|
|
4
|
+
|
|
5
|
+
const INSTRUCTIONS_DIR = join(PACKAGE_ROOT, "bin", "lib", "instructions");
|
|
6
|
+
|
|
7
|
+
export async function handleInstructions(args: string[]) {
|
|
8
|
+
const topic = args[0];
|
|
9
|
+
|
|
10
|
+
if (!topic) {
|
|
11
|
+
// Base instructions — overview
|
|
12
|
+
const overview = readFileSync(join(INSTRUCTIONS_DIR, "overview.md"), "utf-8");
|
|
13
|
+
process.stdout.write(overview);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (topic === "--list") {
|
|
18
|
+
printAvailableTopics(process.stdout);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Try exact match: topic.md
|
|
23
|
+
const file = join(INSTRUCTIONS_DIR, `${topic}.md`);
|
|
24
|
+
if (existsSync(file)) {
|
|
25
|
+
const content = readFileSync(file, "utf-8");
|
|
26
|
+
process.stdout.write(content);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Not found
|
|
31
|
+
console.error(`Unknown topic: ${topic}\n`);
|
|
32
|
+
printAvailableTopics(process.stderr);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function printAvailableTopics(out: NodeJS.WriteStream) {
|
|
37
|
+
const files = readdirSync(INSTRUCTIONS_DIR)
|
|
38
|
+
.filter(f => f.endsWith(".md") && f !== "overview.md")
|
|
39
|
+
.map(f => f.replace(".md", ""))
|
|
40
|
+
.sort();
|
|
41
|
+
|
|
42
|
+
const components = files.filter(f => f.startsWith("component-"));
|
|
43
|
+
const flows = files.filter(f => f.startsWith("flow-"));
|
|
44
|
+
const other = files.filter(f => !f.startsWith("component-") && !f.startsWith("flow-"));
|
|
45
|
+
|
|
46
|
+
const lines: string[] = ["## Available Detail Topics", ""];
|
|
47
|
+
|
|
48
|
+
if (components.length) {
|
|
49
|
+
lines.push("### Components");
|
|
50
|
+
for (const c of components) lines.push(`- \`${c}\``);
|
|
51
|
+
lines.push("");
|
|
52
|
+
}
|
|
53
|
+
if (flows.length) {
|
|
54
|
+
lines.push("### Flows");
|
|
55
|
+
for (const f of flows) lines.push(`- \`${f}\``);
|
|
56
|
+
lines.push("");
|
|
57
|
+
}
|
|
58
|
+
if (other.length) {
|
|
59
|
+
lines.push("### Other");
|
|
60
|
+
for (const o of other) lines.push(`- \`${o}\``);
|
|
61
|
+
lines.push("");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
lines.push("Usage: `bunx agent-canvas instructions <topic>`");
|
|
65
|
+
out.write(lines.join("\n") + "\n");
|
|
66
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Component: Callout
|
|
2
|
+
|
|
3
|
+
Highlighted information block. Background-tinted, no border.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
- `type` ("info" | "warning" | "danger" | "tip") — determines color and icon
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```jsx
|
|
12
|
+
<Callout type="warning">
|
|
13
|
+
This will invalidate all existing sessions. Plan a maintenance window.
|
|
14
|
+
</Callout>
|
|
15
|
+
|
|
16
|
+
<Callout type="tip">
|
|
17
|
+
Consider using connection pooling for better performance.
|
|
18
|
+
</Callout>
|
|
19
|
+
|
|
20
|
+
<Callout type="danger">
|
|
21
|
+
This action is irreversible.
|
|
22
|
+
</Callout>
|
|
23
|
+
|
|
24
|
+
<Callout type="info">
|
|
25
|
+
Review each requirement. Annotate anything that's wrong or missing.
|
|
26
|
+
</Callout>
|
|
27
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Component: Checklist
|
|
2
|
+
|
|
3
|
+
Visual checklist. Read-only display (feedback via annotations).
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
- `items` (array of `{ label: string, checked: boolean }`)
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```jsx
|
|
12
|
+
<Checklist items={[
|
|
13
|
+
{ label: "Run migration on staging", checked: true },
|
|
14
|
+
{ label: "Verify data integrity", checked: false },
|
|
15
|
+
{ label: "Update API docs", checked: false },
|
|
16
|
+
]} />
|
|
17
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Component: Choice
|
|
2
|
+
|
|
3
|
+
Single-select radio group.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
- `id` (string, required) — unique, used as key in feedback
|
|
8
|
+
- `label` (string, required) — question text
|
|
9
|
+
- `options` (string[], required) — radio options
|
|
10
|
+
- `required` (boolean) — prevents submit until answered
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```jsx
|
|
15
|
+
<Choice id="db-choice" label="Which database?" required
|
|
16
|
+
options={["PostgreSQL", "SQLite", "MongoDB"]} />
|
|
17
|
+
|
|
18
|
+
<Choice id="review-action" label="How should I proceed?" required
|
|
19
|
+
options={[
|
|
20
|
+
"Fix all critical + warnings",
|
|
21
|
+
"Fix critical only, I'll handle warnings",
|
|
22
|
+
"Don't fix anything, this was informational",
|
|
23
|
+
"Let me annotate which ones to fix"
|
|
24
|
+
]} />
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Appears in feedback as: `[db-choice]: PostgreSQL`
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Component: CodeBlock
|
|
2
|
+
|
|
3
|
+
Inline code block with syntax highlighting. For code that's part of the narrative, not from a file on disk.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
- `language` (string) — syntax highlighting language (typescript, javascript, bash, python, sql, etc.)
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```jsx
|
|
12
|
+
<CodeBlock language="typescript">
|
|
13
|
+
interface User {
|
|
14
|
+
id: string;
|
|
15
|
+
email: string;
|
|
16
|
+
}
|
|
17
|
+
</CodeBlock>
|
|
18
|
+
|
|
19
|
+
<CodeBlock language="bash">
|
|
20
|
+
npm run migrate:staging
|
|
21
|
+
</CodeBlock>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**Tip**: For showing code from an actual project file, use `<FilePreview>` instead — it shows the real file with line numbers and the user can browse it.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Custom Components
|
|
2
|
+
|
|
3
|
+
When you use the full module format (`export default function Canvas()`), you can define custom helper components. Standard components remain available without import.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```jsx
|
|
8
|
+
function Metric({ label, value, trend }) {
|
|
9
|
+
const color = trend === 'up' ? 'var(--color-accent-green)' : trend === 'down' ? 'var(--color-accent-red)' : 'var(--color-text-secondary)';
|
|
10
|
+
return (
|
|
11
|
+
<div style={{ display: 'flex', gap: 12, alignItems: 'baseline' }}>
|
|
12
|
+
<span style={{ color: 'var(--color-text-tertiary)', fontSize: '0.75rem' }}>{label}</span>
|
|
13
|
+
<span style={{ color, fontSize: '1.25rem', fontWeight: 600 }}>{value}</span>
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default function Canvas() {
|
|
19
|
+
return (
|
|
20
|
+
<Section title="Performance Summary">
|
|
21
|
+
<Metric label="P95 Latency" value="42ms" trend="down" />
|
|
22
|
+
<Metric label="Error Rate" value="0.3%" trend="up" />
|
|
23
|
+
<Metric label="Throughput" value="1.2k rps" trend="up" />
|
|
24
|
+
</Section>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Tips
|
|
30
|
+
|
|
31
|
+
- Use `style={{ }}` with CSS variables for theming (see `bunx agent-canvas instructions theming`)
|
|
32
|
+
- Standard components (Section, Item, etc.) are available without import even in module format
|
|
33
|
+
- You can use `React.useState`, `React.useEffect`, etc. — React is available globally
|
|
34
|
+
- Use `useFeedback` hook to contribute custom data to the feedback response
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Component: Diff
|
|
2
|
+
|
|
3
|
+
Shows a diff view between two code snippets.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
- `before` (string, required) — original code
|
|
8
|
+
- `after` (string, required) — modified code
|
|
9
|
+
- `language` (string) — syntax highlighting language
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```jsx
|
|
14
|
+
<Diff language="typescript"
|
|
15
|
+
before={`function auth(req) {\n return true;\n}`}
|
|
16
|
+
after={`function auth(req) {\n const token = req.headers.authorization;\n if (!token) throw new Error('Unauthorized');\n return verify(token);\n}`}
|
|
17
|
+
/>
|
|
18
|
+
```
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Component: FilePreview
|
|
2
|
+
|
|
3
|
+
Shows a syntax-highlighted preview of a project file. The daemon serves the file content from the project root.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
- `path` (string, required) — relative to project root
|
|
8
|
+
- `lines` ([number, number]) — line range to show. Omit for full file.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```jsx
|
|
13
|
+
<FilePreview path="src/auth/middleware.ts" />
|
|
14
|
+
<FilePreview path="src/auth/middleware.ts" lines={[42, 87]} />
|
|
15
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Component: ImageView
|
|
2
|
+
|
|
3
|
+
Displays an image from the project directory.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
- `src` (string, required) — path relative to project root
|
|
8
|
+
- `alt` (string) — alt text
|
|
9
|
+
- `caption` (string) — caption displayed below image
|
|
10
|
+
- `width` (number) — max width in pixels
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```jsx
|
|
15
|
+
<ImageView src="docs/architecture.png" />
|
|
16
|
+
<ImageView src="screenshots/before.png" alt="Before refactor" caption="Current state" width={600} />
|
|
17
|
+
```
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Component: Item
|
|
2
|
+
|
|
3
|
+
The primary content block. A flexible card-like row used for tasks, findings, requirements, observations, options — anything that has a title and details.
|
|
4
|
+
|
|
5
|
+
Previously called "Task" — Item is the generalized version.
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
|
|
9
|
+
- `id` (string) — unique ID. Required if the item should be individually addressable in feedback. Optional for informational items.
|
|
10
|
+
- `label` (string, required) — item title, rendered in Inter 600
|
|
11
|
+
- `badge` (string) — short label shown as a small tag. Freeform text.
|
|
12
|
+
- `badgeVariant` ("default" | "success" | "warning" | "danger" | "info") — badge color. Default is neutral gray.
|
|
13
|
+
- `status` ("todo" | "done" | "blocked" | "in-progress") — shows a colored dot. Alternative to badge for plan-style items.
|
|
14
|
+
|
|
15
|
+
**Badge vs Status**: Use `status` for things with a workflow state (tasks in a plan). Use `badge` for categorical labels (requirement priority, review severity, component type). You can use both on the same Item if needed.
|
|
16
|
+
|
|
17
|
+
**Children**: Any content — text, components, code blocks, file previews, nested items.
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```jsx
|
|
22
|
+
{/* As a plan task */}
|
|
23
|
+
<Item id="migrate-db" label="Run database migration" badge="todo">
|
|
24
|
+
Execute the migration script against staging first.
|
|
25
|
+
<CodeBlock language="bash">npm run migrate:staging</CodeBlock>
|
|
26
|
+
</Item>
|
|
27
|
+
|
|
28
|
+
{/* As a review finding */}
|
|
29
|
+
<Item id="finding-1" label="Missing null check in auth handler" badge="critical" badgeVariant="danger">
|
|
30
|
+
The handler doesn't check for missing tokens.
|
|
31
|
+
<FilePreview path="src/auth.ts" lines={[42, 48]} />
|
|
32
|
+
</Item>
|
|
33
|
+
|
|
34
|
+
{/* As a requirement */}
|
|
35
|
+
<Item id="req-auth" label="JWT authentication" badge="must-have" badgeVariant="danger">
|
|
36
|
+
All API endpoints must require a valid JWT token.
|
|
37
|
+
</Item>
|
|
38
|
+
|
|
39
|
+
{/* As an architecture component */}
|
|
40
|
+
<Item label="API Gateway" badge="core" badgeVariant="info">
|
|
41
|
+
Routes requests to downstream services. Handles rate limiting.
|
|
42
|
+
</Item>
|
|
43
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Component: Markdown
|
|
2
|
+
|
|
3
|
+
Renders markdown content with full GFM support (headings, lists, tables, code blocks, links, etc.). Two modes:
|
|
4
|
+
|
|
5
|
+
## Inline source — markdown as children
|
|
6
|
+
|
|
7
|
+
```jsx
|
|
8
|
+
<Markdown>{`
|
|
9
|
+
# Summary
|
|
10
|
+
|
|
11
|
+
This is **bold** and *italic*. Here's a list:
|
|
12
|
+
|
|
13
|
+
- First item
|
|
14
|
+
- Second item
|
|
15
|
+
- Nested item
|
|
16
|
+
|
|
17
|
+
\`\`\`typescript
|
|
18
|
+
const x = 42;
|
|
19
|
+
\`\`\`
|
|
20
|
+
`}</Markdown>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## File reference — loads file content at compile time
|
|
24
|
+
|
|
25
|
+
```jsx
|
|
26
|
+
<Markdown file="docs/architecture.md" />
|
|
27
|
+
<Markdown file="CHANGELOG.md" />
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Props
|
|
31
|
+
|
|
32
|
+
- `file` (string) — path relative to project root. Content resolved at compile time.
|
|
33
|
+
- Children (string) — inline markdown source. Used when `file` is not specified.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Component: Mermaid
|
|
2
|
+
|
|
3
|
+
Renders a Mermaid diagram. Supports flowchart, sequence, ER, gantt, pie, and more. The daemon bundles mermaid.js with a custom dark theme matching Canvas colors.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```jsx
|
|
8
|
+
<Mermaid>{`
|
|
9
|
+
graph TD
|
|
10
|
+
A[Client] -->|HTTP| B(API Gateway)
|
|
11
|
+
B --> C{Auth?}
|
|
12
|
+
C -->|Valid| D[Service]
|
|
13
|
+
C -->|Invalid| E[401 Response]
|
|
14
|
+
`}</Mermaid>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Sequence diagram
|
|
18
|
+
|
|
19
|
+
```jsx
|
|
20
|
+
<Mermaid>{`
|
|
21
|
+
sequenceDiagram
|
|
22
|
+
Client->>+API: POST /login
|
|
23
|
+
API->>+DB: Find user
|
|
24
|
+
DB-->>-API: User record
|
|
25
|
+
API-->>-Client: JWT token
|
|
26
|
+
`}</Mermaid>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### ER diagram
|
|
30
|
+
|
|
31
|
+
```jsx
|
|
32
|
+
<Mermaid>{`
|
|
33
|
+
erDiagram
|
|
34
|
+
USER ||--o{ ORDER : places
|
|
35
|
+
ORDER ||--|{ LINE-ITEM : contains
|
|
36
|
+
PRODUCT ||--o{ LINE-ITEM : "ordered in"
|
|
37
|
+
`}</Mermaid>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
For complex diagrams, prefer Mermaid over raw SVG. Use raw `<svg>` only when Mermaid can't express what you need.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Component: MultiChoice
|
|
2
|
+
|
|
3
|
+
Multi-select checkboxes.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
- `id` (string, required) — unique, used as key in feedback
|
|
8
|
+
- `label` (string, required) — question text
|
|
9
|
+
- `options` (string[], required) — checkbox options
|
|
10
|
+
- `required` (boolean) — prevents submit until at least one selected
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```jsx
|
|
15
|
+
<MultiChoice id="affected-areas" label="Which areas need changes?" required
|
|
16
|
+
options={["Models", "API", "Frontend", "Tests"]} />
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Appears in feedback as: `[affected-areas]: Models, API, Tests`
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Component: Priority
|
|
2
|
+
|
|
3
|
+
Inline badge. Use inside Item labels or body text.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
- `level` ("high" | "medium" | "low")
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```jsx
|
|
12
|
+
<Item label="Fix the race condition">
|
|
13
|
+
<Priority level="high" /> This causes data corruption under load.
|
|
14
|
+
</Item>
|
|
15
|
+
```
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Component: RangeInput
|
|
2
|
+
|
|
3
|
+
Slider for numeric ranges or scales.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
- `id` (string, required) — unique, used as key in feedback
|
|
8
|
+
- `label` (string, required) — question text
|
|
9
|
+
- `min` (number) — minimum value
|
|
10
|
+
- `max` (number) — maximum value
|
|
11
|
+
- `minLabel` (string) — label for minimum end
|
|
12
|
+
- `maxLabel` (string) — label for maximum end
|
|
13
|
+
- `required` (boolean) — prevents submit until set
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
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 />
|
|
20
|
+
```
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Component: Section
|
|
2
|
+
|
|
3
|
+
Top-level grouping. Rendered as a serif heading with generous spacing. Collapsible (chevron appears on hover).
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
- `title` (string, required) — section heading, rendered in Instrument Serif
|
|
8
|
+
- `collapsed` (boolean, default false) — start collapsed
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```jsx
|
|
13
|
+
<Section title="Phase 1: Data Migration">
|
|
14
|
+
A brief description of this section.
|
|
15
|
+
|
|
16
|
+
{/* Items, callouts, code blocks, diagrams, etc. */}
|
|
17
|
+
</Section>
|
|
18
|
+
|
|
19
|
+
<Section title="Advanced Details" collapsed>
|
|
20
|
+
This section starts collapsed — user clicks to expand.
|
|
21
|
+
</Section>
|
|
22
|
+
```
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Diagrams with Raw SVG
|
|
2
|
+
|
|
3
|
+
For custom visuals that Mermaid can't express, write `<svg>` directly. Use CSS variables for colors to match the theme.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```jsx
|
|
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>
|
|
13
|
+
|
|
14
|
+
<line x1="130" y1="35" x2="180" y2="35" stroke="var(--color-text-tertiary)" strokeWidth="1.5"
|
|
15
|
+
markerEnd="url(#arrow)" />
|
|
16
|
+
|
|
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>
|
|
21
|
+
|
|
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>
|
|
28
|
+
</svg>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Keep SVG diagrams simple. For anything with more than ~5 nodes, prefer Mermaid.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Component: Table
|
|
2
|
+
|
|
3
|
+
Simple data table.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
- `headers` (string[]) — column headers
|
|
8
|
+
- `rows` (string[][]) — row data
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```jsx
|
|
13
|
+
<Table
|
|
14
|
+
headers={["Endpoint", "Method", "Auth"]}
|
|
15
|
+
rows={[
|
|
16
|
+
["/users", "GET", "Required"],
|
|
17
|
+
["/users/:id", "PUT", "Owner only"],
|
|
18
|
+
["/health", "GET", "None"],
|
|
19
|
+
]}
|
|
20
|
+
/>
|
|
21
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Hook: useFeedback
|
|
2
|
+
|
|
3
|
+
Hook for custom components to contribute computed/derived data to the feedback response. Use when built-in interactive components don't cover your needs.
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
useFeedback(id: string, markdown: string, options?: { label?: string; required?: boolean })
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
- `id` (string, required) — unique feedback entry identifier
|
|
12
|
+
- `markdown` (string, required) — markdown included in feedback, re-evaluated each render
|
|
13
|
+
- `options.label` — display label in feedback preview
|
|
14
|
+
- `options.required` — blocks submit while markdown is empty
|
|
15
|
+
|
|
16
|
+
Registers on mount, updates on change, unregisters on unmount.
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```jsx
|
|
21
|
+
function ProConList() {
|
|
22
|
+
const [pros, setPros] = React.useState(["Fast builds"]);
|
|
23
|
+
const [cons, setCons] = React.useState(["New runtime"]);
|
|
24
|
+
|
|
25
|
+
useFeedback(
|
|
26
|
+
"pro-con",
|
|
27
|
+
`**Pros:** ${pros.join(", ")}\n**Cons:** ${cons.join(", ")}`,
|
|
28
|
+
{ label: "Pro/Con Analysis" },
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
return <div>{/* UI for managing pros/cons */}</div>;
|
|
32
|
+
}
|
|
33
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Component: UserInput
|
|
2
|
+
|
|
3
|
+
Free text input.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
- `id` (string, required) — unique, used as key in feedback
|
|
8
|
+
- `label` (string, required) — question text
|
|
9
|
+
- `placeholder` (string) — hint text
|
|
10
|
+
- `required` (boolean) — prevents submit until filled
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```jsx
|
|
15
|
+
<UserInput id="constraints" label="Any constraints I should know about?"
|
|
16
|
+
placeholder="e.g. must work with existing Redis setup" required />
|
|
17
|
+
```
|