agent-canvas 0.1.7 → 0.1.9
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/.github/workflows/ci.yml +23 -0
- package/.github/workflows/release.yml +36 -0
- package/CLAUDE.md +86 -0
- package/bin/lib/commands/push.ts +2 -1
- package/bun.lock +176 -0
- package/daemon/bunfig.toml +2 -0
- package/daemon/client/AnnotationSidebar.tsx +35 -9
- package/daemon/client/App.tsx +157 -2
- package/daemon/client/CompareView.tsx +1 -1
- package/daemon/client/PlanRenderer.tsx +2 -2
- package/daemon/client/annotationContext.ts +1 -1
- package/daemon/client/generateMarkdown.ts +13 -2
- package/daemon/client/utils.ts +3 -0
- package/daemon/dist/client.css +1 -1
- package/daemon/dist/client.js +76 -76
- package/daemon/langMap.ts +8 -0
- package/daemon/src/handlers/api.ts +2 -2
- package/daemon/src/session.ts +3 -2
- package/daemon/tsconfig.json +20 -0
- package/package.json +2 -12
- package/skills/canvas/SKILL.md +20 -6
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** File extension → highlight.js language name mapping. */
|
|
2
|
+
export const LANG_MAP: Record<string, string> = {
|
|
3
|
+
ts: "typescript", tsx: "typescript", js: "javascript", jsx: "javascript",
|
|
4
|
+
py: "python", rs: "rust", go: "go", rb: "ruby", java: "java",
|
|
5
|
+
json: "json", yaml: "yaml", yml: "yaml", md: "markdown",
|
|
6
|
+
css: "css", html: "html", sh: "bash", bash: "bash", toml: "toml",
|
|
7
|
+
sql: "sql", xml: "xml", c: "c", cpp: "cpp", h: "c",
|
|
8
|
+
};
|
|
@@ -27,7 +27,7 @@ export function createApiHandlers(ctx: ApiContext): Route[] {
|
|
|
27
27
|
const sessionId = match.pathname.groups.id!;
|
|
28
28
|
try {
|
|
29
29
|
const body = await req.json();
|
|
30
|
-
const { jsx, projectRoot, label, sourceFile } = body;
|
|
30
|
+
const { jsx, projectRoot, label, sourceFile, response } = body;
|
|
31
31
|
if (!jsx) return jsonResponse({ error: "Missing jsx" }, 400);
|
|
32
32
|
|
|
33
33
|
const unconsumed = sessionManager.getLatestUnconsumedFeedback(sessionId);
|
|
@@ -42,7 +42,7 @@ export function createApiHandlers(ctx: ApiContext): Route[] {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
const isNew = !sessionManager.get(sessionId);
|
|
45
|
-
const session = sessionManager.upsert(sessionId, jsx, projectRoot || process.cwd(), label, sourceFile);
|
|
45
|
+
const session = sessionManager.upsert(sessionId, jsx, projectRoot || process.cwd(), label, sourceFile, response);
|
|
46
46
|
|
|
47
47
|
const result = await compilePlan(jsx, session.projectRoot);
|
|
48
48
|
if (result.ok) {
|
package/daemon/src/session.ts
CHANGED
|
@@ -9,6 +9,7 @@ export interface RevisionInfo {
|
|
|
9
9
|
createdAt: string;
|
|
10
10
|
hasFeedback: boolean;
|
|
11
11
|
feedbackConsumed: boolean;
|
|
12
|
+
response?: string;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
export interface SessionData {
|
|
@@ -156,12 +157,12 @@ export class SessionManager {
|
|
|
156
157
|
}
|
|
157
158
|
}
|
|
158
159
|
|
|
159
|
-
upsert(id: string, jsx: string, projectRoot: string, label?: string, sourceFile?: string): SessionData {
|
|
160
|
+
upsert(id: string, jsx: string, projectRoot: string, label?: string, sourceFile?: string, response?: string): SessionData {
|
|
160
161
|
const existing = this.sessions.get(id);
|
|
161
162
|
const now = new Date().toISOString();
|
|
162
163
|
const revision = existing ? existing.currentRevision + 1 : 1;
|
|
163
164
|
|
|
164
|
-
const revInfo: RevisionInfo = { revision, createdAt: now, hasFeedback: false, feedbackConsumed: false, ...(label ? { label } : {}), ...(sourceFile ? { sourceFile } : {}) };
|
|
165
|
+
const revInfo: RevisionInfo = { revision, createdAt: now, hasFeedback: false, feedbackConsumed: false, ...(label ? { label } : {}), ...(sourceFile ? { sourceFile } : {}), ...(response ? { response } : {}) };
|
|
165
166
|
const revisions = existing ? [...existing.revisions, revInfo] : [revInfo];
|
|
166
167
|
|
|
167
168
|
const session: SessionData = {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ESNext",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"jsx": "react-jsx",
|
|
7
|
+
"strict": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"noEmit": true,
|
|
11
|
+
"rootDir": ".",
|
|
12
|
+
"types": ["@types/bun"],
|
|
13
|
+
"paths": {
|
|
14
|
+
"#canvas/runtime": ["./client/runtime.ts"],
|
|
15
|
+
"#canvas/components": ["./client/components/index.ts"]
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"include": ["src/**/*", "client/**/*"],
|
|
19
|
+
"exclude": ["client/compat/**/*"]
|
|
20
|
+
}
|
package/package.json
CHANGED
|
@@ -1,21 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-canvas",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Interactive visual canvas for Claude Code — rich annotatable documents in the browser",
|
|
5
5
|
"bin": {
|
|
6
6
|
"agent-canvas": "bin/agent-canvas.js"
|
|
7
7
|
},
|
|
8
|
-
|
|
9
|
-
"bin/",
|
|
10
|
-
"daemon/src/",
|
|
11
|
-
"daemon/client/",
|
|
12
|
-
"daemon/dist/",
|
|
13
|
-
"daemon/build.ts",
|
|
14
|
-
"daemon/package.json",
|
|
15
|
-
"skills/",
|
|
16
|
-
"hooks/"
|
|
17
|
-
],
|
|
18
|
-
"scripts": {
|
|
8
|
+
"scripts": {
|
|
19
9
|
"build": "bun daemon/build.ts",
|
|
20
10
|
"typecheck": "tsc --noEmit && tsc --noEmit -p daemon/tsconfig.json",
|
|
21
11
|
"prepublishOnly": "bun daemon/build.ts"
|
package/skills/canvas/SKILL.md
CHANGED
|
@@ -88,6 +88,21 @@ bunx agent-canvas watch --session ${CLAUDE_SESSION_ID}
|
|
|
88
88
|
|
|
89
89
|
Each push creates a new **round** — the user sees previous rounds and their feedback in the UI.
|
|
90
90
|
|
|
91
|
+
### Responding to feedback
|
|
92
|
+
|
|
93
|
+
When pushing a revised canvas after receiving user feedback, use `--response` to tell the user how you addressed their feedback. The response renders as a short banner at the top of the canvas.
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
bunx agent-canvas push .claude/agent-canvas/${CLAUDE_SESSION_ID}/plan.jsx --session ${CLAUDE_SESSION_ID} --label "Plan (revised)" --response "Incorporated all feedback. Switched to connection pooling as suggested. I kept the sync approach for writes — see the note in Phase 2 for my reasoning."
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Use `--response` to:
|
|
100
|
+
- Confirm what you incorporated and how
|
|
101
|
+
- Explain any opposing stance — if you disagree with a suggestion, say why
|
|
102
|
+
- Call out anything you intentionally did NOT change and why
|
|
103
|
+
|
|
104
|
+
Keep it concise (2-4 sentences). The user can see the diff in the canvas UI, so focus on the "why" not the "what".
|
|
105
|
+
|
|
91
106
|
### Multiple Canvases
|
|
92
107
|
|
|
93
108
|
Maintain separate files for different phases:
|
|
@@ -140,12 +155,11 @@ User wants to make a decision?
|
|
|
140
155
|
1. **Determine flow** from user intent
|
|
141
156
|
2. **Announce** briefly: "I'll start with discovery, then create a detailed plan."
|
|
142
157
|
3. **Write canvas JSX** with the Write tool to `.claude/agent-canvas/${CLAUDE_SESSION_ID}/<name>.jsx`
|
|
143
|
-
4. **Push**:
|
|
144
|
-
5. **
|
|
145
|
-
6. **
|
|
146
|
-
7. **
|
|
147
|
-
8. **
|
|
148
|
-
9. **After implementation**, push a summary canvas
|
|
158
|
+
4. **Push + tell the user**: Push the canvas and show the `browserUrl` from the output so the user can open it
|
|
159
|
+
5. **IMMEDIATELY watch** — run `bunx agent-canvas watch --session ${CLAUDE_SESSION_ID}` right after push, in the same response. Never stop after pushing. The push→watch sequence is atomic: no push without a watch. The watch blocks until the user submits feedback.
|
|
160
|
+
6. **Read feedback** — check for annotations, answers, added context files, approval
|
|
161
|
+
7. **Edit with the Edit tool and re-push + watch**, or advance to next phase
|
|
162
|
+
8. **After implementation**, push a summary canvas
|
|
149
163
|
|
|
150
164
|
## Interview Integration
|
|
151
165
|
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ESNext",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"allowImportingTsExtensions": true,
|
|
10
|
+
"noEmit": true,
|
|
11
|
+
"types": ["@types/bun"]
|
|
12
|
+
},
|
|
13
|
+
"include": ["bin/**/*"]
|
|
14
|
+
}
|