agent-canvas 0.1.10 → 0.1.12
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/daemon/build.ts +1 -1
- package/daemon/client/App.tsx +39 -10
- package/daemon/client/index.html +1 -1
- package/daemon/dist/client.js +47 -47
- package/daemon/dist/index.html +1 -1
- package/daemon/src/compiler.ts +43 -15
- package/package.json +1 -1
- package/skills/canvas/SKILL.md +15 -7
- package/skills/canvas/flows.md +1 -1
package/daemon/dist/index.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
6
|
<title>Agent Canvas</title>
|
|
7
|
-
<script
|
|
7
|
+
<script>!function(){var p=localStorage.getItem('canvas-theme')||'auto';document.documentElement.dataset.theme=p==='auto'?(matchMedia('(prefers-color-scheme:dark)').matches?'dark':'light'):p}()</script>
|
|
8
8
|
<link rel="stylesheet" href="/assets/client.css" />
|
|
9
9
|
<link rel="stylesheet" href="https://unpkg.com/@highlightjs/cdn-assets@11.11.1/styles/github-dark-dimmed.min.css" />
|
|
10
10
|
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
package/daemon/src/compiler.ts
CHANGED
|
@@ -33,22 +33,28 @@ export async function compilePlan(jsx: string, projectRoot?: string): Promise<Co
|
|
|
33
33
|
try {
|
|
34
34
|
writeFileSync(tmpFile, source);
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
36
|
+
try {
|
|
37
|
+
const result = await Bun.build({
|
|
38
|
+
entrypoints: [tmpFile],
|
|
39
|
+
format: "esm",
|
|
40
|
+
external: ["react", "react-dom", "#canvas/components", "#canvas/runtime"],
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
if (!result.success) {
|
|
44
|
+
const errors = result.logs
|
|
45
|
+
.filter((l) => l.level === "error")
|
|
46
|
+
.map((l) => l.message)
|
|
47
|
+
.join("\n");
|
|
48
|
+
return { ok: false, error: errors || "Compilation failed" };
|
|
49
|
+
}
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
const js = await result.outputs[0].text();
|
|
52
|
+
return { ok: true, js };
|
|
53
|
+
} catch {
|
|
54
|
+
// Bun.build() can throw "Unknown Error, TODO" in long-running processes
|
|
55
|
+
// when its internal bundler state gets corrupted. Fall back to subprocess.
|
|
56
|
+
return await compilePlanSubprocess(tmpFile);
|
|
57
|
+
}
|
|
52
58
|
} catch (e: any) {
|
|
53
59
|
return { ok: false, error: e.message };
|
|
54
60
|
} finally {
|
|
@@ -56,6 +62,28 @@ export async function compilePlan(jsx: string, projectRoot?: string): Promise<Co
|
|
|
56
62
|
}
|
|
57
63
|
}
|
|
58
64
|
|
|
65
|
+
async function compilePlanSubprocess(tmpFile: string): Promise<CompileResult> {
|
|
66
|
+
const outFile = `${tmpFile}.out.js`;
|
|
67
|
+
const proc = Bun.spawn(
|
|
68
|
+
["bun", "build", tmpFile, "--format=esm",
|
|
69
|
+
"--external=react", "--external=react-dom",
|
|
70
|
+
"--external=#canvas/components", "--external=#canvas/runtime",
|
|
71
|
+
"--outfile", outFile],
|
|
72
|
+
{ stdout: "pipe", stderr: "pipe" },
|
|
73
|
+
);
|
|
74
|
+
const exitCode = await proc.exited;
|
|
75
|
+
if (exitCode !== 0) {
|
|
76
|
+
const stderr = await new Response(proc.stderr).text();
|
|
77
|
+
return { ok: false, error: stderr || "Compilation failed" };
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
const js = readFileSync(outFile, "utf-8");
|
|
81
|
+
return { ok: true, js };
|
|
82
|
+
} finally {
|
|
83
|
+
try { unlinkSync(outFile); } catch {}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
59
87
|
/**
|
|
60
88
|
* Find <Markdown file="..." /> tags and inject __content with the file contents
|
|
61
89
|
* resolved at compile time.
|
package/package.json
CHANGED
package/skills/canvas/SKILL.md
CHANGED
|
@@ -57,32 +57,37 @@ This opens the canvas in the user's browser (first time) and exits immediately.
|
|
|
57
57
|
|
|
58
58
|
### Waiting for feedback
|
|
59
59
|
|
|
60
|
-
After pushing,
|
|
60
|
+
After pushing, start the watch command **in the background** using the Bash tool's `run_in_background` parameter:
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
|
+
# Use Bash tool with run_in_background: true
|
|
63
64
|
bunx agent-canvas watch --session ${CLAUDE_SESSION_ID}
|
|
64
65
|
```
|
|
65
66
|
|
|
66
|
-
This **
|
|
67
|
+
This runs the watch process in the background. You will be **automatically notified** when the user submits feedback — the output will contain the feedback markdown. Do NOT poll, sleep, or proactively check on it. Just stop and wait for the notification.
|
|
67
68
|
|
|
68
|
-
|
|
69
|
+
If feedback was already submitted but not yet consumed, the command returns immediately with the existing feedback.
|
|
70
|
+
|
|
71
|
+
**Important**: After starting the background watch, do not continue with other work unless instructed. Wait for the notification that feedback has arrived before proceeding.
|
|
69
72
|
|
|
70
73
|
### Checking for feedback without blocking
|
|
71
74
|
|
|
72
|
-
Use `fetch` to
|
|
75
|
+
Use `fetch` to retrieve feedback if the user tells you they've already submitted:
|
|
73
76
|
|
|
74
77
|
```bash
|
|
75
78
|
bunx agent-canvas fetch --session ${CLAUDE_SESSION_ID}
|
|
76
79
|
```
|
|
77
80
|
|
|
78
|
-
Returns immediately — prints feedback to stdout if available, otherwise produces no output. Use this
|
|
81
|
+
Returns immediately — prints feedback to stdout if available, otherwise produces no output. Use this when the user tells you they've submitted feedback (e.g. after a reconnect or if the background watch was lost).
|
|
79
82
|
|
|
80
83
|
### Iterating
|
|
81
84
|
|
|
82
|
-
Use the **Edit** tool to modify the existing JSX based on feedback — targeted edits, not full rewrites. Then push and
|
|
85
|
+
Use the **Edit** tool to modify the existing JSX based on feedback — targeted edits, not full rewrites. Then push and watch again:
|
|
83
86
|
|
|
84
87
|
```bash
|
|
85
88
|
bunx agent-canvas push .claude/agent-canvas/${CLAUDE_SESSION_ID}/plan.jsx --session ${CLAUDE_SESSION_ID} --label "Implementation Plan (revised)"
|
|
89
|
+
|
|
90
|
+
# Use Bash tool with run_in_background: true
|
|
86
91
|
bunx agent-canvas watch --session ${CLAUDE_SESSION_ID}
|
|
87
92
|
```
|
|
88
93
|
|
|
@@ -109,12 +114,15 @@ Maintain separate files for different phases:
|
|
|
109
114
|
|
|
110
115
|
```bash
|
|
111
116
|
bunx agent-canvas push .claude/agent-canvas/${CLAUDE_SESSION_ID}/discovery.jsx --session ${CLAUDE_SESSION_ID} --label "Discovery"
|
|
117
|
+
# watch with run_in_background: true, wait for notification
|
|
112
118
|
bunx agent-canvas watch --session ${CLAUDE_SESSION_ID}
|
|
113
119
|
# ... process feedback ...
|
|
114
120
|
bunx agent-canvas push .claude/agent-canvas/${CLAUDE_SESSION_ID}/requirements.jsx --session ${CLAUDE_SESSION_ID} --label "Requirements"
|
|
121
|
+
# watch with run_in_background: true, wait for notification
|
|
115
122
|
bunx agent-canvas watch --session ${CLAUDE_SESSION_ID}
|
|
116
123
|
# ... process feedback ...
|
|
117
124
|
bunx agent-canvas push .claude/agent-canvas/${CLAUDE_SESSION_ID}/plan.jsx --session ${CLAUDE_SESSION_ID} --label "Implementation Plan"
|
|
125
|
+
# watch with run_in_background: true, wait for notification
|
|
118
126
|
bunx agent-canvas watch --session ${CLAUDE_SESSION_ID}
|
|
119
127
|
```
|
|
120
128
|
|
|
@@ -156,7 +164,7 @@ User wants to make a decision?
|
|
|
156
164
|
2. **Announce** briefly: "I'll start with discovery, then create a detailed plan."
|
|
157
165
|
3. **Write canvas JSX** with the Write tool to `.claude/agent-canvas/${CLAUDE_SESSION_ID}/<name>.jsx`
|
|
158
166
|
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
|
|
167
|
+
5. **IMMEDIATELY watch in background** — run `bunx agent-canvas watch --session ${CLAUDE_SESSION_ID}` with `run_in_background: true` right after push. Never stop after pushing. The push→watch sequence is atomic: no push without a watch. You will be notified when feedback arrives — do not poll or sleep.
|
|
160
168
|
6. **Read feedback** — check for annotations, answers, added context files, approval
|
|
161
169
|
7. **Edit with the Edit tool and re-push + watch**, or advance to next phase
|
|
162
170
|
8. **After implementation**, push a summary canvas
|
package/skills/canvas/flows.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Each flow is a sequence of canvas rounds. Phases can be skipped or combined based on context.
|
|
4
4
|
|
|
5
|
-
**Tooling reminder**: Write all `.jsx` files using the **Write** tool to `.claude/agent-canvas/${CLAUDE_SESSION_ID}/`. Edit them with the **Edit** tool. Push with `bunx agent-canvas push .claude/agent-canvas/${CLAUDE_SESSION_ID}/<file>.jsx --session ${CLAUDE_SESSION_ID} --label "<Label>"`, then `bunx agent-canvas watch --session ${CLAUDE_SESSION_ID}`
|
|
5
|
+
**Tooling reminder**: Write all `.jsx` files using the **Write** tool to `.claude/agent-canvas/${CLAUDE_SESSION_ID}/`. Edit them with the **Edit** tool. Push with `bunx agent-canvas push .claude/agent-canvas/${CLAUDE_SESSION_ID}/<file>.jsx --session ${CLAUDE_SESSION_ID} --label "<Label>"`, then run `bunx agent-canvas watch --session ${CLAUDE_SESSION_ID}` with `run_in_background: true` — you'll be notified when the user submits feedback. The JSX blocks below show what to write — they are the file content, not bash commands.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|