agent-canvas 0.1.23 → 0.1.25
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/lib/commands/push.ts +8 -4
- package/daemon/src/compiler.ts +22 -1
- package/package.json +1 -1
package/bin/lib/commands/push.ts
CHANGED
|
@@ -54,10 +54,14 @@ export async function handlePush(args: string[]) {
|
|
|
54
54
|
|
|
55
55
|
let result = await response.json() as any;
|
|
56
56
|
|
|
57
|
-
// Bun.build()
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
|
|
57
|
+
// Bun.build() / Bun.Transpiler can fail in long-running daemons due to
|
|
58
|
+
// internal state corruption, CWD unlinking, etc. Restart and retry once.
|
|
59
|
+
// Skip restart only for clear user errors (syntax errors with line/col,
|
|
60
|
+
// runtime validation errors) — those won't be fixed by a restart.
|
|
61
|
+
const isUserError = !result.ok && result.errors && Object.values(result.errors).every((e: any) =>
|
|
62
|
+
typeof e === "string" && (/\(line \d+, col \d+\)/.test(e) || e.startsWith("Runtime error:")));
|
|
63
|
+
const shouldRestart = !result.ok && result.error === "Canvas compilation failed" && !isUserError;
|
|
64
|
+
if (shouldRestart) {
|
|
61
65
|
console.error("Compilation failed, restarting daemon and retrying...");
|
|
62
66
|
stopDaemon();
|
|
63
67
|
await startDaemon();
|
package/daemon/src/compiler.ts
CHANGED
|
@@ -20,6 +20,9 @@ const { Section, Item, Task, FilePreview, CodeBlock, Callout,
|
|
|
20
20
|
Markdown, useFeedback, useAnnotations } = C;
|
|
21
21
|
`;
|
|
22
22
|
|
|
23
|
+
/** Number of lines in COMPONENT_IMPORTS — used to adjust error line numbers */
|
|
24
|
+
const COMPONENT_IMPORTS_LINES = COMPONENT_IMPORTS.split("\n").length - 1;
|
|
25
|
+
|
|
23
26
|
// --- Validation via Preact --------------------------------------------------
|
|
24
27
|
// After Bun.build() succeeds we strip ESM syntax from the compiled output,
|
|
25
28
|
// provide Preact as the React implementation with lightweight stub components,
|
|
@@ -121,7 +124,11 @@ async function validateCompiledPlan(js: string): Promise<{ ok: true } | { ok: fa
|
|
|
121
124
|
try {
|
|
122
125
|
await mermaid.parse(source);
|
|
123
126
|
} catch (e: any) {
|
|
124
|
-
|
|
127
|
+
const msg = e?.message || String(e);
|
|
128
|
+
// DOMPurify doesn't work in Bun (no DOM) — mermaid.parse() triggers
|
|
129
|
+
// it for some diagram types even though it's just parsing. Skip these.
|
|
130
|
+
if (msg.includes("DOMPurify")) continue;
|
|
131
|
+
return { ok: false, error: `Mermaid syntax error: ${msg}` };
|
|
125
132
|
}
|
|
126
133
|
}
|
|
127
134
|
|
|
@@ -148,6 +155,20 @@ export async function compilePlan(jsx: string, projectRoot?: string): Promise<Co
|
|
|
148
155
|
? `${COMPONENT_IMPORTS}\n${jsx}`
|
|
149
156
|
: `${COMPONENT_IMPORTS}\nexport default function Plan() {\n return (<>${jsx}</>);\n}\n`;
|
|
150
157
|
|
|
158
|
+
// Pre-validate syntax with Bun.Transpiler — gives precise error positions,
|
|
159
|
+
// unlike Bun.build() which throws opaque "Bundle failed" for syntax errors.
|
|
160
|
+
try {
|
|
161
|
+
const transpiler = new Bun.Transpiler({ loader: "jsx" });
|
|
162
|
+
transpiler.transformSync(source);
|
|
163
|
+
} catch (syntaxError: any) {
|
|
164
|
+
const pos = syntaxError?.position;
|
|
165
|
+
// Offset: COMPONENT_IMPORTS lines + wrapper lines (export default function Plan() + return)
|
|
166
|
+
const wrapperLines = hasDefaultExport ? 1 : 2;
|
|
167
|
+
const lineOffset = COMPONENT_IMPORTS_LINES + wrapperLines;
|
|
168
|
+
const loc = pos ? ` (line ${pos.line - lineOffset}, col ${pos.column})` : "";
|
|
169
|
+
return { ok: false, error: `${syntaxError?.message || "Syntax error"}${loc}` };
|
|
170
|
+
}
|
|
171
|
+
|
|
151
172
|
const tmpFile = join(COMPILE_TEMP_DIR, `plan-${randomUUID()}.jsx`);
|
|
152
173
|
|
|
153
174
|
try {
|