{
    "archive_path": "archive/1790460241.086592",
    "base_url": "tangled.org/yanndegat.tngl.sh/drawgent",
    "basename": "drawgent",
    "bookmarked_date": "2026-09-26 22:04",
    "canonical": {
        "archive_org_path": "https://web.archive.org/web/tangled.org/yanndegat.tngl.sh/drawgent",
        "dom_path": "output.html",
        "favicon_path": "favicon.ico",
        "git_path": "git/",
        "google_favicon_path": "https://www.google.com/s2/favicons?domain=tangled.org",
        "headers_path": "headers.json",
        "htmltotext_path": "htmltotext.txt",
        "index_path": "index.html",
        "media_path": "media/",
        "mercury_path": "mercury/content.html",
        "pdf_path": "output.pdf",
        "readability_path": "readability/content.html",
        "screenshot_path": "screenshot.png",
        "singlefile_path": "singlefile.html",
        "warc_path": "warc/",
        "wget_path": "tangled.org/yanndegat.tngl.sh/drawgent.html"
    },
    "domain": "tangled.org",
    "extension": "",
    "hash": "ZQ2RAVEX5X2NGJXH6AZN",
    "history": {
        "archive_org": [],
        "dom": [],
        "favicon": [
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--max-time",
                    "120",
                    "--output",
                    "favicon.ico",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://www.google.com/s2/favicons?domain=tangled.org"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-09-27T04:18:28.411567+00:00",
                "index_texts": null,
                "output": "favicon.ico",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-27T04:18:27.931342+00:00",
                "status": "succeeded"
            },
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--max-time",
                    "120",
                    "--output",
                    "favicon.ico",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://www.google.com/s2/favicons?domain=tangled.org"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-09-27T01:31:28.187393+00:00",
                "index_texts": null,
                "output": "favicon.ico",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-27T01:31:27.716002+00:00",
                "status": "succeeded"
            },
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--max-time",
                    "120",
                    "--output",
                    "favicon.ico",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://www.google.com/s2/favicons?domain=tangled.org"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-09-26T22:05:01.453328+00:00",
                "index_texts": null,
                "output": "favicon.ico",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-26T22:05:00.862818+00:00",
                "status": "succeeded"
            },
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--max-time",
                    "120",
                    "--output",
                    "favicon.ico",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://www.google.com/s2/favicons?domain=tangled.org"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-09-27T07:18:31.282070+00:00",
                "index_texts": null,
                "output": "favicon.ico",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-27T07:18:30.869830+00:00",
                "status": "succeeded"
            }
        ],
        "git": [],
        "headers": [
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--head",
                    "--max-time",
                    "120",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-09-27T04:18:29.867478+00:00",
                "index_texts": null,
                "output": "headers.json",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-27T04:18:28.417871+00:00",
                "status": "succeeded"
            },
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--head",
                    "--max-time",
                    "120",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-09-27T01:31:29.504924+00:00",
                "index_texts": null,
                "output": "headers.json",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-27T01:31:28.193992+00:00",
                "status": "succeeded"
            },
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--head",
                    "--max-time",
                    "120",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-09-26T22:05:02.820469+00:00",
                "index_texts": null,
                "output": "headers.json",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-26T22:05:01.462077+00:00",
                "status": "succeeded"
            },
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--head",
                    "--max-time",
                    "120",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-09-27T07:18:32.674196+00:00",
                "index_texts": null,
                "output": "headers.json",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-27T07:18:31.288091+00:00",
                "status": "succeeded"
            }
        ],
        "htmltotext": [],
        "media": [],
        "mercury": [
            {
                "cmd": [
                    "/app/node_modules/@postlight/parser/cli.js",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "1.0.0",
                "end_ts": "2026-09-27T04:18:41.217753+00:00",
                "index_texts": null,
                "output": "mercury",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-27T04:18:35.598089+00:00",
                "status": "succeeded"
            },
            {
                "cmd": [
                    "/app/node_modules/@postlight/parser/cli.js",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "1.0.0",
                "end_ts": "2026-09-27T01:31:41.496474+00:00",
                "index_texts": null,
                "output": "mercury",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-27T01:31:36.017604+00:00",
                "status": "succeeded"
            },
            {
                "cmd": [
                    "/app/node_modules/@postlight/parser/cli.js",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "1.0.0",
                "end_ts": "2026-09-26T22:05:13.199900+00:00",
                "index_texts": null,
                "output": "mercury",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-26T22:05:08.141306+00:00",
                "status": "succeeded"
            },
            {
                "cmd": [
                    "/app/node_modules/@postlight/parser/cli.js",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "1.0.0",
                "end_ts": "2026-09-27T07:18:47.247293+00:00",
                "index_texts": null,
                "output": "mercury",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-27T07:18:42.619006+00:00",
                "status": "succeeded"
            }
        ],
        "pdf": [],
        "readability": [
            {
                "cmd": [
                    "/app/node_modules/readability-extractor/readability-extractor",
                    "/tmp/tmpqj5v4cdc",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "0.0.11",
                "end_ts": "2026-09-27T04:18:35.586010+00:00",
                "index_texts": [
                    "7\n            \n        \n    \n\n      \n    \n  \n\n    \n      Configure Feed\n    \n\n    \n        \n        Issues\n      \n\n      \n        \n        Pull Requests\n      \n\n      \n        \n        Commits\n      \n\n      \n        \n        Tags\n      \n    \n\n    \n    \n\n    \n      Select the types of activity you want to include in your feed.\n    \n  \n\n  \n\n  \n      \n  This repository has no description\n    \n\n    \n\n    \n  \n\n\n      \n    \n    \n    \n        \n            \n            \n                7\n            \n        \n    \n\n      \n    \n  \n\n    \n      Configure Feed\n    \n\n    \n        \n        Issues\n      \n\n      \n        \n        Pull Requests\n      \n\n      \n        \n        Commits\n      \n\n      \n        \n        Tags\n      \n    \n\n    \n    \n\n    \n      Select the types of activity you want to include in your feed.\n    \n  \n\n  \n\n  \n    \n\n    \n        \n            \n        \n        \n          \n            \n    \n        \n            \n    \n      \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n      \n      \n    \n\n        \n        \n            \n              \n  \n  \n  \n\n 3\n            \n            \n              \n  \n  \n  \n  \n\n 1\n            \n            \n              \n  \n  \n  \n\n 0\n            \n            \n  \n  \n      \n  \n\n  \n\n  \n\n    \n      Clone this repository\n      \n        \n  \n  \n\n\n        \n  \n\n\n        Use permalink\n      \n    \n\n    \n\n    \n  \n    HTTPShttps://tangled.org/yanndegat.tngl.sh/drawgent\n      https://tangled.org/did:plc:3zklierfkckthy6sodbm4af3\n      \n    \n  \n\n\n    \n  \n    SSHgit@tangled.org:yanndegat.tngl.sh/drawgent\n      git@tangled.org:did:plc:3zklierfkckthy6sodbm4af3\n      \n    \n  \n\n\n    \n      For self-hosted knots, clone URLs may differ based on your setup.\n    \n\n    \n\n    \n      \n        \n  \n  \n  \n\n\n        Download tar.gz\n      \n      \n        \n  \n  \n  \n\n\n        Download .zip\n      \n    \n  \n\n  \n\n  \n\n          \n        \n  \n    \n      \n  \n  \n  \n  \n  \n  \n  \n  \n  \n\n Commits\n      3\n    \n  \n  \n    \n    \n                The editor records Excalidraw laser gestures (onPointerUpdate) and keepsthem as a locked red freedraw trace tagged customData.drawgentZone. Thechat panel opens focused with a chip listing the covered elements; thenext message is sent with the zone, and the server adds the zone boundsand covered elements (most covered first) to the prompt. The trace isremoved when that turn ends (managed sessions) or when a live attachedsession goes idle again. get_scene reports traces as type \"zone\".Adds scripts/laser-e2e.mjs.Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>\n    \n    \n                Server logs each WebSocket request and connection; the editor logstimed [drawgent +Nms] lines in the browser console (page script,connecting/open/closed, init received) and shows an orange\"connecting\" dot in the chat panel.Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>\n    \n    \n                A single Rust binary that serves an Excalidraw editor, keeps the scene,and connects the user's own Claude Code, Codex or opencode to it.- setup <agent>: checks the installed CLI and login, prepares the ACP  bridge (adapters driving the user's own binary), finds or installs a  headless Chrome, and writes ~/.config/drawgent/config.toml- up: new agent session in the current workspace; up --attach [id]  lists running sessions (Claude fork over ACP, live opencode via its  HTTP API, live Codex via `codex queue`)- chat panel, AGENT: canvas notes, MCP canvas tools with vision  (headless Chrome renderer), excalidraw.com room client (AES-GCM,  socket.io, Firestore)- Makefile with static musl builds, Nix dev shell (fish), optional  server-only Docker imageCo-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>\n    \n  \n  \n\n    \n\n          \n          \n\n        \n  \n  \n  \n  \n  \n\n\n        README.md\n      \n    \n        \ndrawgent connects your own Claude Code, Codex or opencode (your install, login, config and\nrepo) to an Excalidraw whiteboard. Ask for a diagram in the chat panel, or write AGENT: \u2026\nnext to the part of a drawing you want changed. The agent looks at the canvas (screenshot +\nscene), edits it live, checks the result, and marks the note DONE.\nQuick start#\nPrerequisite: one of claude, codex or opencode installed and logged in. The Claude and\nCodex bridges also need Node.js \u2265 18 (npm).\ndrawgent setup claude        # once per agent: claude | codex | opencode\ncd ~/my-repo\ndrawgent up                  # new agent session in this repo + canvas in your browser\ndrawgent up --attach         # or: pick one of your running sessions and connect the canvas to it\ndrawgent setup <agent>#\nChecks everything once, fails with the exact fix when something is missing, and writes\n~/.config/drawgent/config.toml:\n\n\nThe agent CLI. Your claude / codex / opencode on PATH.\n\n\nLogin. claude auth status, codex login status or opencode auth list.\n\n\nACP bridge.\n\nopencode speaks ACP itself (opencode acp).\nClaude Code and Codex use the official ACP adapters. They are installed once into\n~/.cache/drawgent/adapters (~60 MB), without their bundled agent binaries, and pointed\nat your CLI (CLAUDE_CODE_EXECUTABLE, CODEX_PATH).\nSetup then verifies the ACP handshake.\n\n\n\nCanvas tools for attached sessions. Only Codex needs a change:\ncodex mcp add drawgent -- drawgent mcp. Claude and opencode get the tools at attach time.\n\n\nHeadless Chrome for the renderer. Setup uses your Chrome/Chromium if you have one.\nOtherwise it proposes:\n\ndownloading Chrome Headless Shell (Chrome for Testing, ~120 MB, no sudo) into\n~/.cache/drawgent/chrome, and telling you exactly which system libraries are missing, if\nany;\ninstalling Chromium with your package manager (apt, snap, dnf, pacman, zypper,\napk, brew, or nix without sudo).\n\nNon-interactive: --chrome download | system | /path/to/chrome.\n\n\ndrawgent up refuses to start until setup succeeded for that agent, or if something setup\nrecorded disappeared.\ndrawgent up#\nRuns in the current directory (the workspace):\n\nstarts the editor + API on 127.0.0.1:7300 (next free port if taken);\nstarts a new session of your agent over ACP, working in the workspace;\nopens your browser. On a headless box it prints the ssh -L command instead.\n\nThe scene is kept in .drawgent/scene.json, which is git-ignored automatically.\ndrawgent up --attach [id]#\nConnects the canvas to a session you already run. Without an id it lists the sessions it\nfinds (current directory first) and lets you pick one:\n\n\n\nagent\ndiscovery\nhow the canvas reaches it\n\n\n\n\nClaude Code\nclaude agents --json (interactive and background sessions)\nfork: a new session carrying the full conversation, driven by drawgent over ACP. Your terminal session is left untouched\n\n\nopencode\nopencode servers listening locally: start the TUI with opencode --port 4096 (or opencode serve)\nlive: messages go into your running session (you see them in your TUI); drawgent adds its MCP tools to that server at runtime; replies, tool calls and prompts you type in the TUI are mirrored into the chat panel\n\n\nCodex\nsessions in ~/.codex/sessions\nlive: codex queue --thread <id>; replies are mirrored from the session's rollout file. The session needs the drawgent MCP (registered by setup, loaded when Codex starts)\n\n\n\nUsing the canvas#\n\nChat panel (right side): send a request, watch replies and tool calls stream in, approve\npermission prompts, press Stop to cancel a turn.\nOn the canvas: write a text starting with AGENT: next to or inside a shape, or draw an\narrow from the note to a shape. It fires about 2.5 s after you stop typing, with its\nposition, what it points at and what is nearby. The agent resolves it into a green\nDONE: \u2026 note. Edit it back to AGENT: to send it again.\nLaser zones: pick Excalidraw's laser (K) and circle or scribble over part of the diagram.\nThe trace stays on the canvas as a red outline, and the chat panel opens ready for your\ninstruction, with a chip listing what is under the zone (\ud83d\udd34 Laser zone \u00b7 API, Redis \u00d7). Your\nnext message goes to the agent together with the zone (bounds and covered elements), and the\ntrace disappears when the agent is done. Strokes within 4 s of each other form one zone; \u00d7\ndiscards it.\nPrompts are queued and run one at a time. A queued note that was already handled is skipped.\n\nexcalidraw.com rooms#\ndrawgent up --room 'https://excalidraw.com/#room=<id>,<key>'\n\ndrawgent joins the room as a collaborator (\ud83e\udd16 Agent, with a cursor that follows its edits).\nHumans can stay on excalidraw.com: their AGENT: notes reach your agent, and its edits\nappear there live.\nTraffic is end-to-end encrypted with the room key. Empty rooms are loaded from and saved to\nexcalidraw's Firestore storage.\nThe local editor mirrors the room and still has the chat panel.\n\nOther commands#\n\ndrawgent mcp: stdio MCP server with the canvas tools. Agents launch it; it finds the running\ndrawgent up by itself.\ndrawgent serve: low-level server with explicit agents (--agent claude,codex,opencode as set up,\nor name=command for any ACP agent); for scripts and containers.\nOptions for up / serve: --port, --room, --token (API bearer + ?token= in the URL),\n--permissions canvas|ask|all (default canvas: drawing tools auto-approved, anything else\nasked in the chat panel), --data, --settle-ms.\n\nOptional: Docker#\ndocker compose up --build runs a canvas server (drawgent + Chromium, no agents), e.g. to\nhost a shared canvas or a room bridge on a server. Agents are never bundled: they always run\nwith your own setup.\nBuild from source#\nnpm ci && npm run build      # editor + renderer pages -> dist/ (embedded into the binary)\ncargo install --path .       # or: cargo build --release\nAgent tools (MCP)#\nget_scene, get_screenshot (vision; zoom with element_ids), add_elements (Excalidraw\nskeletons; arrows bind by id and are routed edge-to-edge), add_mermaid (auto-layout),\nupdate_elements (labels follow shapes, bound arrows re-route), delete_elements,\nclear_canvas, list_instructions, resolve_instruction, set_status.\nAPI#\nGET /api/health \u00b7 GET /api/scene \u00b7 GET /api/screenshot?ids=&padding=&max= \u00b7\nPOST|PATCH|DELETE /api/elements \u00b7 POST /api/mermaid \u00b7 POST /api/clear \u00b7\nGET /api/instructions \u00b7 POST /api/instructions/{id}/resolve \u00b7 POST /api/status \u00b7\nPOST /api/chat {agent?, text} \u00b7 WS /ws (browser sync + chat events)\nTests#\ncargo test                          # fractional indices, room crypto/framing\nnode scripts/smoke.mjs [url]        # chat turn + AGENT: note against a running drawgent\nnode scripts/e2e-browser.mjs [url]  # real browser: chat panel + note typed on the canvas\nnode scripts/room-e2e.mjs           # fresh excalidraw.com room \u2194 drawgent, both directions\nnode scripts/laser-e2e.mjs          # laser zone \u2192 chat \u2192 agent edits only that zone (needs setup claude)\nLayout#\nsrc/ (Rust):\n\nmain.rs: CLI.\nsetup.rs, config.rs, chrome.rs: setup, config, renderer install.\nattach.rs: session discovery and picker.\nagents.rs + acp.rs: ACP driver (new / fork sessions).\nlive.rs: live opencode / Codex drivers.\nhub.rs: routing, notes, chat log.\nscene.rs: store and edit operations.\nrenderer.rs: Chrome over CDP.\nmcp.rs: MCP server.\nroom.rs: excalidraw.com client.\nfractional.rs, geometry.rs, el.rs: helpers.\n\nweb/: editor (main.jsx, chat.jsx, laser.js) and renderer page (render.jsx).\nLimits#\n\nThe renderer needs Chrome (a native renderer is planned).\nClaude \"attach\" is a fork, because Claude Code has no public way to inject into a running\nterminal session.\nCodex live attach is implemented, but was not yet tested against a logged-in Codex.\nOne scene per workspace. Images/files are not synced."
                ],
                "output": "readability",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-27T04:18:32.526500+00:00",
                "status": "succeeded"
            },
            {
                "cmd": [
                    "/app/node_modules/readability-extractor/readability-extractor",
                    "/tmp/tmp5is5kp52",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "0.0.11",
                "end_ts": "2026-09-27T01:31:36.004053+00:00",
                "index_texts": [
                    "7\n            \n        \n    \n\n      \n    \n  \n\n    \n      Configure Feed\n    \n\n    \n        \n        Issues\n      \n\n      \n        \n        Pull Requests\n      \n\n      \n        \n        Commits\n      \n\n      \n        \n        Tags\n      \n    \n\n    \n    \n\n    \n      Select the types of activity you want to include in your feed.\n    \n  \n\n  \n\n  \n      \n  This repository has no description\n    \n\n    \n\n    \n  \n\n\n      \n    \n    \n    \n        \n            \n            \n                7\n            \n        \n    \n\n      \n    \n  \n\n    \n      Configure Feed\n    \n\n    \n        \n        Issues\n      \n\n      \n        \n        Pull Requests\n      \n\n      \n        \n        Commits\n      \n\n      \n        \n        Tags\n      \n    \n\n    \n    \n\n    \n      Select the types of activity you want to include in your feed.\n    \n  \n\n  \n\n  \n    \n\n    \n        \n            \n        \n        \n          \n            \n    \n        \n            \n    \n      \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n      \n      \n    \n\n        \n        \n            \n              \n  \n  \n  \n\n 3\n            \n            \n              \n  \n  \n  \n  \n\n 1\n            \n            \n              \n  \n  \n  \n\n 0\n            \n            \n  \n  \n      \n  \n\n  \n\n  \n\n    \n      Clone this repository\n      \n        \n  \n  \n\n\n        \n  \n\n\n        Use permalink\n      \n    \n\n    \n\n    \n  \n    HTTPShttps://tangled.org/yanndegat.tngl.sh/drawgent\n      https://tangled.org/did:plc:3zklierfkckthy6sodbm4af3\n      \n    \n  \n\n\n    \n  \n    SSHgit@tangled.org:yanndegat.tngl.sh/drawgent\n      git@tangled.org:did:plc:3zklierfkckthy6sodbm4af3\n      \n    \n  \n\n\n    \n      For self-hosted knots, clone URLs may differ based on your setup.\n    \n\n    \n\n    \n      \n        \n  \n  \n  \n\n\n        Download tar.gz\n      \n      \n        \n  \n  \n  \n\n\n        Download .zip\n      \n    \n  \n\n  \n\n  \n\n          \n        \n  \n    \n      \n  \n  \n  \n  \n  \n  \n  \n  \n  \n\n Commits\n      3\n    \n  \n  \n    \n    \n                The editor records Excalidraw laser gestures (onPointerUpdate) and keepsthem as a locked red freedraw trace tagged customData.drawgentZone. Thechat panel opens focused with a chip listing the covered elements; thenext message is sent with the zone, and the server adds the zone boundsand covered elements (most covered first) to the prompt. The trace isremoved when that turn ends (managed sessions) or when a live attachedsession goes idle again. get_scene reports traces as type \"zone\".Adds scripts/laser-e2e.mjs.Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>\n    \n    \n                Server logs each WebSocket request and connection; the editor logstimed [drawgent +Nms] lines in the browser console (page script,connecting/open/closed, init received) and shows an orange\"connecting\" dot in the chat panel.Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>\n    \n    \n                A single Rust binary that serves an Excalidraw editor, keeps the scene,and connects the user's own Claude Code, Codex or opencode to it.- setup <agent>: checks the installed CLI and login, prepares the ACP  bridge (adapters driving the user's own binary), finds or installs a  headless Chrome, and writes ~/.config/drawgent/config.toml- up: new agent session in the current workspace; up --attach [id]  lists running sessions (Claude fork over ACP, live opencode via its  HTTP API, live Codex via `codex queue`)- chat panel, AGENT: canvas notes, MCP canvas tools with vision  (headless Chrome renderer), excalidraw.com room client (AES-GCM,  socket.io, Firestore)- Makefile with static musl builds, Nix dev shell (fish), optional  server-only Docker imageCo-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>\n    \n  \n  \n\n    \n\n          \n          \n\n        \n  \n  \n  \n  \n  \n\n\n        README.md\n      \n    \n        \ndrawgent connects your own Claude Code, Codex or opencode (your install, login, config and\nrepo) to an Excalidraw whiteboard. Ask for a diagram in the chat panel, or write AGENT: \u2026\nnext to the part of a drawing you want changed. The agent looks at the canvas (screenshot +\nscene), edits it live, checks the result, and marks the note DONE.\nQuick start#\nPrerequisite: one of claude, codex or opencode installed and logged in. The Claude and\nCodex bridges also need Node.js \u2265 18 (npm).\ndrawgent setup claude        # once per agent: claude | codex | opencode\ncd ~/my-repo\ndrawgent up                  # new agent session in this repo + canvas in your browser\ndrawgent up --attach         # or: pick one of your running sessions and connect the canvas to it\ndrawgent setup <agent>#\nChecks everything once, fails with the exact fix when something is missing, and writes\n~/.config/drawgent/config.toml:\n\n\nThe agent CLI. Your claude / codex / opencode on PATH.\n\n\nLogin. claude auth status, codex login status or opencode auth list.\n\n\nACP bridge.\n\nopencode speaks ACP itself (opencode acp).\nClaude Code and Codex use the official ACP adapters. They are installed once into\n~/.cache/drawgent/adapters (~60 MB), without their bundled agent binaries, and pointed\nat your CLI (CLAUDE_CODE_EXECUTABLE, CODEX_PATH).\nSetup then verifies the ACP handshake.\n\n\n\nCanvas tools for attached sessions. Only Codex needs a change:\ncodex mcp add drawgent -- drawgent mcp. Claude and opencode get the tools at attach time.\n\n\nHeadless Chrome for the renderer. Setup uses your Chrome/Chromium if you have one.\nOtherwise it proposes:\n\ndownloading Chrome Headless Shell (Chrome for Testing, ~120 MB, no sudo) into\n~/.cache/drawgent/chrome, and telling you exactly which system libraries are missing, if\nany;\ninstalling Chromium with your package manager (apt, snap, dnf, pacman, zypper,\napk, brew, or nix without sudo).\n\nNon-interactive: --chrome download | system | /path/to/chrome.\n\n\ndrawgent up refuses to start until setup succeeded for that agent, or if something setup\nrecorded disappeared.\ndrawgent up#\nRuns in the current directory (the workspace):\n\nstarts the editor + API on 127.0.0.1:7300 (next free port if taken);\nstarts a new session of your agent over ACP, working in the workspace;\nopens your browser. On a headless box it prints the ssh -L command instead.\n\nThe scene is kept in .drawgent/scene.json, which is git-ignored automatically.\ndrawgent up --attach [id]#\nConnects the canvas to a session you already run. Without an id it lists the sessions it\nfinds (current directory first) and lets you pick one:\n\n\n\nagent\ndiscovery\nhow the canvas reaches it\n\n\n\n\nClaude Code\nclaude agents --json (interactive and background sessions)\nfork: a new session carrying the full conversation, driven by drawgent over ACP. Your terminal session is left untouched\n\n\nopencode\nopencode servers listening locally: start the TUI with opencode --port 4096 (or opencode serve)\nlive: messages go into your running session (you see them in your TUI); drawgent adds its MCP tools to that server at runtime; replies, tool calls and prompts you type in the TUI are mirrored into the chat panel\n\n\nCodex\nsessions in ~/.codex/sessions\nlive: codex queue --thread <id>; replies are mirrored from the session's rollout file. The session needs the drawgent MCP (registered by setup, loaded when Codex starts)\n\n\n\nUsing the canvas#\n\nChat panel (right side): send a request, watch replies and tool calls stream in, approve\npermission prompts, press Stop to cancel a turn.\nOn the canvas: write a text starting with AGENT: next to or inside a shape, or draw an\narrow from the note to a shape. It fires about 2.5 s after you stop typing, with its\nposition, what it points at and what is nearby. The agent resolves it into a green\nDONE: \u2026 note. Edit it back to AGENT: to send it again.\nLaser zones: pick Excalidraw's laser (K) and circle or scribble over part of the diagram.\nThe trace stays on the canvas as a red outline, and the chat panel opens ready for your\ninstruction, with a chip listing what is under the zone (\ud83d\udd34 Laser zone \u00b7 API, Redis \u00d7). Your\nnext message goes to the agent together with the zone (bounds and covered elements), and the\ntrace disappears when the agent is done. Strokes within 4 s of each other form one zone; \u00d7\ndiscards it.\nPrompts are queued and run one at a time. A queued note that was already handled is skipped.\n\nexcalidraw.com rooms#\ndrawgent up --room 'https://excalidraw.com/#room=<id>,<key>'\n\ndrawgent joins the room as a collaborator (\ud83e\udd16 Agent, with a cursor that follows its edits).\nHumans can stay on excalidraw.com: their AGENT: notes reach your agent, and its edits\nappear there live.\nTraffic is end-to-end encrypted with the room key. Empty rooms are loaded from and saved to\nexcalidraw's Firestore storage.\nThe local editor mirrors the room and still has the chat panel.\n\nOther commands#\n\ndrawgent mcp: stdio MCP server with the canvas tools. Agents launch it; it finds the running\ndrawgent up by itself.\ndrawgent serve: low-level server with explicit agents (--agent claude,codex,opencode as set up,\nor name=command for any ACP agent); for scripts and containers.\nOptions for up / serve: --port, --room, --token (API bearer + ?token= in the URL),\n--permissions canvas|ask|all (default canvas: drawing tools auto-approved, anything else\nasked in the chat panel), --data, --settle-ms.\n\nOptional: Docker#\ndocker compose up --build runs a canvas server (drawgent + Chromium, no agents), e.g. to\nhost a shared canvas or a room bridge on a server. Agents are never bundled: they always run\nwith your own setup.\nBuild from source#\nnpm ci && npm run build      # editor + renderer pages -> dist/ (embedded into the binary)\ncargo install --path .       # or: cargo build --release\nAgent tools (MCP)#\nget_scene, get_screenshot (vision; zoom with element_ids), add_elements (Excalidraw\nskeletons; arrows bind by id and are routed edge-to-edge), add_mermaid (auto-layout),\nupdate_elements (labels follow shapes, bound arrows re-route), delete_elements,\nclear_canvas, list_instructions, resolve_instruction, set_status.\nAPI#\nGET /api/health \u00b7 GET /api/scene \u00b7 GET /api/screenshot?ids=&padding=&max= \u00b7\nPOST|PATCH|DELETE /api/elements \u00b7 POST /api/mermaid \u00b7 POST /api/clear \u00b7\nGET /api/instructions \u00b7 POST /api/instructions/{id}/resolve \u00b7 POST /api/status \u00b7\nPOST /api/chat {agent?, text} \u00b7 WS /ws (browser sync + chat events)\nTests#\ncargo test                          # fractional indices, room crypto/framing\nnode scripts/smoke.mjs [url]        # chat turn + AGENT: note against a running drawgent\nnode scripts/e2e-browser.mjs [url]  # real browser: chat panel + note typed on the canvas\nnode scripts/room-e2e.mjs           # fresh excalidraw.com room \u2194 drawgent, both directions\nnode scripts/laser-e2e.mjs          # laser zone \u2192 chat \u2192 agent edits only that zone (needs setup claude)\nLayout#\nsrc/ (Rust):\n\nmain.rs: CLI.\nsetup.rs, config.rs, chrome.rs: setup, config, renderer install.\nattach.rs: session discovery and picker.\nagents.rs + acp.rs: ACP driver (new / fork sessions).\nlive.rs: live opencode / Codex drivers.\nhub.rs: routing, notes, chat log.\nscene.rs: store and edit operations.\nrenderer.rs: Chrome over CDP.\nmcp.rs: MCP server.\nroom.rs: excalidraw.com client.\nfractional.rs, geometry.rs, el.rs: helpers.\n\nweb/: editor (main.jsx, chat.jsx, laser.js) and renderer page (render.jsx).\nLimits#\n\nThe renderer needs Chrome (a native renderer is planned).\nClaude \"attach\" is a fork, because Claude Code has no public way to inject into a running\nterminal session.\nCodex live attach is implemented, but was not yet tested against a logged-in Codex.\nOne scene per workspace. Images/files are not synced."
                ],
                "output": "readability",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-27T01:31:31.979023+00:00",
                "status": "succeeded"
            },
            {
                "cmd": [
                    "/app/node_modules/readability-extractor/readability-extractor",
                    "/tmp/tmptprv77fl",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "0.0.11",
                "end_ts": "2026-09-26T22:05:08.132583+00:00",
                "index_texts": [
                    "6\n            \n        \n    \n\n      \n    \n  \n\n    \n      Configure Feed\n    \n\n    \n        \n        Issues\n      \n\n      \n        \n        Pull Requests\n      \n\n      \n        \n        Commits\n      \n\n      \n        \n        Tags\n      \n    \n\n    \n    \n\n    \n      Select the types of activity you want to include in your feed.\n    \n  \n\n  \n\n  \n      \n  This repository has no description\n    \n\n    \n\n    \n  \n\n\n      \n    \n    \n    \n        \n            \n            \n                6\n            \n        \n    \n\n      \n    \n  \n\n    \n      Configure Feed\n    \n\n    \n        \n        Issues\n      \n\n      \n        \n        Pull Requests\n      \n\n      \n        \n        Commits\n      \n\n      \n        \n        Tags\n      \n    \n\n    \n    \n\n    \n      Select the types of activity you want to include in your feed.\n    \n  \n\n  \n\n  \n    \n\n    \n        \n            \n        \n        \n          \n            \n    \n        \n            \n    \n      \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n      \n      \n    \n\n        \n        \n            \n              \n  \n  \n  \n\n 1\n            \n            \n              \n  \n  \n  \n  \n\n 1\n            \n            \n              \n  \n  \n  \n\n 0\n            \n            \n  \n  \n      \n  \n\n  \n\n  \n\n    \n      Clone this repository\n      \n        \n  \n  \n\n\n        \n  \n\n\n        Use permalink\n      \n    \n\n    \n\n    \n  \n    HTTPShttps://tangled.org/yanndegat.tngl.sh/drawgent\n      https://tangled.org/did:plc:3zklierfkckthy6sodbm4af3\n      \n    \n  \n\n\n    \n  \n    SSHgit@tangled.org:yanndegat.tngl.sh/drawgent\n      git@tangled.org:did:plc:3zklierfkckthy6sodbm4af3\n      \n    \n  \n\n\n    \n      For self-hosted knots, clone URLs may differ based on your setup.\n    \n\n    \n\n    \n      \n        \n  \n  \n  \n\n\n        Download tar.gz\n      \n      \n        \n  \n  \n  \n\n\n        Download .zip\n      \n    \n  \n\n  \n\n  \n\n          \n        \n  \n    \n      \n  \n  \n  \n  \n  \n  \n  \n  \n  \n\n Commits\n      1\n    \n  \n  \n                A single Rust binary that serves an Excalidraw editor, keeps the scene,and connects the user's own Claude Code, Codex or opencode to it.- setup <agent>: checks the installed CLI and login, prepares the ACP  bridge (adapters driving the user's own binary), finds or installs a  headless Chrome, and writes ~/.config/drawgent/config.toml- up: new agent session in the current workspace; up --attach [id]  lists running sessions (Claude fork over ACP, live opencode via its  HTTP API, live Codex via `codex queue`)- chat panel, AGENT: canvas notes, MCP canvas tools with vision  (headless Chrome renderer), excalidraw.com room client (AES-GCM,  socket.io, Firestore)- Makefile with static musl builds, Nix dev shell (fish), optional  server-only Docker imageCo-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>\n  \n\n    \n\n          \n          \n\n        \n  \n  \n  \n  \n  \n\n\n        README.md\n      \n    \n        \ndrawgent connects your own Claude Code, Codex or opencode (your install, login, config and\nrepo) to an Excalidraw whiteboard. Ask for a diagram in the chat panel, or write AGENT: \u2026\nnext to the part of a drawing you want changed. The agent looks at the canvas (screenshot +\nscene), edits it live, checks the result, and marks the note DONE.\nQuick start#\nPrerequisite: one of claude, codex or opencode installed and logged in. The Claude and\nCodex bridges also need Node.js \u2265 18 (npm).\ndrawgent setup claude        # once per agent: claude | codex | opencode\ncd ~/my-repo\ndrawgent up                  # new agent session in this repo + canvas in your browser\ndrawgent up --attach         # or: pick one of your running sessions and connect the canvas to it\ndrawgent setup <agent>#\nChecks everything once, fails with the exact fix when something is missing, and writes\n~/.config/drawgent/config.toml:\n\n\nThe agent CLI. Your claude / codex / opencode on PATH.\n\n\nLogin. claude auth status, codex login status or opencode auth list.\n\n\nACP bridge.\n\nopencode speaks ACP itself (opencode acp).\nClaude Code and Codex use the official ACP adapters. They are installed once into\n~/.cache/drawgent/adapters (~60 MB), without their bundled agent binaries, and pointed\nat your CLI (CLAUDE_CODE_EXECUTABLE, CODEX_PATH).\nSetup then verifies the ACP handshake.\n\n\n\nCanvas tools for attached sessions. Only Codex needs a change:\ncodex mcp add drawgent -- drawgent mcp. Claude and opencode get the tools at attach time.\n\n\nHeadless Chrome for the renderer. Setup uses your Chrome/Chromium if you have one.\nOtherwise it proposes:\n\ndownloading Chrome Headless Shell (Chrome for Testing, ~120 MB, no sudo) into\n~/.cache/drawgent/chrome, and telling you exactly which system libraries are missing, if\nany;\ninstalling Chromium with your package manager (apt, snap, dnf, pacman, zypper,\napk, brew, or nix without sudo).\n\nNon-interactive: --chrome download | system | /path/to/chrome.\n\n\ndrawgent up refuses to start until setup succeeded for that agent, or if something setup\nrecorded disappeared.\ndrawgent up#\nRuns in the current directory (the workspace):\n\nstarts the editor + API on 127.0.0.1:7300 (next free port if taken);\nstarts a new session of your agent over ACP, working in the workspace;\nopens your browser. On a headless box it prints the ssh -L command instead.\n\nThe scene is kept in .drawgent/scene.json, which is git-ignored automatically.\ndrawgent up --attach [id]#\nConnects the canvas to a session you already run. Without an id it lists the sessions it\nfinds (current directory first) and lets you pick one:\n\n\n\nagent\ndiscovery\nhow the canvas reaches it\n\n\n\n\nClaude Code\nclaude agents --json (interactive and background sessions)\nfork: a new session carrying the full conversation, driven by drawgent over ACP. Your terminal session is left untouched\n\n\nopencode\nopencode servers listening locally: start the TUI with opencode --port 4096 (or opencode serve)\nlive: messages go into your running session (you see them in your TUI); drawgent adds its MCP tools to that server at runtime; replies, tool calls and prompts you type in the TUI are mirrored into the chat panel\n\n\nCodex\nsessions in ~/.codex/sessions\nlive: codex queue --thread <id>; replies are mirrored from the session's rollout file. The session needs the drawgent MCP (registered by setup, loaded when Codex starts)\n\n\n\nUsing the canvas#\n\nChat panel (right side): send a request, watch replies and tool calls stream in, approve\npermission prompts, press Stop to cancel a turn.\nOn the canvas: write a text starting with AGENT: next to or inside a shape, or draw an\narrow from the note to a shape. It fires about 2.5 s after you stop typing, with its\nposition, what it points at and what is nearby. The agent resolves it into a green\nDONE: \u2026 note. Edit it back to AGENT: to send it again.\nPrompts are queued and run one at a time. A queued note that was already handled is skipped.\n\nexcalidraw.com rooms#\ndrawgent up --room 'https://excalidraw.com/#room=<id>,<key>'\n\ndrawgent joins the room as a collaborator (\ud83e\udd16 Agent, with a cursor that follows its edits).\nHumans can stay on excalidraw.com: their AGENT: notes reach your agent, and its edits\nappear there live.\nTraffic is end-to-end encrypted with the room key. Empty rooms are loaded from and saved to\nexcalidraw's Firestore storage.\nThe local editor mirrors the room and still has the chat panel.\n\nOther commands#\n\ndrawgent mcp: stdio MCP server with the canvas tools. Agents launch it; it finds the running\ndrawgent up by itself.\ndrawgent serve: low-level server with explicit agents (--agent claude,codex,opencode as set up,\nor name=command for any ACP agent); for scripts and containers.\nOptions for up / serve: --port, --room, --token (API bearer + ?token= in the URL),\n--permissions canvas|ask|all (default canvas: drawing tools auto-approved, anything else\nasked in the chat panel), --data, --settle-ms.\n\nOptional: Docker#\ndocker compose up --build runs a canvas server (drawgent + Chromium, no agents), e.g. to\nhost a shared canvas or a room bridge on a server. Agents are never bundled: they always run\nwith your own setup.\nBuild from source#\nnpm ci && npm run build      # editor + renderer pages -> dist/ (embedded into the binary)\ncargo install --path .       # or: cargo build --release\nAgent tools (MCP)#\nget_scene, get_screenshot (vision; zoom with element_ids), add_elements (Excalidraw\nskeletons; arrows bind by id and are routed edge-to-edge), add_mermaid (auto-layout),\nupdate_elements (labels follow shapes, bound arrows re-route), delete_elements,\nclear_canvas, list_instructions, resolve_instruction, set_status.\nAPI#\nGET /api/health \u00b7 GET /api/scene \u00b7 GET /api/screenshot?ids=&padding=&max= \u00b7\nPOST|PATCH|DELETE /api/elements \u00b7 POST /api/mermaid \u00b7 POST /api/clear \u00b7\nGET /api/instructions \u00b7 POST /api/instructions/{id}/resolve \u00b7 POST /api/status \u00b7\nPOST /api/chat {agent?, text} \u00b7 WS /ws (browser sync + chat events)\nTests#\ncargo test                          # fractional indices, room crypto/framing\nnode scripts/smoke.mjs [url]        # chat turn + AGENT: note against a running drawgent\nnode scripts/e2e-browser.mjs [url]  # real browser: chat panel + note typed on the canvas\nnode scripts/room-e2e.mjs           # fresh excalidraw.com room \u2194 drawgent, both directions\nLayout#\nsrc/ (Rust):\n\nmain.rs: CLI.\nsetup.rs, config.rs, chrome.rs: setup, config, renderer install.\nattach.rs: session discovery and picker.\nagents.rs + acp.rs: ACP driver (new / fork sessions).\nlive.rs: live opencode / Codex drivers.\nhub.rs: routing, notes, chat log.\nscene.rs: store and edit operations.\nrenderer.rs: Chrome over CDP.\nmcp.rs: MCP server.\nroom.rs: excalidraw.com client.\nfractional.rs, geometry.rs, el.rs: helpers.\n\nweb/: editor (main.jsx, chat.jsx) and renderer page (render.jsx).\nLimits#\n\nThe renderer needs Chrome (a native renderer is planned).\nClaude \"attach\" is a fork, because Claude Code has no public way to inject into a running\nterminal session.\nCodex live attach is implemented, but was not yet tested against a logged-in Codex.\nOne scene per workspace. Images/files are not synced."
                ],
                "output": "readability",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-26T22:05:05.527198+00:00",
                "status": "succeeded"
            },
            {
                "cmd": [
                    "/app/node_modules/readability-extractor/readability-extractor",
                    "/tmp/tmpwe5vif9_",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "0.0.11",
                "end_ts": "2026-09-27T07:18:42.606821+00:00",
                "index_texts": [
                    "8\n            \n        \n    \n\n      \n    \n  \n\n    \n      Configure Feed\n    \n\n    \n        \n        Issues\n      \n\n      \n        \n        Pull Requests\n      \n\n      \n        \n        Commits\n      \n\n      \n        \n        Tags\n      \n    \n\n    \n    \n\n    \n      Select the types of activity you want to include in your feed.\n    \n  \n\n  \n\n  \n      \n  This repository has no description\n    \n\n    \n\n    \n  \n\n\n      \n    \n    \n    \n        \n            \n            \n                8\n            \n        \n    \n\n      \n    \n  \n\n    \n      Configure Feed\n    \n\n    \n        \n        Issues\n      \n\n      \n        \n        Pull Requests\n      \n\n      \n        \n        Commits\n      \n\n      \n        \n        Tags\n      \n    \n\n    \n    \n\n    \n      Select the types of activity you want to include in your feed.\n    \n  \n\n  \n\n  \n    \n\n    \n        \n            \n        \n        \n          \n            \n    \n        \n            \n    \n      \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n      \n      \n    \n\n        \n        \n            \n              \n  \n  \n  \n\n 9\n            \n            \n              \n  \n  \n  \n  \n\n 1\n            \n            \n              \n  \n  \n  \n\n 0\n            \n            \n  \n  \n      \n  \n\n  \n\n  \n\n    \n      Clone this repository\n      \n        \n  \n  \n\n\n        \n  \n\n\n        Use permalink\n      \n    \n\n    \n\n    \n  \n    HTTPShttps://tangled.org/yanndegat.tngl.sh/drawgent\n      https://tangled.org/did:plc:3zklierfkckthy6sodbm4af3\n      \n    \n  \n\n\n    \n  \n    SSHgit@tangled.org:yanndegat.tngl.sh/drawgent\n      git@tangled.org:did:plc:3zklierfkckthy6sodbm4af3\n      \n    \n  \n\n\n    \n      For self-hosted knots, clone URLs may differ based on your setup.\n    \n\n    \n\n    \n      \n        \n  \n  \n  \n\n\n        Download tar.gz\n      \n      \n        \n  \n  \n  \n\n\n        Download .zip\n      \n    \n  \n\n  \n\n  \n\n          \n        \n  \n    \n      \n  \n  \n  \n  \n  \n  \n  \n  \n  \n\n Commits\n      9\n    \n  \n  \n    \n    \n                - acp: keep the agent's last stderr lines and exit status and report them  (\"agent process exited (exit status: 1): <stderr>\") in the log, the chat  panel and to pending requests, instead of a bare \"agent process exited\".- setup: record node's absolute path and launch `node <adapter script>`,  so `up` works where node isn't on PATH (e.g. setup ran in a nix shell);  warn when Node is older than the adapter's declared >= 22.- up: check every absolute path of the bridge still exists.Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>\n    \n    \n                A new stroke used to start its own zone once 4 s had passed, orphaningearlier traces that the chip's \u00d7 could no longer remove. Strokes now jointhe pending zone until it is sent or discarded, and traces already on thecanvas when the editor (re)connects are merged into one pending zone.laser-e2e covers both cases.Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>\n    \n    \n    \n    \n            \n                \n                \n                Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>\n                \n                \n          \n    \n    \n            \n                \n                \n                Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>\n                \n                \n          \n    \n    \n                Exported from the drawgent canvas: the hand sketch and its redrawnNetwork overview (Internet -> gateway -> 3 k8s nodes on vRack 10.0.0.0/8).Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>\n    \n    \n                The editor records Excalidraw laser gestures (onPointerUpdate) and keepsthem as a locked red freedraw trace tagged customData.drawgentZone. Thechat panel opens focused with a chip listing the covered elements; thenext message is sent with the zone, and the server adds the zone boundsand covered elements (most covered first) to the prompt. The trace isremoved when that turn ends (managed sessions) or when a live attachedsession goes idle again. get_scene reports traces as type \"zone\".Adds scripts/laser-e2e.mjs.Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>\n    \n    \n                Server logs each WebSocket request and connection; the editor logstimed [drawgent +Nms] lines in the browser console (page script,connecting/open/closed, init received) and shows an orange\"connecting\" dot in the chat panel.Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>\n    \n  \n  \n\n    \n\n          \n          \n\n        \n  \n  \n  \n  \n  \n\n\n        README.md\n      \n    \n        \ndrawgent connects your own Claude Code, Codex or opencode (your install, login, config and\nrepo) to an Excalidraw whiteboard. Ask for a diagram in the chat panel, or write AGENT: \u2026\nnext to the part of a drawing you want changed. The agent looks at the canvas (screenshot +\nscene), edits it live, checks the result, and marks the note DONE.\nHow it works#\n\nQuick start#\nPrerequisite: one of claude, codex or opencode installed and logged in. The Claude and\nCodex bridges also need Node.js \u2265 18 (npm).\ndrawgent setup claude        # once per agent: claude | codex | opencode\ncd ~/my-repo\ndrawgent up                  # new agent session in this repo + canvas in your browser\ndrawgent up --attach         # or: pick one of your running sessions and connect the canvas to it\nExample :)#\n\ndrawgent setup <agent>#\nChecks everything once, fails with the exact fix when something is missing, and writes\n~/.config/drawgent/config.toml:\n\n\nThe agent CLI. Your claude / codex / opencode on PATH.\n\n\nLogin. claude auth status, codex login status or opencode auth list.\n\n\nACP bridge.\n\nopencode speaks ACP itself (opencode acp).\nClaude Code and Codex use the official ACP adapters. They are installed once into\n~/.cache/drawgent/adapters (~60 MB), without their bundled agent binaries, and pointed\nat your CLI (CLAUDE_CODE_EXECUTABLE, CODEX_PATH).\nSetup then verifies the ACP handshake.\n\n\n\nCanvas tools for attached sessions. Only Codex needs a change:\ncodex mcp add drawgent -- drawgent mcp. Claude and opencode get the tools at attach time.\n\n\nHeadless Chrome for the renderer. Setup uses your Chrome/Chromium if you have one.\nOtherwise it proposes:\n\ndownloading Chrome Headless Shell (Chrome for Testing, ~120 MB, no sudo) into\n~/.cache/drawgent/chrome, and telling you exactly which system libraries are missing, if\nany;\ninstalling Chromium with your package manager (apt, snap, dnf, pacman, zypper,\napk, brew, or nix without sudo).\n\nNon-interactive: --chrome download | system | /path/to/chrome.\n\n\ndrawgent up refuses to start until setup succeeded for that agent, or if something setup\nrecorded disappeared.\ndrawgent up#\nRuns in the current directory (the workspace):\n\nstarts the editor + API on 127.0.0.1:7300 (next free port if taken);\nstarts a new session of your agent over ACP, working in the workspace;\nopens your browser. On a headless box it prints the ssh -L command instead.\n\nThe scene is kept in .drawgent/scene.json, which is git-ignored automatically.\ndrawgent up --attach [id]#\nConnects the canvas to a session you already run. Without an id it lists the sessions it\nfinds (current directory first) and lets you pick one:\n\n\n\nagent\ndiscovery\nhow the canvas reaches it\n\n\n\n\nClaude Code\nclaude agents --json (interactive and background sessions)\nfork: a new session carrying the full conversation, driven by drawgent over ACP. Your terminal session is left untouched\n\n\nopencode\nopencode servers listening locally: start the TUI with opencode --port 4096 (or opencode serve)\nlive: messages go into your running session (you see them in your TUI); drawgent adds its MCP tools to that server at runtime; replies, tool calls and prompts you type in the TUI are mirrored into the chat panel\n\n\nCodex\nsessions in ~/.codex/sessions\nlive: codex queue --thread <id>; replies are mirrored from the session's rollout file. The session needs the drawgent MCP (registered by setup, loaded when Codex starts)\n\n\n\nUsing the canvas#\n\nChat panel (right side): send a request, watch replies and tool calls stream in, approve\npermission prompts, press Stop to cancel a turn.\nOn the canvas: write a text starting with AGENT: next to or inside a shape, or draw an\narrow from the note to a shape. It fires about 2.5 s after you stop typing, with its\nposition, what it points at and what is nearby. The agent resolves it into a green\nDONE: \u2026 note. Edit it back to AGENT: to send it again.\nLaser zones: pick Excalidraw's laser (K) and circle or scribble over part of the diagram.\nThe trace stays on the canvas as a red outline, and the chat panel opens ready for your\ninstruction, with a chip listing what is under the zone (\ud83d\udd34 Laser zone \u00b7 API, Redis \u00d7). Your\nnext message goes to the agent together with the zone (bounds and covered elements), and the\ntrace disappears when the agent is done. Strokes within 4 s of each other form one zone; \u00d7\ndiscards it.\nPrompts are queued and run one at a time. A queued note that was already handled is skipped.\n\nexcalidraw.com rooms#\ndrawgent up --room 'https://excalidraw.com/#room=<id>,<key>'\n\ndrawgent joins the room as a collaborator (\ud83e\udd16 Agent, with a cursor that follows its edits).\nHumans can stay on excalidraw.com: their AGENT: notes reach your agent, and its edits\nappear there live.\nTraffic is end-to-end encrypted with the room key. Empty rooms are loaded from and saved to\nexcalidraw's Firestore storage.\nThe local editor mirrors the room and still has the chat panel.\n\nOther commands#\n\ndrawgent mcp: stdio MCP server with the canvas tools. Agents launch it; it finds the running\ndrawgent up by itself.\ndrawgent serve: low-level server with explicit agents (--agent claude,codex,opencode as set up,\nor name=command for any ACP agent); for scripts and containers.\nOptions for up / serve: --port, --room, --token (API bearer + ?token= in the URL),\n--permissions canvas|ask|all (default canvas: drawing tools auto-approved, anything else\nasked in the chat panel), --data, --settle-ms.\n\nOptional: Docker#\ndocker compose up --build runs a canvas server (drawgent + Chromium, no agents), e.g. to\nhost a shared canvas or a room bridge on a server. Agents are never bundled: they always run\nwith your own setup.\nBuild from source#\nnpm ci && npm run build      # editor + renderer pages -> dist/ (embedded into the binary)\ncargo install --path .       # or: cargo build --release\nAgent tools (MCP)#\nget_scene, get_screenshot (vision; zoom with element_ids), add_elements (Excalidraw\nskeletons; arrows bind by id and are routed edge-to-edge), add_mermaid (auto-layout),\nupdate_elements (labels follow shapes, bound arrows re-route), delete_elements,\nclear_canvas, list_instructions, resolve_instruction, set_status.\nAPI#\nGET /api/health \u00b7 GET /api/scene \u00b7 GET /api/screenshot?ids=&padding=&max= \u00b7\nPOST|PATCH|DELETE /api/elements \u00b7 POST /api/mermaid \u00b7 POST /api/clear \u00b7\nGET /api/instructions \u00b7 POST /api/instructions/{id}/resolve \u00b7 POST /api/status \u00b7\nPOST /api/chat {agent?, text} \u00b7 WS /ws (browser sync + chat events)\nTests#\ncargo test                          # fractional indices, room crypto/framing\nnode scripts/smoke.mjs [url]        # chat turn + AGENT: note against a running drawgent\nnode scripts/e2e-browser.mjs [url]  # real browser: chat panel + note typed on the canvas\nnode scripts/room-e2e.mjs           # fresh excalidraw.com room \u2194 drawgent, both directions\nnode scripts/laser-e2e.mjs          # laser zone \u2192 chat \u2192 agent edits only that zone (needs setup claude)\nLayout#\nsrc/ (Rust):\n\nmain.rs: CLI.\nsetup.rs, config.rs, chrome.rs: setup, config, renderer install.\nattach.rs: session discovery and picker.\nagents.rs + acp.rs: ACP driver (new / fork sessions).\nlive.rs: live opencode / Codex drivers.\nhub.rs: routing, notes, chat log.\nscene.rs: store and edit operations.\nrenderer.rs: Chrome over CDP.\nmcp.rs: MCP server.\nroom.rs: excalidraw.com client.\nfractional.rs, geometry.rs, el.rs: helpers.\n\nweb/: editor (main.jsx, chat.jsx, laser.js) and renderer page (render.jsx).\nLimits#\n\nThe renderer needs Chrome (a native renderer is planned).\nClaude \"attach\" is a fork, because Claude Code has no public way to inject into a running\nterminal session.\nCodex live attach is implemented, but was not yet tested against a logged-in Codex.\nOne scene per workspace. Images/files are not synced."
                ],
                "output": "readability",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-27T07:18:38.678938+00:00",
                "status": "succeeded"
            }
        ],
        "screenshot": [],
        "singlefile": [],
        "title": [
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--max-time",
                    "120",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-09-27T04:18:32.519319+00:00",
                "index_texts": null,
                "output": "yanndegat.tngl.sh/drawgent at main \u00b7 Tangled",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-27T04:18:32.468967+00:00",
                "status": "succeeded"
            },
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--max-time",
                    "120",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-09-27T01:31:31.971395+00:00",
                "index_texts": null,
                "output": "yanndegat.tngl.sh/drawgent at main \u00b7 Tangled",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-27T01:31:31.928626+00:00",
                "status": "succeeded"
            },
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--max-time",
                    "120",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-09-26T22:05:05.520606+00:00",
                "index_texts": null,
                "output": "yanndegat.tngl.sh/drawgent at main \u00b7 Tangled",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-26T22:05:05.485203+00:00",
                "status": "succeeded"
            },
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--max-time",
                    "120",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-09-27T07:18:38.673858+00:00",
                "index_texts": null,
                "output": "yanndegat.tngl.sh/drawgent at main \u00b7 Tangled",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-27T07:18:38.650811+00:00",
                "status": "succeeded"
            }
        ],
        "wget": [
            {
                "cmd": [
                    "wget",
                    "--no-verbose",
                    "--adjust-extension",
                    "--convert-links",
                    "--force-directories",
                    "--span-hosts",
                    "--no-parent",
                    "-e",
                    "robots=off",
                    "--reject=js,mjs,woff,woff2,ttf,otf,eot,mp4,m4v,mov,webm,ogv,mkv,avi,flv",
                    "--timeout=120",
                    "--restrict-file-names=windows",
                    "--page-requisites",
                    "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) wget/GNU Wget 1.21.3",
                    "--compression=auto",
                    "--timestamping",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "GNU Wget 1.21.3",
                "end_ts": "2026-09-27T04:18:32.459692+00:00",
                "index_texts": null,
                "output": "tangled.org/yanndegat.tngl.sh/drawgent.html",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-27T04:18:29.875516+00:00",
                "status": "succeeded"
            },
            {
                "cmd": [
                    "wget",
                    "--no-verbose",
                    "--adjust-extension",
                    "--convert-links",
                    "--force-directories",
                    "--span-hosts",
                    "--no-parent",
                    "-e",
                    "robots=off",
                    "--reject=js,mjs,woff,woff2,ttf,otf,eot,mp4,m4v,mov,webm,ogv,mkv,avi,flv",
                    "--timeout=120",
                    "--restrict-file-names=windows",
                    "--page-requisites",
                    "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) wget/GNU Wget 1.21.3",
                    "--compression=auto",
                    "--timestamping",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "GNU Wget 1.21.3",
                "end_ts": "2026-09-27T01:31:31.919069+00:00",
                "index_texts": null,
                "output": "tangled.org/yanndegat.tngl.sh/drawgent.html",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-27T01:31:29.514013+00:00",
                "status": "succeeded"
            },
            {
                "cmd": [
                    "wget",
                    "--no-verbose",
                    "--adjust-extension",
                    "--convert-links",
                    "--force-directories",
                    "--span-hosts",
                    "--no-parent",
                    "-e",
                    "robots=off",
                    "--reject=js,mjs,woff,woff2,ttf,otf,eot,mp4,m4v,mov,webm,ogv,mkv,avi,flv",
                    "--timeout=120",
                    "--restrict-file-names=windows",
                    "--page-requisites",
                    "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) wget/GNU Wget 1.21.3",
                    "--compression=auto",
                    "--timestamping",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "GNU Wget 1.21.3",
                "end_ts": "2026-09-26T22:05:05.476481+00:00",
                "index_texts": null,
                "output": "tangled.org/yanndegat.tngl.sh/drawgent.html",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-26T22:05:02.829143+00:00",
                "status": "succeeded"
            },
            {
                "cmd": [
                    "wget",
                    "--no-verbose",
                    "--adjust-extension",
                    "--convert-links",
                    "--force-directories",
                    "--span-hosts",
                    "--no-parent",
                    "-e",
                    "robots=off",
                    "--reject=js,mjs,woff,woff2,ttf,otf,eot,mp4,m4v,mov,webm,ogv,mkv,avi,flv",
                    "--timeout=120",
                    "--restrict-file-names=windows",
                    "--page-requisites",
                    "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) wget/GNU Wget 1.21.3",
                    "--compression=auto",
                    "--timestamping",
                    "https://tangled.org/yanndegat.tngl.sh/drawgent"
                ],
                "cmd_version": "GNU Wget 1.21.3",
                "end_ts": "2026-09-27T07:18:38.644238+00:00",
                "index_texts": null,
                "output": "tangled.org/yanndegat.tngl.sh/drawgent.html",
                "pwd": "/data/archive/1790460241.086592",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-27T07:18:32.682681+00:00",
                "status": "succeeded"
            }
        ]
    },
    "icons": null,
    "is_archived": true,
    "is_static": false,
    "latest": {
        "archive_org": null,
        "dom": null,
        "favicon": "favicon.ico",
        "git": null,
        "media": null,
        "pdf": null,
        "screenshot": null,
        "singlefile": null,
        "title": "yanndegat.tngl.sh/drawgent at main \u00b7 Tangled",
        "warc": null,
        "wget": "tangled.org/yanndegat.tngl.sh/drawgent.html"
    },
    "link_dir": "/data/archive/1790460241.086592",
    "newest_archive_date": "2026-09-27T07:18:42.619006+00:00",
    "num_failures": 0,
    "num_outputs": 24,
    "oldest_archive_date": "2026-09-26T22:05:00.862818+00:00",
    "path": "/yanndegat.tngl.sh/drawgent",
    "schema": "Link",
    "scheme": "https",
    "snapshot_id": "0aec0580-ac20-43fb-8691-35a0d0600431",
    "sources": [
        "/data/sources/1790460241-import.txt"
    ],
    "tags": ",war-wiki",
    "tags_str": "war-wiki",
    "timestamp": "1790460241.086592",
    "title": "yanndegat.tngl.sh/drawgent at main \u00b7 Tangled",
    "updated": "2026-09-27T07:18:30.869680+00:00",
    "updated_date": "2026-09-27 07:18",
    "url": "https://tangled.org/yanndegat.tngl.sh/drawgent"
}