agent-canvas 0.1.44 → 0.2.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.
- package/README.md +14 -0
- package/bin/lib/commands/daemon.ts +3 -6
- package/bin/lib/commands/push.ts +1 -1
- package/bin/lib/daemon-lifecycle.ts +65 -72
- package/bin/lib/helpers.test.ts +1 -0
- package/bin/lib/helpers.ts +30 -74
- package/daemon/build.ts +37 -16
- package/daemon/client/App.tsx +27 -61
- package/daemon/client/CompareView.tsx +4 -4
- package/daemon/client/FileBrowser.tsx +4 -4
- package/daemon/client/FileViewer.tsx +4 -4
- package/daemon/client/OverviewView.tsx +2 -2
- package/daemon/client/RevisionSelect.tsx +1 -1
- package/daemon/client/canvas-runtime.ts +1 -0
- package/daemon/client/clientApi.ts +18 -0
- package/daemon/client/components/index.ts +3 -16
- package/daemon/client/styles.css +4 -457
- package/daemon/dist/annotations-runtime.js +1 -0
- package/daemon/dist/client.css +1 -1
- package/daemon/dist/client.js +76 -76
- package/daemon/dist/components.js +59 -59
- package/daemon/dist/index.html +1 -0
- package/daemon/dist/preact-compat.js +1 -1
- package/daemon/dist/runtime.js +1 -1
- package/daemon/src/components.ts +13 -0
- package/daemon/src/handlers/api.ts +13 -9
- package/daemon/src/handlers/files.ts +2 -3
- package/daemon/src/handlers/static.ts +1 -1
- package/daemon/src/handlers/uploads.ts +2 -3
- package/daemon/src/paths.ts +10 -24
- package/daemon/src/remote-feedback.test.ts +1 -1
- package/daemon/src/remote-feedback.ts +1 -1
- package/daemon/src/secrets-api.test.ts +2 -2
- package/daemon/src/server.ts +11 -10
- package/daemon/src/share-e2e.test.ts +1 -1
- package/daemon/src/share.test.ts +1 -1
- package/daemon/src/share.ts +1 -1
- package/daemon/tsconfig.json +1 -3
- package/package.json +11 -4
- package/.github/dark.png +0 -0
- package/.github/light.png +0 -0
- package/.github/workflows/ci.yml +0 -48
- package/.github/workflows/deploy-worker-prod.yml +0 -19
- package/.github/workflows/deploy-worker-stage.yml +0 -21
- package/.github/workflows/deploy-worker.yml +0 -72
- package/.github/workflows/release.yml +0 -36
- package/CLAUDE.md +0 -86
- package/bun.lock +0 -377
- package/daemon/client/AnnotationEditor.tsx +0 -315
- package/daemon/client/AnnotationProvider.tsx +0 -195
- package/daemon/client/AnnotationSidebar.tsx +0 -627
- package/daemon/client/FileIcon.tsx +0 -76
- package/daemon/client/PlanRenderer.tsx +0 -614
- package/daemon/client/Popover.tsx +0 -350
- package/daemon/client/RenderErrorContext.ts +0 -11
- package/daemon/client/ResponsePreview.tsx +0 -186
- package/daemon/client/SessionContext.tsx +0 -3
- package/daemon/client/annotationContext.ts +0 -114
- package/daemon/client/annotationDom.ts +0 -104
- package/daemon/client/annotationDraft.test.ts +0 -188
- package/daemon/client/annotationDraft.ts +0 -130
- package/daemon/client/compat/preact-all.ts +0 -4
- package/daemon/client/components/Callout.tsx +0 -26
- package/daemon/client/components/Checklist.tsx +0 -37
- package/daemon/client/components/Choice.tsx +0 -176
- package/daemon/client/components/CodeBlock.tsx +0 -35
- package/daemon/client/components/Diff.tsx +0 -65
- package/daemon/client/components/FilePreview.tsx +0 -88
- package/daemon/client/components/Image.tsx +0 -45
- package/daemon/client/components/Markdown.tsx +0 -44
- package/daemon/client/components/Mermaid.tsx +0 -565
- package/daemon/client/components/Note.tsx +0 -14
- package/daemon/client/components/Priority.tsx +0 -19
- package/daemon/client/components/ResponseNote.tsx +0 -19
- package/daemon/client/components/Section.tsx +0 -33
- package/daemon/client/components/Table.tsx +0 -35
- package/daemon/client/components/Task.tsx +0 -76
- package/daemon/client/components/UserInput.tsx +0 -174
- package/daemon/client/components/renderMarkdownChildren.tsx +0 -97
- package/daemon/client/generateMarkdown.ts +0 -273
- package/daemon/client/highlightRange.ts +0 -224
- package/daemon/client/popoverPosition.ts +0 -31
- package/daemon/client/runtime.ts +0 -123
- package/daemon/client/theme.css +0 -66
- package/daemon/client/useTextAnnotation.tsx +0 -188
- package/daemon/client/utils.ts +0 -13
- package/daemon/src/compiler.test.ts +0 -57
- package/daemon/src/compiler.ts +0 -360
- package/daemon/src/handlers/utils.ts +0 -14
- package/daemon/src/router.ts +0 -16
- package/daemon/src/session-secrets.test.ts +0 -83
- package/daemon/src/session.ts +0 -612
- package/daemon/src/watcher.ts +0 -71
- package/daemon/src/websocket.test.ts +0 -99
- package/daemon/src/websocket.ts +0 -211
- package/tsconfig.json +0 -14
- package/workers/canvas-share/README.md +0 -159
- package/workers/canvas-share/oblaka.ts +0 -56
- package/workers/canvas-share/package.json +0 -25
- package/workers/canvas-share/public/assets/.gitkeep +0 -0
- package/workers/canvas-share/public/assets/client.css +0 -2
- package/workers/canvas-share/public/assets/client.js +0 -91
- package/workers/canvas-share/public/assets/components.js +0 -65
- package/workers/canvas-share/public/assets/jsx-runtime.js +0 -3
- package/workers/canvas-share/public/assets/preact-compat.js +0 -1
- package/workers/canvas-share/public/assets/runtime.js +0 -1
- package/workers/canvas-share/public/index.html +0 -385
- package/workers/canvas-share/public/screenshot-dark.png +0 -0
- package/workers/canvas-share/public/screenshot-light.png +0 -0
- package/workers/canvas-share/src/index.test.ts +0 -209
- package/workers/canvas-share/src/index.ts +0 -518
- package/workers/canvas-share/src/types.ts +0 -119
- package/workers/canvas-share/src/util.ts +0 -156
- package/workers/canvas-share/src/validation.ts +0 -160
- package/workers/canvas-share/tsconfig.json +0 -16
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useRef } from "react";
|
|
2
|
-
|
|
3
|
-
interface CodeBlockProps {
|
|
4
|
-
language?: string;
|
|
5
|
-
children?: React.ReactNode;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function CodeBlock({ language, children }: CodeBlockProps) {
|
|
9
|
-
const code = typeof children === "string" ? children : String(children ?? "");
|
|
10
|
-
const codeRef = useRef<HTMLElement>(null);
|
|
11
|
-
|
|
12
|
-
useEffect(() => {
|
|
13
|
-
const el = codeRef.current;
|
|
14
|
-
const hljs = (window as any).hljs;
|
|
15
|
-
if (!el || !hljs) return;
|
|
16
|
-
// Reset previous highlighting
|
|
17
|
-
el.removeAttribute("data-highlighted");
|
|
18
|
-
el.className = language ? `language-${language}` : "";
|
|
19
|
-
el.textContent = code;
|
|
20
|
-
hljs.highlightElement(el);
|
|
21
|
-
}, [code, language]);
|
|
22
|
-
|
|
23
|
-
return (
|
|
24
|
-
<div className="relative mt-3 group/code" data-md="codeblock" data-md-language={language || ""}>
|
|
25
|
-
{language && (
|
|
26
|
-
<span className="absolute top-2 right-3 text-tiny text-text-tertiary opacity-0 group-hover/code:opacity-60 transition-opacity duration-150 z-10 font-mono">
|
|
27
|
-
{language}
|
|
28
|
-
</span>
|
|
29
|
-
)}
|
|
30
|
-
<pre className="bg-bg-code rounded-md p-4 overflow-x-auto text-code font-mono leading-relaxed">
|
|
31
|
-
<code ref={codeRef} className={language ? `language-${language}` : ""}>{code}</code>
|
|
32
|
-
</pre>
|
|
33
|
-
</div>
|
|
34
|
-
);
|
|
35
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
|
|
3
|
-
interface DiffProps {
|
|
4
|
-
before: string;
|
|
5
|
-
after: string;
|
|
6
|
-
language?: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function Diff({ before, after, language }: DiffProps) {
|
|
10
|
-
const beforeLines = before.split("\n");
|
|
11
|
-
const afterLines = after.split("\n");
|
|
12
|
-
const lcs = computeLCS(beforeLines, afterLines);
|
|
13
|
-
const diffLines: Array<{ type: "same" | "removed" | "added"; line: string }> = [];
|
|
14
|
-
|
|
15
|
-
let bi = 0, ai = 0, li = 0;
|
|
16
|
-
while (bi < beforeLines.length || ai < afterLines.length) {
|
|
17
|
-
if (li < lcs.length && bi < beforeLines.length && ai < afterLines.length
|
|
18
|
-
&& beforeLines[bi] === lcs[li] && afterLines[ai] === lcs[li]) {
|
|
19
|
-
diffLines.push({ type: "same", line: beforeLines[bi] }); bi++; ai++; li++;
|
|
20
|
-
} else if (bi < beforeLines.length && (li >= lcs.length || beforeLines[bi] !== lcs[li])) {
|
|
21
|
-
diffLines.push({ type: "removed", line: beforeLines[bi] }); bi++;
|
|
22
|
-
} else if (ai < afterLines.length) {
|
|
23
|
-
diffLines.push({ type: "added", line: afterLines[ai] }); ai++;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<div className="mt-3 bg-bg-code rounded-md overflow-hidden group/diff" data-md="diff" data-md-language={language || ""}>
|
|
29
|
-
{language && (
|
|
30
|
-
<div className="px-4 py-2 text-meta font-mono text-text-tertiary opacity-0 group-hover/diff:opacity-60 transition-opacity">
|
|
31
|
-
diff ({language})
|
|
32
|
-
</div>
|
|
33
|
-
)}
|
|
34
|
-
<pre className="px-4 pb-3 overflow-x-auto text-code font-mono">
|
|
35
|
-
{diffLines.map((d, i) => (
|
|
36
|
-
<div key={i} className={
|
|
37
|
-
d.type === "removed" ? "bg-accent-red-muted text-accent-red" :
|
|
38
|
-
d.type === "added" ? "bg-accent-green-muted text-accent-green" :
|
|
39
|
-
"text-text-tertiary"
|
|
40
|
-
}>
|
|
41
|
-
<span className="select-none w-6 inline-block text-center opacity-60">
|
|
42
|
-
{d.type === "removed" ? "-" : d.type === "added" ? "+" : " "}
|
|
43
|
-
</span>
|
|
44
|
-
{d.line}
|
|
45
|
-
</div>
|
|
46
|
-
))}
|
|
47
|
-
</pre>
|
|
48
|
-
</div>
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function computeLCS(a: string[], b: string[]): string[] {
|
|
53
|
-
const m = a.length, n = b.length;
|
|
54
|
-
const dp: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
|
|
55
|
-
for (let i = 1; i <= m; i++)
|
|
56
|
-
for (let j = 1; j <= n; j++)
|
|
57
|
-
dp[i][j] = a[i-1] === b[j-1] ? dp[i-1][j-1]+1 : Math.max(dp[i-1][j], dp[i][j-1]);
|
|
58
|
-
const result: string[] = [];
|
|
59
|
-
let i = m, j = n;
|
|
60
|
-
while (i > 0 && j > 0) {
|
|
61
|
-
if (a[i-1] === b[j-1]) { result.unshift(a[i-1]); i--; j--; }
|
|
62
|
-
else if (dp[i-1][j] > dp[i][j-1]) i--; else j--;
|
|
63
|
-
}
|
|
64
|
-
return result;
|
|
65
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useState, useContext, useRef } from "react";
|
|
2
|
-
import { SessionContext, ActiveViewCtx } from "#canvas/runtime";
|
|
3
|
-
|
|
4
|
-
interface FilePreviewProps {
|
|
5
|
-
path: string;
|
|
6
|
-
lines?: [number, number];
|
|
7
|
-
/** Injected by compiler at build time — skip runtime fetch when present */
|
|
8
|
-
__content?: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const EXT_TO_LANG: Record<string, string> = {
|
|
12
|
-
ts: "typescript", tsx: "typescript", js: "javascript", jsx: "javascript",
|
|
13
|
-
py: "python", rs: "rust", go: "go", rb: "ruby", java: "java",
|
|
14
|
-
json: "json", yaml: "yaml", yml: "yaml", md: "markdown",
|
|
15
|
-
css: "css", html: "html", sh: "bash", bash: "bash", toml: "toml",
|
|
16
|
-
sql: "sql", xml: "xml", c: "c", cpp: "cpp", h: "c",
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export function FilePreview({ path, lines, __content }: FilePreviewProps) {
|
|
20
|
-
const sessionId = useContext(SessionContext);
|
|
21
|
-
const { setActiveView } = useContext(ActiveViewCtx);
|
|
22
|
-
const [content, setContent] = useState<string | null>(__content ?? null);
|
|
23
|
-
const [language, setLanguage] = useState(() => {
|
|
24
|
-
const ext = path.split(".").pop() || "";
|
|
25
|
-
return EXT_TO_LANG[ext] || "text";
|
|
26
|
-
});
|
|
27
|
-
const [error, setError] = useState<string | null>(null);
|
|
28
|
-
const [loading, setLoading] = useState(!__content);
|
|
29
|
-
const codeRef = useRef<HTMLElement>(null);
|
|
30
|
-
|
|
31
|
-
useEffect(() => {
|
|
32
|
-
if (__content !== undefined) return; // already resolved at compile time
|
|
33
|
-
setLoading(true);
|
|
34
|
-
setError(null);
|
|
35
|
-
fetch(`/api/file?session=${sessionId}&path=${encodeURIComponent(path)}`)
|
|
36
|
-
.then((r) => r.json())
|
|
37
|
-
.then((data: any) => {
|
|
38
|
-
if (data.error) {
|
|
39
|
-
setError(data.error);
|
|
40
|
-
} else {
|
|
41
|
-
let text = data.content;
|
|
42
|
-
if (lines) {
|
|
43
|
-
const allLines = text.split("\n");
|
|
44
|
-
text = allLines.slice(lines[0] - 1, lines[1]).join("\n");
|
|
45
|
-
}
|
|
46
|
-
setContent(text);
|
|
47
|
-
setLanguage(data.language || "text");
|
|
48
|
-
}
|
|
49
|
-
})
|
|
50
|
-
.catch(() => setError("Failed to fetch file"))
|
|
51
|
-
.finally(() => setLoading(false));
|
|
52
|
-
}, [sessionId, path, lines?.[0], lines?.[1], __content]);
|
|
53
|
-
|
|
54
|
-
// Highlight after content loads
|
|
55
|
-
useEffect(() => {
|
|
56
|
-
const el = codeRef.current;
|
|
57
|
-
const hljs = (window as any).hljs;
|
|
58
|
-
if (!el || !hljs || !content) return;
|
|
59
|
-
el.removeAttribute("data-highlighted");
|
|
60
|
-
el.className = language ? `language-${language}` : "";
|
|
61
|
-
el.textContent = content;
|
|
62
|
-
hljs.highlightElement(el);
|
|
63
|
-
}, [content, language]);
|
|
64
|
-
|
|
65
|
-
if (loading) {
|
|
66
|
-
return <div className="text-text-tertiary text-body mt-3 bg-bg-code rounded-md p-4">Loading {path}...</div>;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (error) {
|
|
70
|
-
return <div className="text-accent-red text-body mt-3 bg-accent-red-muted rounded-md p-4">{path}: {error}</div>;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return (
|
|
74
|
-
<div className="mt-3 bg-bg-code rounded-md overflow-hidden" data-md="filepreview" data-md-path={path} {...(lines ? { "data-md-lines": `${lines[0]}-${lines[1]}` } : {})}>
|
|
75
|
-
<div className="px-4 py-2 flex items-center justify-between">
|
|
76
|
-
<button
|
|
77
|
-
className="font-mono text-meta text-text-tertiary hover:text-text-secondary hover:underline cursor-pointer text-left"
|
|
78
|
-
onClick={() => setActiveView({ type: "file", path })}
|
|
79
|
-
title={`Open ${path}`}
|
|
80
|
-
>{path}</button>
|
|
81
|
-
{lines && <span className="font-mono text-meta text-text-tertiary opacity-60">L{lines[0]}–{lines[1]}</span>}
|
|
82
|
-
</div>
|
|
83
|
-
<pre className="px-4 pb-3 overflow-x-auto text-code font-mono !bg-transparent" style={{ background: "transparent" }}>
|
|
84
|
-
<code ref={codeRef} className={language ? `language-${language}` : ""}>{content}</code>
|
|
85
|
-
</pre>
|
|
86
|
-
</div>
|
|
87
|
-
);
|
|
88
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import React, { useContext, useState } from "react";
|
|
2
|
-
import { SessionContext } from "#canvas/runtime";
|
|
3
|
-
|
|
4
|
-
interface ImageProps {
|
|
5
|
-
src: string;
|
|
6
|
-
alt?: string;
|
|
7
|
-
caption?: string;
|
|
8
|
-
width?: number | string;
|
|
9
|
-
height?: number | string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function ImageView({ src, alt, caption, width, height }: ImageProps) {
|
|
13
|
-
const sessionId = useContext(SessionContext);
|
|
14
|
-
const [error, setError] = useState(false);
|
|
15
|
-
|
|
16
|
-
const imgSrc = `/api/image?session=${encodeURIComponent(sessionId)}&path=${encodeURIComponent(src)}`;
|
|
17
|
-
|
|
18
|
-
if (error) {
|
|
19
|
-
return (
|
|
20
|
-
<div className="mt-3 text-accent-red text-body bg-accent-red-muted rounded-md p-4">
|
|
21
|
-
{src}: Failed to load image
|
|
22
|
-
</div>
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<figure className="mt-3 relative" data-md="image" data-md-src={src}>
|
|
28
|
-
<div className="rounded-md overflow-hidden border border-border-subtle bg-bg-code inline-block">
|
|
29
|
-
<img
|
|
30
|
-
src={imgSrc}
|
|
31
|
-
alt={alt || src}
|
|
32
|
-
onError={() => setError(true)}
|
|
33
|
-
className="block max-w-full h-auto"
|
|
34
|
-
{...(width ? { width } : {})}
|
|
35
|
-
{...(height ? { height } : {})}
|
|
36
|
-
/>
|
|
37
|
-
</div>
|
|
38
|
-
{caption && (
|
|
39
|
-
<figcaption className="mt-1.5 text-meta text-text-tertiary font-body">
|
|
40
|
-
{caption}
|
|
41
|
-
</figcaption>
|
|
42
|
-
)}
|
|
43
|
-
</figure>
|
|
44
|
-
);
|
|
45
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import React, { useMemo } from "react";
|
|
2
|
-
import { marked } from "marked";
|
|
3
|
-
|
|
4
|
-
interface MarkdownProps {
|
|
5
|
-
/** Inline markdown source (via children) */
|
|
6
|
-
children?: React.ReactNode;
|
|
7
|
-
/** File path (resolved at compile time) */
|
|
8
|
-
file?: string;
|
|
9
|
-
/** Injected by compiler when file prop is used */
|
|
10
|
-
__content?: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// Configure marked for safe rendering
|
|
14
|
-
marked.setOptions({
|
|
15
|
-
gfm: true,
|
|
16
|
-
breaks: false,
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
export function Markdown({ children, file, __content }: MarkdownProps) {
|
|
20
|
-
const source = __content ?? (typeof children === "string" ? children : String(children ?? ""));
|
|
21
|
-
|
|
22
|
-
const html = useMemo(() => {
|
|
23
|
-
if (!source) return "";
|
|
24
|
-
return marked.parse(source, { async: false }) as string;
|
|
25
|
-
}, [source]);
|
|
26
|
-
|
|
27
|
-
if (!source) {
|
|
28
|
-
return (
|
|
29
|
-
<div className="text-text-tertiary text-tiny mt-3">
|
|
30
|
-
{file ? `Could not load: ${file}` : "No markdown content"}
|
|
31
|
-
</div>
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return (
|
|
36
|
-
<div
|
|
37
|
-
className="mt-3 prose-canvas"
|
|
38
|
-
data-md="markdown"
|
|
39
|
-
{...(file ? { "data-md-file": file } : {})}
|
|
40
|
-
data-md-source={source}
|
|
41
|
-
dangerouslySetInnerHTML={{ __html: html }}
|
|
42
|
-
/>
|
|
43
|
-
);
|
|
44
|
-
}
|