forked from bots-garden/ori
🛟 Updated.Unverified
b6cd929 parent: 3d1f70c added
.memory/handoffs/2026-09-18-desktop-linux-build.md +69 -0 | new file mode 100644 | ||
| @@ -0,0 +1,69 @@ | ||
| 1 | +# Handoff — 2026-09-18 — ori-desktop built on Linux, MIT LICENSE added | |
| 2 | + | |
| 3 | +## What was asked | |
| 4 | + | |
| 5 | +1. `cd ori-desktop && wails build`. | |
| 6 | +2. Mid-session: "ajoute un fichier de licence MIT". | |
| 7 | +3. Then: how to build the macOS version (answered in chat), and "cree un document expliquant ca | |
| 8 | + dans ./ori-desktop/how-to-build.md". | |
| 9 | + | |
| 10 | +## State at the end | |
| 11 | + | |
| 12 | +All three done. New tracked files: `LICENSE` (root) and `ori-desktop/how-to-build.md`. The | |
| 13 | +pre-existing modifications to `docs/.assets/ori-architecture.drawio.svg`, | |
| 14 | +`ori-desktop/README.md`, `ori-desktop/README.fr.md` and `template/build.sh` are the user's and | |
| 15 | +were deliberately not touched. Nothing committed, nothing pushed. | |
| 16 | + | |
| 17 | +## The build recipe that works in this sandbox | |
| 18 | + | |
| 19 | +```bash | |
| 20 | +go install github.com/wailsapp/wails/v2/cmd/wails@v2.16.0 | |
| 21 | +sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev | |
| 22 | +export PATH="$PATH:$(go env GOPATH)/bin" | |
| 23 | +cd ori-desktop && wails build -tags webkit2_41 # → build/bin/ori-desktop (ELF aarch64, 9.4 MB) | |
| 24 | +``` | |
| 25 | + | |
| 26 | +## Traps found | |
| 27 | + | |
| 28 | +- **`wails build` without `-tags webkit2_41` fails here.** Wails' cgo pkg-config line asks for | |
| 29 | + `webkit2gtk-4.0`; Ubuntu 26.04 only packages `webkit2gtk-4.1`. Error: | |
| 30 | + `Package 'webkit2gtk-4.0' not found` ×3. | |
| 31 | +- **`wails doctor` lies about it**: it reports `libwebkit | Unknown | Not Found` and | |
| 32 | + `Fatal: Required dependencies missing: libwebkit` *after* 4.1 is installed, because it probes | |
| 33 | + only 4.0. Trust `pkg-config --modversion webkit2gtk-4.1` (→ 2.52.6) instead. | |
| 34 | +- **`make desktop` is still broken on Linux** — it runs bare `wails build`. Left as-is | |
| 35 | + deliberately (outside the ask). If you fix it, the tag must stay Linux-only: macOS and the | |
| 36 | + Windows cross-build must not receive `-tags webkit2_41`. | |
| 37 | +- **No macOS build is possible from here.** Wails needs macOS/Xcode for a `.app`. The | |
| 38 | + `build/bin/ori-desktop.app` that `scripts/launch-ori.applescript` opens is the user's own Mac | |
| 39 | + build; this session did not touch it. `build/bin/` now holds all three targets side by side. | |
| 40 | +- The apt packages live on the container disk, so a sandbox recreation loses them and the | |
| 41 | + install step has to be repeated. | |
| 42 | + | |
| 43 | +## The document | |
| 44 | + | |
| 45 | +`ori-desktop/how-to-build.md` — prerequisites, a from-where/to-what cross-build matrix, one | |
| 46 | +section per platform (macOS / Linux / Windows), the `wails build` flags that matter, `wails dev`, | |
| 47 | +the tests, troubleshooting. Written in the repository's Diátaxis how-to style, in English | |
| 48 | +(the `.md` / `.fr.md` pair convention means the unsuffixed name is the English one). | |
| 49 | + | |
| 50 | +Everything in it about Linux was verified in this session. The macOS section reflects the user's | |
| 51 | +own earlier build plus Wails v2.16 CLI behaviour (`wails build -help` was read, not guessed); the | |
| 52 | +`darwin/universal` variant has never been exercised in this project. | |
| 53 | + | |
| 54 | +## Next steps / still open | |
| 55 | + | |
| 56 | +- The window has **never been run** — neither here (no display) nor confirmed on the Mac after | |
| 57 | + the CSS specificity fix. The summary's "Not yet established" item about the iframe actually | |
| 58 | + showing ori inside WKWebView is unchanged by this session. | |
| 59 | +- The Linux binary was not executed either; only compiled. `xvfb` + a running ori server would | |
| 60 | + be the way to smoke-test it in the sandbox. | |
| 61 | +- `LICENSE` is referenced from nowhere: no badge or "Licence" section in `README.md` / | |
| 62 | + `README.fr.md` / `ori-desktop/README*.md`, no `"license": "MIT"` in `ui/package.json`. Add | |
| 63 | + those if the user wants the licence discoverable. | |
| 64 | +- `how-to-build.md` has no French counterpart and nothing links to it. Both were left undone on | |
| 65 | + purpose: the repository pairs every doc with a `.fr.md`, and `ori-desktop/README.md` has a | |
| 66 | + "Build a redistributable binary" section that is the obvious place for the pointer — but that | |
| 67 | + file has uncommitted user edits, so it was not touched. Offered to the user. | |
| 68 | +- The overlap between `how-to-build.md` and the build sections of `ori-desktop/README*.md` is now | |
| 69 | + duplicated content. If the user wants it deduplicated, the README should shrink to a link. | |
| new file mode 100644 | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | +# Handoff — 2026-09-18 — ori-desktop built on Linux, MIT LICENSE added | ||
| 2 | + | ||
| 3 | +## What was asked | ||
| 4 | + | ||
| 5 | +1. `cd ori-desktop && wails build`. | ||
| 6 | +2. Mid-session: "ajoute un fichier de licence MIT". | ||
| 7 | +3. Then: how to build the macOS version (answered in chat), and "cree un document expliquant ca | ||
| 8 | + dans ./ori-desktop/how-to-build.md". | ||
| 9 | + | ||
| 10 | +## State at the end | ||
| 11 | + | ||
| 12 | +All three done. New tracked files: `LICENSE` (root) and `ori-desktop/how-to-build.md`. The | ||
| 13 | +pre-existing modifications to `docs/.assets/ori-architecture.drawio.svg`, | ||
| 14 | +`ori-desktop/README.md`, `ori-desktop/README.fr.md` and `template/build.sh` are the user's and | ||
| 15 | +were deliberately not touched. Nothing committed, nothing pushed. | ||
| 16 | + | ||
| 17 | +## The build recipe that works in this sandbox | ||
| 18 | + | ||
| 19 | +```bash | ||
| 20 | +go install github.com/wailsapp/wails/v2/cmd/wails@v2.16.0 | ||
| 21 | +sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev | ||
| 22 | +export PATH="$PATH:$(go env GOPATH)/bin" | ||
| 23 | +cd ori-desktop && wails build -tags webkit2_41 # → build/bin/ori-desktop (ELF aarch64, 9.4 MB) | ||
| 24 | +``` | ||
| 25 | + | ||
| 26 | +## Traps found | ||
| 27 | + | ||
| 28 | +- **`wails build` without `-tags webkit2_41` fails here.** Wails' cgo pkg-config line asks for | ||
| 29 | + `webkit2gtk-4.0`; Ubuntu 26.04 only packages `webkit2gtk-4.1`. Error: | ||
| 30 | + `Package 'webkit2gtk-4.0' not found` ×3. | ||
| 31 | +- **`wails doctor` lies about it**: it reports `libwebkit | Unknown | Not Found` and | ||
| 32 | + `Fatal: Required dependencies missing: libwebkit` *after* 4.1 is installed, because it probes | ||
| 33 | + only 4.0. Trust `pkg-config --modversion webkit2gtk-4.1` (→ 2.52.6) instead. | ||
| 34 | +- **`make desktop` is still broken on Linux** — it runs bare `wails build`. Left as-is | ||
| 35 | + deliberately (outside the ask). If you fix it, the tag must stay Linux-only: macOS and the | ||
| 36 | + Windows cross-build must not receive `-tags webkit2_41`. | ||
| 37 | +- **No macOS build is possible from here.** Wails needs macOS/Xcode for a `.app`. The | ||
| 38 | + `build/bin/ori-desktop.app` that `scripts/launch-ori.applescript` opens is the user's own Mac | ||
| 39 | + build; this session did not touch it. `build/bin/` now holds all three targets side by side. | ||
| 40 | +- The apt packages live on the container disk, so a sandbox recreation loses them and the | ||
| 41 | + install step has to be repeated. | ||
| 42 | + | ||
| 43 | +## The document | ||
| 44 | + | ||
| 45 | +`ori-desktop/how-to-build.md` — prerequisites, a from-where/to-what cross-build matrix, one | ||
| 46 | +section per platform (macOS / Linux / Windows), the `wails build` flags that matter, `wails dev`, | ||
| 47 | +the tests, troubleshooting. Written in the repository's Diátaxis how-to style, in English | ||
| 48 | +(the `.md` / `.fr.md` pair convention means the unsuffixed name is the English one). | ||
| 49 | + | ||
| 50 | +Everything in it about Linux was verified in this session. The macOS section reflects the user's | ||
| 51 | +own earlier build plus Wails v2.16 CLI behaviour (`wails build -help` was read, not guessed); the | ||
| 52 | +`darwin/universal` variant has never been exercised in this project. | ||
| 53 | + | ||
| 54 | +## Next steps / still open | ||
| 55 | + | ||
| 56 | +- The window has **never been run** — neither here (no display) nor confirmed on the Mac after | ||
| 57 | + the CSS specificity fix. The summary's "Not yet established" item about the iframe actually | ||
| 58 | + showing ori inside WKWebView is unchanged by this session. | ||
| 59 | +- The Linux binary was not executed either; only compiled. `xvfb` + a running ori server would | ||
| 60 | + be the way to smoke-test it in the sandbox. | ||
| 61 | +- `LICENSE` is referenced from nowhere: no badge or "Licence" section in `README.md` / | ||
| 62 | + `README.fr.md` / `ori-desktop/README*.md`, no `"license": "MIT"` in `ui/package.json`. Add | ||
| 63 | + those if the user wants the licence discoverable. | ||
| 64 | +- `how-to-build.md` has no French counterpart and nothing links to it. Both were left undone on | ||
| 65 | + purpose: the repository pairs every doc with a `.fr.md`, and `ori-desktop/README.md` has a | ||
| 66 | + "Build a redistributable binary" section that is the obvious place for the pointer — but that | ||
| 67 | + file has uncommitted user edits, so it was not touched. Offered to the user. | ||
| 68 | +- The overlap between `how-to-build.md` and the build sections of `ori-desktop/README*.md` is now | ||
| 69 | + duplicated content. If the user wants it deduplicated, the README should shrink to a link. | ||
modified
.memory/history.md +10 -0 | @@ -178,3 +178,13 @@ | ||
| 178 | 178 | - **Decisions**: (1) new adapter over "bake `claude update` + `CLAUDE_CODE_EXECUTABLE`": the SDK ships a current CLI per platform, no version chasing. (2) `adapter` stage stays `--platform=$BUILDPLATFORM` (native npm) and targets the CPU explicitly, instead of npm under qemu. (3) Backend default changed too (user: "backend + template") so `make run` gets the same fix. (4) Pre-existing failures fixed along the way with the user's explicit OK: MIME test, Node 25, Markdown.tsx types, ToolCallCard complexity. (5) Left untracked as the user's artefacts/memos: `kits/.backup/`, `demo/` (the three prompt-generated stories the user moved there — their root copies are deleted in `5d476ff`), `kits/ori/publish.kit.md`, `template/publish.template.md`. |
| 179 | 179 | - **Verification**: `go vet ./... && go test ./...` green; ui `tsc -b` + 134 vitest green; `docker build --check` clean; arm64 image built locally — `claude-agent-acp` resolves for root and via `su … agent`, native SDK `linux-arm64` with the 230 MB CLI, manifest 2.1.274, ACP `initialize` answered by adapter 0.79.0, Zed adapter gone; amd64 install verified in a `node:24` container (`-linux-x64` present). Test sandbox `ori-acp` (image via `sbx template load`) served ori with CLI 2.1.274; the user pushed `k33g/ori:0.0.2` (multi-arch) and confirmed a real prompt in sandbox `hello-world` after the kit re-push. **Quality**: run #18 PASS (0/0/0, complex 532) after repairing qlty on the Mac (dangling `.qlty/*` symlinks from the sandbox; golangci-lint too old for Go 1.26). |
| 180 | 180 | - **Docs**: as listed, EN + FR in sync. `diataxis-doc` skill not invoked: edits to existing pages, done directly. |
| 181 | + | |
| 182 | +## 2026-09-18 — Linux build of ori-desktop (webkit2gtk-4.1) + MIT LICENSE | |
| 183 | + | |
| 184 | +- **Asked**: `cd ori-desktop && wails build`; then, mid-session, "ajoute un fichier de licence MIT". | |
| 185 | +- **Build**: installed the Wails CLI (`go install …/cmd/wails@v2.16.0`) and the GUI toolchain (`sudo apt-get install libgtk-3-dev libwebkit2gtk-4.1-dev`) in the sandbox — they were absent, which is why the window had never been launched here. Plain `wails build` fails: Wails' cgo pkg-config asks for `webkit2gtk-4.0`, Ubuntu 26.04 only ships 4.1. `wails build -tags webkit2_41` → `build/bin/ori-desktop`, ELF aarch64, 9.4 MB, 4.8 s. `wails doctor` still says `libwebkit: Not Found` (it only probes 4.0) — a false negative. No source change was needed. | |
| 186 | +- **Not done**: no macOS build — Wails cannot cross-compile to macOS from Linux, and the `.app` the user actually launches (`build/bin/ori-desktop.app`, and the AppleScript launcher) must still be built on the Mac. The Linux binary was added next to the existing `.app` and `.exe`, overwriting neither. The window itself was not run (no display in the sandbox). | |
| 187 | +- **Changes**: `LICENSE` (MIT, `Copyright (c) 2026 k33g`) at the repository root — the only file added to the tree; `build/bin/` and `frontend/wailsjs/` are gitignored. `.memory/summary.md`: the `-tags webkit2_41` requirement and the three build outputs on the `ori-desktop/` bullet, the apt/CLI install recipe under "Environment facts", the licence line. | |
| 188 | +- **Decisions**: holder `k33g` (the name used by every ticket author block and the git identity), not a guessed legal name. Root-only LICENSE, no copy under `ori-desktop/` despite it being a separate Go module. `make desktop` left untouched even though it fails on Linux for want of the tag — a Makefile change was outside what was asked; flagged to the user instead. | |
| 189 | +- **Verification**: `go test ./internal/...` in `ori-desktop` green (health, settings). Quality gate not re-run: no Go/TS source was modified. | |
| 190 | +- **Follow-up (same session)**: `ori-desktop/how-to-build.md` written on request — prerequisites, the from-where/to-what cross-build matrix (macOS only from macOS; Windows from anywhere; Linux from Linux), one section per platform, the `wails build` flags that matter, `wails dev`, the tests, and a troubleshooting list (webkit 4.0 vs 4.1, the `wails doctor` false negative, `make desktop` on Linux, the lost execute bit under cloud sync, Gatekeeper/`xattr -cr`, empty window = no server). English only, house Diátaxis how-to style; `how-to-build.fr.md` NOT written and `README.md` NOT linked to it — the user's own edits to `ori-desktop/README*.md` are uncommitted in the tree and were left alone. All four relative links in the doc were checked to resolve. | |
| @@ -178,3 +178,13 @@ | |||
| 178 | - **Decisions**: (1) new adapter over "bake `claude update` + `CLAUDE_CODE_EXECUTABLE`": the SDK ships a current CLI per platform, no version chasing. (2) `adapter` stage stays `--platform=$BUILDPLATFORM` (native npm) and targets the CPU explicitly, instead of npm under qemu. (3) Backend default changed too (user: "backend + template") so `make run` gets the same fix. (4) Pre-existing failures fixed along the way with the user's explicit OK: MIME test, Node 25, Markdown.tsx types, ToolCallCard complexity. (5) Left untracked as the user's artefacts/memos: `kits/.backup/`, `demo/` (the three prompt-generated stories the user moved there — their root copies are deleted in `5d476ff`), `kits/ori/publish.kit.md`, `template/publish.template.md`. | 178 | - **Decisions**: (1) new adapter over "bake `claude update` + `CLAUDE_CODE_EXECUTABLE`": the SDK ships a current CLI per platform, no version chasing. (2) `adapter` stage stays `--platform=$BUILDPLATFORM` (native npm) and targets the CPU explicitly, instead of npm under qemu. (3) Backend default changed too (user: "backend + template") so `make run` gets the same fix. (4) Pre-existing failures fixed along the way with the user's explicit OK: MIME test, Node 25, Markdown.tsx types, ToolCallCard complexity. (5) Left untracked as the user's artefacts/memos: `kits/.backup/`, `demo/` (the three prompt-generated stories the user moved there — their root copies are deleted in `5d476ff`), `kits/ori/publish.kit.md`, `template/publish.template.md`. |
| 179 | - **Verification**: `go vet ./... && go test ./...` green; ui `tsc -b` + 134 vitest green; `docker build --check` clean; arm64 image built locally — `claude-agent-acp` resolves for root and via `su … agent`, native SDK `linux-arm64` with the 230 MB CLI, manifest 2.1.274, ACP `initialize` answered by adapter 0.79.0, Zed adapter gone; amd64 install verified in a `node:24` container (`-linux-x64` present). Test sandbox `ori-acp` (image via `sbx template load`) served ori with CLI 2.1.274; the user pushed `k33g/ori:0.0.2` (multi-arch) and confirmed a real prompt in sandbox `hello-world` after the kit re-push. **Quality**: run #18 PASS (0/0/0, complex 532) after repairing qlty on the Mac (dangling `.qlty/*` symlinks from the sandbox; golangci-lint too old for Go 1.26). | 179 | - **Verification**: `go vet ./... && go test ./...` green; ui `tsc -b` + 134 vitest green; `docker build --check` clean; arm64 image built locally — `claude-agent-acp` resolves for root and via `su … agent`, native SDK `linux-arm64` with the 230 MB CLI, manifest 2.1.274, ACP `initialize` answered by adapter 0.79.0, Zed adapter gone; amd64 install verified in a `node:24` container (`-linux-x64` present). Test sandbox `ori-acp` (image via `sbx template load`) served ori with CLI 2.1.274; the user pushed `k33g/ori:0.0.2` (multi-arch) and confirmed a real prompt in sandbox `hello-world` after the kit re-push. **Quality**: run #18 PASS (0/0/0, complex 532) after repairing qlty on the Mac (dangling `.qlty/*` symlinks from the sandbox; golangci-lint too old for Go 1.26). |
| 180 | - **Docs**: as listed, EN + FR in sync. `diataxis-doc` skill not invoked: edits to existing pages, done directly. | 180 | - **Docs**: as listed, EN + FR in sync. `diataxis-doc` skill not invoked: edits to existing pages, done directly. |
| 181 | + | ||
| 182 | +## 2026-09-18 — Linux build of ori-desktop (webkit2gtk-4.1) + MIT LICENSE | ||
| 183 | + | ||
| 184 | +- **Asked**: `cd ori-desktop && wails build`; then, mid-session, "ajoute un fichier de licence MIT". | ||
| 185 | +- **Build**: installed the Wails CLI (`go install …/cmd/wails@v2.16.0`) and the GUI toolchain (`sudo apt-get install libgtk-3-dev libwebkit2gtk-4.1-dev`) in the sandbox — they were absent, which is why the window had never been launched here. Plain `wails build` fails: Wails' cgo pkg-config asks for `webkit2gtk-4.0`, Ubuntu 26.04 only ships 4.1. `wails build -tags webkit2_41` → `build/bin/ori-desktop`, ELF aarch64, 9.4 MB, 4.8 s. `wails doctor` still says `libwebkit: Not Found` (it only probes 4.0) — a false negative. No source change was needed. | ||
| 186 | +- **Not done**: no macOS build — Wails cannot cross-compile to macOS from Linux, and the `.app` the user actually launches (`build/bin/ori-desktop.app`, and the AppleScript launcher) must still be built on the Mac. The Linux binary was added next to the existing `.app` and `.exe`, overwriting neither. The window itself was not run (no display in the sandbox). | ||
| 187 | +- **Changes**: `LICENSE` (MIT, `Copyright (c) 2026 k33g`) at the repository root — the only file added to the tree; `build/bin/` and `frontend/wailsjs/` are gitignored. `.memory/summary.md`: the `-tags webkit2_41` requirement and the three build outputs on the `ori-desktop/` bullet, the apt/CLI install recipe under "Environment facts", the licence line. | ||
| 188 | +- **Decisions**: holder `k33g` (the name used by every ticket author block and the git identity), not a guessed legal name. Root-only LICENSE, no copy under `ori-desktop/` despite it being a separate Go module. `make desktop` left untouched even though it fails on Linux for want of the tag — a Makefile change was outside what was asked; flagged to the user instead. | ||
| 189 | +- **Verification**: `go test ./internal/...` in `ori-desktop` green (health, settings). Quality gate not re-run: no Go/TS source was modified. | ||
| 190 | +- **Follow-up (same session)**: `ori-desktop/how-to-build.md` written on request — prerequisites, the from-where/to-what cross-build matrix (macOS only from macOS; Windows from anywhere; Linux from Linux), one section per platform, the `wails build` flags that matter, `wails dev`, the tests, and a troubleshooting list (webkit 4.0 vs 4.1, the `wails doctor` false negative, `make desktop` on Linux, the lost execute bit under cloud sync, Gatekeeper/`xattr -cr`, empty window = no server). English only, house Diátaxis how-to style; `how-to-build.fr.md` NOT written and `README.md` NOT linked to it — the user's own edits to `ori-desktop/README*.md` are uncommitted in the tree and were left alone. All four relative links in the doc were checked to resolve. | ||
modified
.memory/summary.md +4 -1 | @@ -21,7 +21,7 @@ browser ⇆ WebSocket /ws ⇆ Go backend ⇆ stdio (ACP) ⇆ agent subprocess | ||
| 21 | 21 | - `internal/skills` — `GET /api/skills`: discovers `<cwd>/.claude/skills/*/SKILL.md` and `~/.claude/skills/*/SKILL.md` (frontmatter `name`/`description`, directory-name fallback, project shadows user, sorted). |
| 22 | 22 | - `internal/bridge` — hub between agent and browsers: JSON protocol (see `docs/*/reference/websocket-protocol.md`), broadcast with per-client buffers (slow client = dropped), append-only history (cap 4096) replayed on every connection, `user_message` echo so the server is the single source of truth, permission routing by requestId (pending requests replayed to late joiners; agent-side ctx cancellation handled). The `prompt` message carries optional `attachments: [{path,name}]`, turned server-side into ACP `resource_link` blocks (`file://<abs>`) next to the text block — `Prompter.Prompt(ctx, []acp.ContentBlock)` replaced `PromptText`; relative paths are joined to the root given by `Bridge.SetWorkspaceRoot` (wired in `cmd/ori/main.go`); `user_message` echoes the attachments. Uses `github.com/coder/websocket` v1.8.15; origins restricted to localhost. |
| 23 | 23 | - `ui/` — Vite + React 19 + TS strict; zustand store around a pure reducer (`ui/src/reducer.ts`, handler-table style); WS client with backoff reconnect; thread resets on `hello` so replays are idempotent; unknown ACP update kinds ignored by design. Workspace panel (separate zustand store `ui/src/workspace.ts`): file tree (click=preview, double-click=edit; column resizable via `ResizeHandle` — ARIA separator, pointer drag / arrows / Home-End / double-click reset — width `fileTreeWidth` in the store, bounded 120–800 px, default 224, applied through the `--filetree-width` CSS custom property, persisted in localStorage `ori.fileTreeWidth`). Colour theme (`ui/src/theme.ts`, own zustand store): `light` (default) | `dark`, stamped as `data-theme` on `<html>` at module load and on change, remembered in localStorage `ori.theme`, toggled by the header ☾/☀ button; `app.css` keys the dark palette on `:root[data-theme="dark"]` (the former `prefers-color-scheme` media query is gone — decision: explicit choice, light default), `MonacoViewer` reads the store (`vs-dark`/`light`), the terminal stays dark. Preview tab (Monaco read-only for code — bundled workers, no CDN, lazy chunk ~1MB gzip; rendered Markdown; rendered AsciiDoc via lazily-imported `@asciidoctor/core`, Rendered/Source toggle), Editor tab (Monaco, dirty ●, Save/Ctrl+S via PUT /api/file), Terminal tab (xterm.js on /ws/terminal, starts on first activation); inactive panes are hidden not unmounted so shell/edit state survives tab switches; `execute` tool-call output renders in a monospace `<pre>`, never markdown. Composer completions (`ui/src/mentions.ts` pure helpers, `ui/src/useCompletion.ts`, `CompletionPopup`): `@` opens a workspace file search (→ attachments), `/` opens a merged list of local skills (`/api/skills`) and ACP `available_commands_update` commands (stored as `commands` in the reducer, cleared on `hello`; deduped by name, skill wins) and inserts `/<name> ` as plain text — the text is the invocation mechanism, there is no ACP "run command" method. Preview kinds `image` (`ImageView`, `<img>` over checkerboard via `/api/raw`, natural size shown) and `drawio` (`DrawioView`: iframe on `embed.diagrams.net` fed by postMessage, Rendered/Source toggle, 8 s timeout → Source fallback; `.drawio.svg/.png` are images). The mock agent emits `available_commands_update` (`review`, `compact`) on session start and echoes `[attached: name]`. |
| 24 | -- `ori-desktop/` — separate Go module `rickub.com/bots-garden/ori-desktop` (Wails v2.16.0, Go ≥ 1.25, "plain" template, `//go:embed all:frontend/src`, no npm; `frontend/src/main.js` is loaded as an ES module — `type="module"` — since the 2026-09-17 lint cleanup): connection screen (URL remembered in `<UserConfigDir>/ori-desktop/settings.json`, key `serverUrl`; auto-connect at startup), `/healthz` probe via bound Go methods (GetConfig, SaveConfig, CheckHealth, Connect, OpenInBrowser, SettingsPath), then the ori SPA loaded in an `<iframe>` (Wails v2 cannot navigate the main webview to an external URL; `runtime.BrowserOpenURL` is the fallback). Ticket 0005. `make desktop` / `make desktop-test`; root `go test ./...` unaffected (nested module). | |
| 24 | +- `ori-desktop/` — separate Go module `rickub.com/bots-garden/ori-desktop` (Wails v2.16.0, Go ≥ 1.25, "plain" template, `//go:embed all:frontend/src`, no npm; `frontend/src/main.js` is loaded as an ES module — `type="module"` — since the 2026-09-17 lint cleanup): connection screen (URL remembered in `<UserConfigDir>/ori-desktop/settings.json`, key `serverUrl`; auto-connect at startup), `/healthz` probe via bound Go methods (GetConfig, SaveConfig, CheckHealth, Connect, OpenInBrowser, SettingsPath), then the ori SPA loaded in an `<iframe>` (Wails v2 cannot navigate the main webview to an external URL; `runtime.BrowserOpenURL` is the fallback). Ticket 0005. `make desktop` / `make desktop-test`; root `go test ./...` unaffected (nested module). **On Linux, `wails build` needs `-tags webkit2_41`** (Ubuntu 26.04 ships only `webkit2gtk-4.1`; the plain command dies on `Package 'webkit2gtk-4.0' not found`). `make desktop` does NOT pass that tag, so it fails in this sandbox — run `cd ori-desktop && wails build -tags webkit2_41` instead. Build outputs coexist in `build/bin/`: `ori-desktop` (Linux ELF), `ori-desktop.app` (macOS, built on the Mac), `ori-desktop.exe` (Windows cross-build); Wails cannot cross-compile to macOS from Linux. Build instructions for the three platforms: `ori-desktop/how-to-build.md` (2026-09-18, EN only — no `.fr.md` counterpart yet, and no README links to it). | |
| 25 | 25 | |
| 26 | 26 | ## Key decisions in force |
| 27 | 27 | |
| @@ -54,6 +54,7 @@ browser ⇆ WebSocket /ws ⇆ Go backend ⇆ stdio (ACP) ⇆ agent subprocess | ||
| 54 | 54 | - `~/.npm` is the same kind of 488MB dedicated volume and filled up when installing Monaco; the npm cache now lives at `~/.npm-big` via `NPM_CONFIG_CACHE` exported in `/etc/sandbox-persistent.sh`. |
| 55 | 55 | - Running ori inside this Claude-Code-driven sandbox requires `env -u CLAUDECODE ./bin/ori` (Claude refuses nested sessions). With the current template/kit (`claude-agent-acp`, bundled CLI 2.1.274) no `CLAUDE_CODE_EXECUTABLE` is needed. It remains the lever if something spawns the old Zed adapter (points it at another `claude` binary) — but the template's own CLI is 2.1.246 (base image 2026-08-26), below the 2.1.251 floor the API enforces for `claude-fable-5-1[1m]` (host `~/.claude/settings.json`), so `claude update` inside the sandbox would come first. Handoffs `2026-09-18-claude-version-too-old.md`, `2026-09-18-claude-agent-acp-adapter.md`. |
| 56 | 56 | - npm blocks install scripts by default here; esbuild's postinstall was approved via `npm approve-scripts` (recorded in `ui/package.json` `allowScripts`). |
| 57 | +- The Wails GUI toolchain is installable here (verified 2026-09-18): `go install github.com/wailsapp/wails/v2/cmd/wails@v2.16.0` then `sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev` (~15 GB free on `/`, plenty). `wails doctor` still reports `libwebkit: Not Found` because it only looks for `webkit2gtk-4.0` — ignore it; `pkg-config --modversion webkit2gtk-4.1` → 2.52.6 is what matters. These are apt packages on the container disk, so a sandbox recreation loses them. | |
| 57 | 58 | |
| 58 | 59 | ## Known limitations |
| 59 | 60 | |
| @@ -63,6 +64,8 @@ browser ⇆ WebSocket /ws ⇆ Go backend ⇆ stdio (ACP) ⇆ agent subprocess | ||
| 63 | 64 | - `user_message` / thought / message chunks only render text content blocks; images/audio/resources are not rendered yet; `user_message.attachments` are not rendered as chips (only the `@path` text mention). |
| 64 | 65 | - Skills list is fetched once per page load; the file search walks whatever sits under `--cwd` (an untracked `sandboxes/` clone at the repo root gets walked). |
| 65 | 66 | |
| 67 | +- Licence: MIT, `LICENSE` at the repository root (added 2026-09-18, holder `k33g` — the name used in the tickets and git identity). No per-module licence file; `ori-desktop/` is covered by the root one. Nothing references it yet from the READMEs or `ui/package.json`. | |
| 68 | + | |
| 66 | 69 | - Git: remote `origin` = `https://git.rickub.com/bots-garden/ori.git` (Gitea-style self-hosted, not GitHub). `main` fast-forwarded to `feat/acp-webapp` at commit `76d62ac` on 2026-09-17; **not pushed** yet. `hello.md` (a story generated during an ori test) and `.claude/settings.local.json` are deliberately left untracked. |
| 67 | 70 | |
| 68 | 71 | ## Not yet established |
| @@ -21,7 +21,7 @@ browser ⇆ WebSocket /ws ⇆ Go backend ⇆ stdio (ACP) ⇆ agent subprocess | |||
| 21 | - `internal/skills` — `GET /api/skills`: discovers `<cwd>/.claude/skills/*/SKILL.md` and `~/.claude/skills/*/SKILL.md` (frontmatter `name`/`description`, directory-name fallback, project shadows user, sorted). | 21 | - `internal/skills` — `GET /api/skills`: discovers `<cwd>/.claude/skills/*/SKILL.md` and `~/.claude/skills/*/SKILL.md` (frontmatter `name`/`description`, directory-name fallback, project shadows user, sorted). |
| 22 | - `internal/bridge` — hub between agent and browsers: JSON protocol (see `docs/*/reference/websocket-protocol.md`), broadcast with per-client buffers (slow client = dropped), append-only history (cap 4096) replayed on every connection, `user_message` echo so the server is the single source of truth, permission routing by requestId (pending requests replayed to late joiners; agent-side ctx cancellation handled). The `prompt` message carries optional `attachments: [{path,name}]`, turned server-side into ACP `resource_link` blocks (`file://<abs>`) next to the text block — `Prompter.Prompt(ctx, []acp.ContentBlock)` replaced `PromptText`; relative paths are joined to the root given by `Bridge.SetWorkspaceRoot` (wired in `cmd/ori/main.go`); `user_message` echoes the attachments. Uses `github.com/coder/websocket` v1.8.15; origins restricted to localhost. | 22 | - `internal/bridge` — hub between agent and browsers: JSON protocol (see `docs/*/reference/websocket-protocol.md`), broadcast with per-client buffers (slow client = dropped), append-only history (cap 4096) replayed on every connection, `user_message` echo so the server is the single source of truth, permission routing by requestId (pending requests replayed to late joiners; agent-side ctx cancellation handled). The `prompt` message carries optional `attachments: [{path,name}]`, turned server-side into ACP `resource_link` blocks (`file://<abs>`) next to the text block — `Prompter.Prompt(ctx, []acp.ContentBlock)` replaced `PromptText`; relative paths are joined to the root given by `Bridge.SetWorkspaceRoot` (wired in `cmd/ori/main.go`); `user_message` echoes the attachments. Uses `github.com/coder/websocket` v1.8.15; origins restricted to localhost. |
| 23 | - `ui/` — Vite + React 19 + TS strict; zustand store around a pure reducer (`ui/src/reducer.ts`, handler-table style); WS client with backoff reconnect; thread resets on `hello` so replays are idempotent; unknown ACP update kinds ignored by design. Workspace panel (separate zustand store `ui/src/workspace.ts`): file tree (click=preview, double-click=edit; column resizable via `ResizeHandle` — ARIA separator, pointer drag / arrows / Home-End / double-click reset — width `fileTreeWidth` in the store, bounded 120–800 px, default 224, applied through the `--filetree-width` CSS custom property, persisted in localStorage `ori.fileTreeWidth`). Colour theme (`ui/src/theme.ts`, own zustand store): `light` (default) | `dark`, stamped as `data-theme` on `<html>` at module load and on change, remembered in localStorage `ori.theme`, toggled by the header ☾/☀ button; `app.css` keys the dark palette on `:root[data-theme="dark"]` (the former `prefers-color-scheme` media query is gone — decision: explicit choice, light default), `MonacoViewer` reads the store (`vs-dark`/`light`), the terminal stays dark. Preview tab (Monaco read-only for code — bundled workers, no CDN, lazy chunk ~1MB gzip; rendered Markdown; rendered AsciiDoc via lazily-imported `@asciidoctor/core`, Rendered/Source toggle), Editor tab (Monaco, dirty ●, Save/Ctrl+S via PUT /api/file), Terminal tab (xterm.js on /ws/terminal, starts on first activation); inactive panes are hidden not unmounted so shell/edit state survives tab switches; `execute` tool-call output renders in a monospace `<pre>`, never markdown. Composer completions (`ui/src/mentions.ts` pure helpers, `ui/src/useCompletion.ts`, `CompletionPopup`): `@` opens a workspace file search (→ attachments), `/` opens a merged list of local skills (`/api/skills`) and ACP `available_commands_update` commands (stored as `commands` in the reducer, cleared on `hello`; deduped by name, skill wins) and inserts `/<name> ` as plain text — the text is the invocation mechanism, there is no ACP "run command" method. Preview kinds `image` (`ImageView`, `<img>` over checkerboard via `/api/raw`, natural size shown) and `drawio` (`DrawioView`: iframe on `embed.diagrams.net` fed by postMessage, Rendered/Source toggle, 8 s timeout → Source fallback; `.drawio.svg/.png` are images). The mock agent emits `available_commands_update` (`review`, `compact`) on session start and echoes `[attached: name]`. | 23 | - `ui/` — Vite + React 19 + TS strict; zustand store around a pure reducer (`ui/src/reducer.ts`, handler-table style); WS client with backoff reconnect; thread resets on `hello` so replays are idempotent; unknown ACP update kinds ignored by design. Workspace panel (separate zustand store `ui/src/workspace.ts`): file tree (click=preview, double-click=edit; column resizable via `ResizeHandle` — ARIA separator, pointer drag / arrows / Home-End / double-click reset — width `fileTreeWidth` in the store, bounded 120–800 px, default 224, applied through the `--filetree-width` CSS custom property, persisted in localStorage `ori.fileTreeWidth`). Colour theme (`ui/src/theme.ts`, own zustand store): `light` (default) | `dark`, stamped as `data-theme` on `<html>` at module load and on change, remembered in localStorage `ori.theme`, toggled by the header ☾/☀ button; `app.css` keys the dark palette on `:root[data-theme="dark"]` (the former `prefers-color-scheme` media query is gone — decision: explicit choice, light default), `MonacoViewer` reads the store (`vs-dark`/`light`), the terminal stays dark. Preview tab (Monaco read-only for code — bundled workers, no CDN, lazy chunk ~1MB gzip; rendered Markdown; rendered AsciiDoc via lazily-imported `@asciidoctor/core`, Rendered/Source toggle), Editor tab (Monaco, dirty ●, Save/Ctrl+S via PUT /api/file), Terminal tab (xterm.js on /ws/terminal, starts on first activation); inactive panes are hidden not unmounted so shell/edit state survives tab switches; `execute` tool-call output renders in a monospace `<pre>`, never markdown. Composer completions (`ui/src/mentions.ts` pure helpers, `ui/src/useCompletion.ts`, `CompletionPopup`): `@` opens a workspace file search (→ attachments), `/` opens a merged list of local skills (`/api/skills`) and ACP `available_commands_update` commands (stored as `commands` in the reducer, cleared on `hello`; deduped by name, skill wins) and inserts `/<name> ` as plain text — the text is the invocation mechanism, there is no ACP "run command" method. Preview kinds `image` (`ImageView`, `<img>` over checkerboard via `/api/raw`, natural size shown) and `drawio` (`DrawioView`: iframe on `embed.diagrams.net` fed by postMessage, Rendered/Source toggle, 8 s timeout → Source fallback; `.drawio.svg/.png` are images). The mock agent emits `available_commands_update` (`review`, `compact`) on session start and echoes `[attached: name]`. |
| 24 | -- `ori-desktop/` — separate Go module `rickub.com/bots-garden/ori-desktop` (Wails v2.16.0, Go ≥ 1.25, "plain" template, `//go:embed all:frontend/src`, no npm; `frontend/src/main.js` is loaded as an ES module — `type="module"` — since the 2026-09-17 lint cleanup): connection screen (URL remembered in `<UserConfigDir>/ori-desktop/settings.json`, key `serverUrl`; auto-connect at startup), `/healthz` probe via bound Go methods (GetConfig, SaveConfig, CheckHealth, Connect, OpenInBrowser, SettingsPath), then the ori SPA loaded in an `<iframe>` (Wails v2 cannot navigate the main webview to an external URL; `runtime.BrowserOpenURL` is the fallback). Ticket 0005. `make desktop` / `make desktop-test`; root `go test ./...` unaffected (nested module). | 24 | +- `ori-desktop/` — separate Go module `rickub.com/bots-garden/ori-desktop` (Wails v2.16.0, Go ≥ 1.25, "plain" template, `//go:embed all:frontend/src`, no npm; `frontend/src/main.js` is loaded as an ES module — `type="module"` — since the 2026-09-17 lint cleanup): connection screen (URL remembered in `<UserConfigDir>/ori-desktop/settings.json`, key `serverUrl`; auto-connect at startup), `/healthz` probe via bound Go methods (GetConfig, SaveConfig, CheckHealth, Connect, OpenInBrowser, SettingsPath), then the ori SPA loaded in an `<iframe>` (Wails v2 cannot navigate the main webview to an external URL; `runtime.BrowserOpenURL` is the fallback). Ticket 0005. `make desktop` / `make desktop-test`; root `go test ./...` unaffected (nested module). **On Linux, `wails build` needs `-tags webkit2_41`** (Ubuntu 26.04 ships only `webkit2gtk-4.1`; the plain command dies on `Package 'webkit2gtk-4.0' not found`). `make desktop` does NOT pass that tag, so it fails in this sandbox — run `cd ori-desktop && wails build -tags webkit2_41` instead. Build outputs coexist in `build/bin/`: `ori-desktop` (Linux ELF), `ori-desktop.app` (macOS, built on the Mac), `ori-desktop.exe` (Windows cross-build); Wails cannot cross-compile to macOS from Linux. Build instructions for the three platforms: `ori-desktop/how-to-build.md` (2026-09-18, EN only — no `.fr.md` counterpart yet, and no README links to it). |
| 25 | 25 | ||
| 26 | ## Key decisions in force | 26 | ## Key decisions in force |
| 27 | 27 | ||
| @@ -54,6 +54,7 @@ browser ⇆ WebSocket /ws ⇆ Go backend ⇆ stdio (ACP) ⇆ agent subprocess | |||
| 54 | - `~/.npm` is the same kind of 488MB dedicated volume and filled up when installing Monaco; the npm cache now lives at `~/.npm-big` via `NPM_CONFIG_CACHE` exported in `/etc/sandbox-persistent.sh`. | 54 | - `~/.npm` is the same kind of 488MB dedicated volume and filled up when installing Monaco; the npm cache now lives at `~/.npm-big` via `NPM_CONFIG_CACHE` exported in `/etc/sandbox-persistent.sh`. |
| 55 | - Running ori inside this Claude-Code-driven sandbox requires `env -u CLAUDECODE ./bin/ori` (Claude refuses nested sessions). With the current template/kit (`claude-agent-acp`, bundled CLI 2.1.274) no `CLAUDE_CODE_EXECUTABLE` is needed. It remains the lever if something spawns the old Zed adapter (points it at another `claude` binary) — but the template's own CLI is 2.1.246 (base image 2026-08-26), below the 2.1.251 floor the API enforces for `claude-fable-5-1[1m]` (host `~/.claude/settings.json`), so `claude update` inside the sandbox would come first. Handoffs `2026-09-18-claude-version-too-old.md`, `2026-09-18-claude-agent-acp-adapter.md`. | 55 | - Running ori inside this Claude-Code-driven sandbox requires `env -u CLAUDECODE ./bin/ori` (Claude refuses nested sessions). With the current template/kit (`claude-agent-acp`, bundled CLI 2.1.274) no `CLAUDE_CODE_EXECUTABLE` is needed. It remains the lever if something spawns the old Zed adapter (points it at another `claude` binary) — but the template's own CLI is 2.1.246 (base image 2026-08-26), below the 2.1.251 floor the API enforces for `claude-fable-5-1[1m]` (host `~/.claude/settings.json`), so `claude update` inside the sandbox would come first. Handoffs `2026-09-18-claude-version-too-old.md`, `2026-09-18-claude-agent-acp-adapter.md`. |
| 56 | - npm blocks install scripts by default here; esbuild's postinstall was approved via `npm approve-scripts` (recorded in `ui/package.json` `allowScripts`). | 56 | - npm blocks install scripts by default here; esbuild's postinstall was approved via `npm approve-scripts` (recorded in `ui/package.json` `allowScripts`). |
| 57 | +- The Wails GUI toolchain is installable here (verified 2026-09-18): `go install github.com/wailsapp/wails/v2/cmd/wails@v2.16.0` then `sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev` (~15 GB free on `/`, plenty). `wails doctor` still reports `libwebkit: Not Found` because it only looks for `webkit2gtk-4.0` — ignore it; `pkg-config --modversion webkit2gtk-4.1` → 2.52.6 is what matters. These are apt packages on the container disk, so a sandbox recreation loses them. | ||
| 57 | 58 | ||
| 58 | ## Known limitations | 59 | ## Known limitations |
| 59 | 60 | ||
| @@ -63,6 +64,8 @@ browser ⇆ WebSocket /ws ⇆ Go backend ⇆ stdio (ACP) ⇆ agent subprocess | |||
| 63 | - `user_message` / thought / message chunks only render text content blocks; images/audio/resources are not rendered yet; `user_message.attachments` are not rendered as chips (only the `@path` text mention). | 64 | - `user_message` / thought / message chunks only render text content blocks; images/audio/resources are not rendered yet; `user_message.attachments` are not rendered as chips (only the `@path` text mention). |
| 64 | - Skills list is fetched once per page load; the file search walks whatever sits under `--cwd` (an untracked `sandboxes/` clone at the repo root gets walked). | 65 | - Skills list is fetched once per page load; the file search walks whatever sits under `--cwd` (an untracked `sandboxes/` clone at the repo root gets walked). |
| 65 | 66 | ||
| 67 | +- Licence: MIT, `LICENSE` at the repository root (added 2026-09-18, holder `k33g` — the name used in the tickets and git identity). No per-module licence file; `ori-desktop/` is covered by the root one. Nothing references it yet from the READMEs or `ui/package.json`. | ||
| 68 | + | ||
| 66 | - Git: remote `origin` = `https://git.rickub.com/bots-garden/ori.git` (Gitea-style self-hosted, not GitHub). `main` fast-forwarded to `feat/acp-webapp` at commit `76d62ac` on 2026-09-17; **not pushed** yet. `hello.md` (a story generated during an ori test) and `.claude/settings.local.json` are deliberately left untracked. | 69 | - Git: remote `origin` = `https://git.rickub.com/bots-garden/ori.git` (Gitea-style self-hosted, not GitHub). `main` fast-forwarded to `feat/acp-webapp` at commit `76d62ac` on 2026-09-17; **not pushed** yet. `hello.md` (a story generated during an ori test) and `.claude/settings.local.json` are deliberately left untracked. |
| 67 | 70 | ||
| 68 | ## Not yet established | 71 | ## Not yet established |
added
LICENSE +21 -0 | new file mode 100644 | ||
| @@ -0,0 +1,21 @@ | ||
| 1 | +MIT License | |
| 2 | + | |
| 3 | +Copyright (c) 2026 k33g | |
| 4 | + | |
| 5 | +Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 6 | +of this software and associated documentation files (the "Software"), to deal | |
| 7 | +in the Software without restriction, including without limitation the rights | |
| 8 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 9 | +copies of the Software, and to permit persons to whom the Software is | |
| 10 | +furnished to do so, subject to the following conditions: | |
| 11 | + | |
| 12 | +The above copyright notice and this permission notice shall be included in all | |
| 13 | +copies or substantial portions of the Software. | |
| 14 | + | |
| 15 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 16 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 17 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 18 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 19 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 20 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
| 21 | +SOFTWARE. | |
| new file mode 100644 | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | +MIT License | ||
| 2 | + | ||
| 3 | +Copyright (c) 2026 k33g | ||
| 4 | + | ||
| 5 | +Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 6 | +of this software and associated documentation files (the "Software"), to deal | ||
| 7 | +in the Software without restriction, including without limitation the rights | ||
| 8 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 9 | +copies of the Software, and to permit persons to whom the Software is | ||
| 10 | +furnished to do so, subject to the following conditions: | ||
| 11 | + | ||
| 12 | +The above copyright notice and this permission notice shall be included in all | ||
| 13 | +copies or substantial portions of the Software. | ||
| 14 | + | ||
| 15 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 16 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 17 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 18 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 19 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 20 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 21 | +SOFTWARE. | ||
modified
docs/.assets/ori-architecture.drawio.svg +359 -80 | @@ -1,80 +1,359 @@ | ||
| 1 | -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1220" height="640" viewBox="0 0 1220 640" content="<mxfile host="Electron" agent="make-diagram.mjs" type="device"><diagram name="Ori Architecture" id="diagram-1"><mxGraphModel dx="1000" dy="600" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="826" math="0" shadow="0"><root><mxCell id="0"/><mxCell id="1" parent="0"/><mxCell id="3" value="Browser&amp;#10;React SPA" style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#fdfdfb;strokeColor=#15202b;fontColor=#15202b;fontSize=17;fontStyle=0;strokeWidth=2;" vertex="1" parent="1"><mxGeometry x="20" y="20" width="220" height="110" as="geometry"/></mxCell><mxCell id="4" value="UI Components&amp;#10;· Agent Panel&amp;#10;· Workspace Panel&amp;#10;· File Tree&amp;#10;· Monaco Editor&amp;#10;· Terminal (xterm.js)" style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#e8ebda;strokeColor=#15202b;fontColor=#15202b;fontSize=17;fontStyle=1;strokeWidth=2;" vertex="1" parent="1"><mxGeometry x="20" y="150" width="220" height="150" as="geometry"/></mxCell><mxCell id="5" value="httpserver&amp;#10;Serves SPA + /ws" style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#15202b;strokeColor=#15202b;fontColor=#fdfdfb;fontSize=17;fontStyle=1;strokeWidth=2;" vertex="1" parent="1"><mxGeometry x="370" y="20" width="280" height="90" as="geometry"/></mxCell><mxCell id="6" value="bridge&amp;#10;· WebSocket ⇄ ACP&amp;#10;· Event broadcast&amp;#10;· Permission routing&amp;#10;· History replay" style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#15202b;strokeColor=#15202b;fontColor=#fdfdfb;fontSize=17;fontStyle=1;strokeWidth=2;" vertex="1" parent="1"><mxGeometry x="370" y="140" width="280" height="130" as="geometry"/></mxCell><mxCell id="7" value="agent&amp;#10;ACP session&amp;#10;lifecycle" style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#15202b;strokeColor=#15202b;fontColor=#fdfdfb;fontSize=17;fontStyle=1;strokeWidth=2;" vertex="1" parent="1"><mxGeometry x="370" y="300" width="135" height="90" as="geometry"/></mxCell><mxCell id="8" value="files&amp;#10;Workspace&amp;#10;file API" style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#15202b;strokeColor=#15202b;fontColor=#fdfdfb;fontSize=17;fontStyle=1;strokeWidth=2;" vertex="1" parent="1"><mxGeometry x="515" y="300" width="135" height="90" as="geometry"/></mxCell><mxCell id="9" value="terminal&amp;#10;PTY per&amp;#10;connection" style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#15202b;strokeColor=#15202b;fontColor=#fdfdfb;fontSize=17;fontStyle=1;strokeWidth=2;" vertex="1" parent="1"><mxGeometry x="370" y="410" width="135" height="90" as="geometry"/></mxCell><mxCell id="10" value="mockagent&amp;#10;Demo agent&amp;#10;(testing)" style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#e8ebda;strokeColor=#15202b;fontColor=#15202b;fontSize=17;fontStyle=1;strokeWidth=2;" vertex="1" parent="1"><mxGeometry x="515" y="410" width="135" height="90" as="geometry"/></mxCell><mxCell id="11" value="ACP Agent&amp;#10;(claude-code-acp / Gemini CLI)&amp;#10;&amp;#10;JSON-RPC over stdio&amp;#10;session_update · permission_request" style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#fdfdfb;strokeColor=#0062FF;fontColor=#0062FF;fontSize=17;fontStyle=1;strokeWidth=2;" vertex="1" parent="1"><mxGeometry x="800" y="230" width="400" height="130" as="geometry"/></mxCell><mxCell id="12" value="Go backend bridges browser WebSockets to ACP stdio, broadcasting agent updates to all connected browsers while routing permissions back to the waiting call." style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#fdfdfb;strokeColor=#15202b;fontColor=#15202b;fontSize=15;fontStyle=0;strokeWidth=2;dashed=1;" vertex="1" parent="1"><mxGeometry x="20" y="560" width="1180" height="60" as="geometry"/></mxCell><mxCell id="13" value="1. load SPA" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeWidth=2;strokeColor=#15202b;fontSize=14;fontColor=#15202b;" edge="1" parent="1" source="3" target="5"><mxGeometry relative="1" as="geometry"></mxGeometry></mxCell><mxCell id="14" value="2. WebSocket&amp;#10;/ws" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeWidth=2;strokeColor=#15202b;fontSize=14;fontColor=#15202b;exitX=1;exitY=0.7272727272727273;exitDx=0;exitDy=0;entryX=0;entryY=0.3076923076923077;entryDx=0;entryDy=0;" edge="1" parent="1" source="3" target="6"><mxGeometry relative="1" as="geometry"></mxGeometry></mxCell><mxCell id="15" value="3. prompt +&amp;#10;permission&amp;#10;responses" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeWidth=2;strokeColor=#15202b;fontSize=14;fontColor=#15202b;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.6538461538461539;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="6"><mxGeometry relative="1" as="geometry"></mxGeometry></mxCell><mxCell id="16" value="4. session_update&amp;#10;events (replay)" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeWidth=2;strokeColor=#0062FF;fontSize=14;fontColor=#0062FF;dashed=1;" edge="1" parent="1" source="6" target="4"><mxGeometry relative="1" as="geometry"><Array as="points"><mxPoint x="310" y="230"/><mxPoint x="280" y="230"/></Array></mxGeometry></mxCell><mxCell id="17" value="5. ACP&amp;#10;lifecycle" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeWidth=2;strokeColor=#15202b;fontSize=14;fontColor=#15202b;exitX=0.2857142857142857;exitY=1;exitDx=0;exitDy=0;entryX=0.4962962962962963;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="7"><mxGeometry relative="1" as="geometry"></mxGeometry></mxCell><mxCell id="18" value="6. stdio&amp;#10;JSON-RPC" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeWidth=2;strokeColor=#15202b;fontSize=14;fontColor=#15202b;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="7" target="11"><mxGeometry relative="1" as="geometry"></mxGeometry></mxCell><mxCell id="19" value="7. updates +&amp;#10;permissions" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeWidth=2;strokeColor=#0062FF;fontSize=14;fontColor=#0062FF;dashed=1;" edge="1" parent="1" source="11" target="6"><mxGeometry relative="1" as="geometry"><Array as="points"><mxPoint x="720" y="200"/><mxPoint x="650" y="200"/></Array></mxGeometry></mxCell><mxCell id="20" value="file ops" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeWidth=2;strokeColor=#0062FF;fontSize=14;fontColor=#0062FF;dashed=1;exitX=1;exitY=0.8666666666666667;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="8"><mxGeometry relative="1" as="geometry"></mxGeometry></mxCell><mxCell id="21" value="shell I/O" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeWidth=2;strokeColor=#0062FF;fontSize=14;fontColor=#0062FF;dashed=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="9"><mxGeometry relative="1" as="geometry"></mxGeometry></mxCell></root></mxGraphModel></diagram></mxfile>"> | |
| 2 | - <defs><marker id="arrow-dark" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M 0 0 L 10 5 L 0 10 z" fill="#15202b"/></marker><marker id="arrow-blue" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M 0 0 L 10 5 L 0 10 z" fill="#0062FF"/></marker></defs> | |
| 3 | - <path d="M 242 75 L 364 75" fill="none" stroke="#15202b" stroke-width="2" marker-end="url(#arrow-dark)"/> | |
| 4 | - <rect x="254.2" y="62.5" width="97.6" height="25" rx="4" fill="#fdfdfb" opacity="0.92"/> | |
| 5 | - <text x="303" y="75" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">1. load SPA</text> | |
| 6 | - <path d="M 242 100 L 364 180" fill="none" stroke="#15202b" stroke-width="2" marker-end="url(#arrow-dark)"/> | |
| 7 | - <rect x="250.4" y="119" width="105.19999999999999" height="42" rx="4" fill="#fdfdfb" opacity="0.92"/> | |
| 8 | - <text x="303" y="131.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">2. WebSocket</text> | |
| 9 | - <text x="303" y="148.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">/ws</text> | |
| 10 | - <path d="M 242 225 L 364 225" fill="none" stroke="#15202b" stroke-width="2" marker-end="url(#arrow-dark)"/> | |
| 11 | - <rect x="254.2" y="195.5" width="97.6" height="59" rx="4" fill="#fdfdfb" opacity="0.92"/> | |
| 12 | - <text x="303" y="208" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">3. prompt +</text> | |
| 13 | - <text x="303" y="225" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">permission</text> | |
| 14 | - <text x="303" y="242" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">responses</text> | |
| 15 | - <path d="M 368 205 L 310 230 L 280 230 L 246 225" fill="none" stroke="#0062FF" stroke-width="2" stroke-dasharray="6 5" marker-end="url(#arrow-blue)"/> | |
| 16 | - <rect x="267.4" y="196.5" width="143.2" height="42" rx="4" fill="#fdfdfb" opacity="0.92"/> | |
| 17 | - <text x="339" y="209" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#0062FF">4. session_update</text> | |
| 18 | - <text x="339" y="226" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#0062FF">events (replay)</text> | |
| 19 | - <path d="M 450 272 L 437 294" fill="none" stroke="#15202b" stroke-width="2" marker-end="url(#arrow-dark)"/> | |
| 20 | - <rect x="402.3" y="262" width="82.39999999999999" height="42" rx="4" fill="#fdfdfb" opacity="0.92"/> | |
| 21 | - <text x="443.5" y="274.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">5. ACP</text> | |
| 22 | - <text x="443.5" y="291.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">lifecycle</text> | |
| 23 | - <path d="M 507 345 L 794 295" fill="none" stroke="#15202b" stroke-width="2" marker-end="url(#arrow-dark)"/> | |
| 24 | - <rect x="613.1" y="299" width="74.8" height="42" rx="4" fill="#fdfdfb" opacity="0.92"/> | |
| 25 | - <text x="650.5" y="311.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">6. stdio</text> | |
| 26 | - <text x="650.5" y="328.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">JSON-RPC</text> | |
| 27 | - <path d="M 798 295 L 720 200 L 650 200 L 656 205" fill="none" stroke="#0062FF" stroke-width="2" stroke-dasharray="6 5" marker-end="url(#arrow-blue)"/> | |
| 28 | - <rect x="706.4" y="226.5" width="105.19999999999999" height="42" rx="4" fill="#fdfdfb" opacity="0.92"/> | |
| 29 | - <text x="759" y="239" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#0062FF">7. updates +</text> | |
| 30 | - <text x="759" y="256" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#0062FF">permissions</text> | |
| 31 | - <path d="M 242 280 L 509 345" fill="none" stroke="#0062FF" stroke-width="2" stroke-dasharray="6 5" marker-end="url(#arrow-blue)"/> | |
| 32 | - <rect x="338.1" y="300" width="74.8" height="25" rx="4" fill="#fdfdfb" opacity="0.92"/> | |
| 33 | - <text x="375.5" y="312.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#0062FF">file ops</text> | |
| 34 | - <path d="M 130 302 L 364 455" fill="none" stroke="#0062FF" stroke-width="2" stroke-dasharray="6 5" marker-end="url(#arrow-blue)"/> | |
| 35 | - <rect x="205.8" y="366" width="82.39999999999999" height="25" rx="4" fill="#fdfdfb" opacity="0.92"/> | |
| 36 | - <text x="247" y="378.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#0062FF">shell I/O</text> | |
| 37 | - <rect x="20" y="20" width="220" height="110" rx="10" ry="10" fill="#fdfdfb" stroke="#15202b" stroke-width="2"/> | |
| 38 | - <text x="130" y="64.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="normal" fill="#15202b">Browser</text> | |
| 39 | - <text x="130" y="85.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="normal" fill="#15202b">React SPA</text> | |
| 40 | - <rect x="20" y="150" width="220" height="150" rx="10" ry="10" fill="#e8ebda" stroke="#15202b" stroke-width="2"/> | |
| 41 | - <text x="130" y="172.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#15202b">UI Components</text> | |
| 42 | - <text x="130" y="193.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#15202b">· Agent Panel</text> | |
| 43 | - <text x="130" y="214.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#15202b">· Workspace Panel</text> | |
| 44 | - <text x="130" y="235.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#15202b">· File Tree</text> | |
| 45 | - <text x="130" y="256.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#15202b">· Monaco Editor</text> | |
| 46 | - <text x="130" y="277.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#15202b">· Terminal (xterm.js)</text> | |
| 47 | - <rect x="370" y="20" width="280" height="90" rx="10" ry="10" fill="#15202b" stroke="#15202b" stroke-width="2"/> | |
| 48 | - <text x="510" y="54.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">httpserver</text> | |
| 49 | - <text x="510" y="75.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">Serves SPA + /ws</text> | |
| 50 | - <rect x="370" y="140" width="280" height="130" rx="10" ry="10" fill="#15202b" stroke="#15202b" stroke-width="2"/> | |
| 51 | - <text x="510" y="163" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">bridge</text> | |
| 52 | - <text x="510" y="184" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">· WebSocket ⇄ ACP</text> | |
| 53 | - <text x="510" y="205" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">· Event broadcast</text> | |
| 54 | - <text x="510" y="226" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">· Permission routing</text> | |
| 55 | - <text x="510" y="247" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">· History replay</text> | |
| 56 | - <rect x="370" y="300" width="135" height="90" rx="10" ry="10" fill="#15202b" stroke="#15202b" stroke-width="2"/> | |
| 57 | - <text x="437.5" y="324" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">agent</text> | |
| 58 | - <text x="437.5" y="345" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">ACP session</text> | |
| 59 | - <text x="437.5" y="366" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">lifecycle</text> | |
| 60 | - <rect x="515" y="300" width="135" height="90" rx="10" ry="10" fill="#15202b" stroke="#15202b" stroke-width="2"/> | |
| 61 | - <text x="582.5" y="324" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">files</text> | |
| 62 | - <text x="582.5" y="345" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">Workspace</text> | |
| 63 | - <text x="582.5" y="366" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">file API</text> | |
| 64 | - <rect x="370" y="410" width="135" height="90" rx="10" ry="10" fill="#15202b" stroke="#15202b" stroke-width="2"/> | |
| 65 | - <text x="437.5" y="434" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">terminal</text> | |
| 66 | - <text x="437.5" y="455" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">PTY per</text> | |
| 67 | - <text x="437.5" y="476" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">connection</text> | |
| 68 | - <rect x="515" y="410" width="135" height="90" rx="10" ry="10" fill="#e8ebda" stroke="#15202b" stroke-width="2"/> | |
| 69 | - <text x="582.5" y="434" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#15202b">mockagent</text> | |
| 70 | - <text x="582.5" y="455" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#15202b">Demo agent</text> | |
| 71 | - <text x="582.5" y="476" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#15202b">(testing)</text> | |
| 72 | - <rect x="800" y="230" width="400" height="130" rx="10" ry="10" fill="#fdfdfb" stroke="#0062FF" stroke-width="2"/> | |
| 73 | - <text x="1000" y="253" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#0062FF">ACP Agent</text> | |
| 74 | - <text x="1000" y="274" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#0062FF">(claude-code-acp / Gemini CLI)</text> | |
| 75 | - <text x="1000" y="295" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#0062FF"></text> | |
| 76 | - <text x="1000" y="316" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#0062FF">JSON-RPC over stdio</text> | |
| 77 | - <text x="1000" y="337" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#0062FF">session_update · permission_request</text> | |
| 78 | - <rect x="20" y="560" width="1180" height="60" rx="10" ry="10" fill="#fdfdfb" stroke="#15202b" stroke-width="2" stroke-dasharray="6 5"/> | |
| 79 | - <text x="610" y="590" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="15" font-weight="normal" fill="#15202b">Go backend bridges browser WebSockets to ACP stdio, broadcasting agent updates to all connected browsers while routing permissions back to the waiting call.</text> | |
| 80 | -</svg> | |
| 1 | +<svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1182px" height="602px" viewBox="-0.5 -0.5 1182 602" content="<mxfile><diagram name="Ori Architecture" id="diagram-1">7Vpbc9o4FP41nkkfwsh38xgoSbsz3TIlO2mfOsIW4I2xvLIgsL9+JVvyTTYF1pBmJkPGsY6OZUnfp3MDzRyvdw8EJqsvOECRZoBgp5kfNcPQdXfI/nHJPpfYnpcLliQMhFIpmIX/IiEEQroJA5TWFCnGEQ2TutDHcYx8WpNBQvBLXW2Bo/pbE7hEimDmw0iVPoUBXcl1OcOy4xMKlyvxas9w8o41lMpiJekKBvilIjInmjkmGNP8br0bo4hvntyX/Ln7jt5iYgTF9JgHzPyBLYw2Ym0jvj2IaIYD14lmjjTDZNtujr4hyHbSALPpnZg63cv9IHgTB4gPqTNNSHwBmc7WM3pZhRTNEuhzyQsjBJOt6DoS2oswisY4wiQbylwE7DNn8pQS/IwqPbptAIP3LHBMu+Tyxa5si0mCYkQJmJGtrblbYgO3iFC0q4jE7j0gvEaU7JmK6JVA7uvNl5IWhWxVYYQuqQwFFZfFyCVa7EYA1g6epYD312fWHuN1gmO2pFQBURsb2shlOndLvmQDTGHMz2aX2hMmz2kG3S9V78OIaz0ShLqVvuAY+pjdTIKQYpVkheIjIuswhny1NzvKGoO/0w+X5B3y0DyAvfNOvxLvdPtY4tk9EM9WiLeiNGFWY9tiOGZcnErLwd4+yq73zAhfEM8CnaPxLCzPq+BpOcYvDYnXguewBzgdBc45c7vLA+f4Cc1n2H9G3IRoE0PzXM2zuFkZT7sfmmxzmzMnGAY+TGm36pQf/zQNccwajBU0jJfd2p/ClBkTvpkEJRHcv/Oqyiu9biisI4mlmz0wy1WYBXPH04Ay4w1IkYC80RuFC+Tvfe5f3oGVwJpu3QOYjgqsbtqXsRiegivbTaTGG5X4odGzyMOFu+nnd1BLUG3HroMKrgjqUAGVFlFYA73p4w++1BZvL1Ku7Bi/49p1WK1rHlZdV4DN7a1IApyIvWw0J3xAw1nyxo0fwU2Abn2Wut9CP/nQqtUq/GP29c/bb1M2K4CzcJBRIAhxq64w+D83SQApNweFS0+KAOAnQf9sEA8WXiPpBMAx7u9VOtXkV6eTBxpZp6nSyQKXcuq6ofDpged0c8giwjjIIjwePqZ5rJdXE8qQkYsplsGiZMe4Ghhm0R4QoQLI2VE8BrPJCDuDgvIlXIPhnvmVImasMCkVc5QD0RXXfIGh0PTZyIPXodlJOaZ9VG0jgOmqmHYPnGsknHabBdPbAkmnD8qpdSqdQQUiRhitvSaFGAPlDmFCV3iJmSeblNJRHdkKbOpmHgZMAmMdALATgRRviC/mLFZJIVkioSV8Al/NQZQIiiANt/UC5f/acrW6ZAzqqV8zH2vN6X8zHNAupN/F+Pz+Bz9AA9eofUzR+XEnjlfW2MtGzLbye7WRD2IC1xkaxdWVveUoWUsOcy4jnFdjhFr2MTkjEoLXSVYJ4KWdBimSSibf6CIoTZhVRm+UM/ZZJHFs02M5ubwO+yCJdT5JhHG/BQMArHruIU3P0TwSo09xmLltqYIXixRRhWjFJI7jnlqjsgZlyaCIIBsUQ9u8DA5u8sqQWkK+LNVaw8QWqhV6x3ntKviOCr51MvicjXXwwTng3xHCq2+FQsKpkLZwQ6ZFViOOtRvfVp2mz27yGVyUiWpNyx5o7aXP7sLVb2rhwMDwbFe3ymvF5OlHGryBNXSMyp9Zs4B9GLwWzruv5hXVWpgzqGS9dUaU2fHbIEQfLs/uA3JXhVzWNY61c4zcYDisGZBb+ywnd6qdcxv5uilcbZeda+obQ1u7up1Ty4HuoJaNHw73rh3VXcHVSsJdNBo/j2DKzxAOO1LHPqhfJ9gZ5JHTaXxBwCQ4eVvE6N2oVcnjnWrAgFU3X+ZZYZpCB93r+NpBDpGfAvFUG696NT2GWrBmiGQqn9mzX98WgYrQSnrPU2KpC3jSlmxxeKXgiTXLn7blxCh/IGhO/gM=</diagram></mxfile>"> | |
| 2 | + <defs/> | |
| 3 | + <g> | |
| 4 | + <rect x="1" y="1" width="220" height="110" rx="13.2" ry="13.2" fill="#fdfdfb" stroke="#15202b" stroke-width="2" pointer-events="all"/> | |
| 5 | + <g transform="translate(-0.5 -0.5)"> | |
| 6 | + <switch> | |
| 7 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | |
| 8 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 56px; margin-left: 2px;"> | |
| 9 | + <div data-drawio-colors="color: #15202b; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | |
| 10 | + <div style="display: inline-block; font-size: 17px; font-family: Helvetica; color: rgb(21, 32, 43); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> | |
| 11 | + Browser | |
| 12 | +React SPA | |
| 13 | + </div> | |
| 14 | + </div> | |
| 15 | + </div> | |
| 16 | + </foreignObject> | |
| 17 | + <text x="111" y="61" fill="#15202b" font-family="Helvetica" font-size="17px" text-anchor="middle"> | |
| 18 | + Browser... | |
| 19 | + </text> | |
| 20 | + </switch> | |
| 21 | + </g> | |
| 22 | + <rect x="1" y="131" width="220" height="150" rx="18" ry="18" fill="#e8ebda" stroke="#15202b" stroke-width="2" pointer-events="all"/> | |
| 23 | + <g transform="translate(-0.5 -0.5)"> | |
| 24 | + <switch> | |
| 25 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | |
| 26 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 206px; margin-left: 2px;"> | |
| 27 | + <div data-drawio-colors="color: #15202b; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | |
| 28 | + <div style="display: inline-block; font-size: 17px; font-family: Helvetica; color: rgb(21, 32, 43); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; overflow-wrap: normal;"> | |
| 29 | + UI Components | |
| 30 | +· Agent Panel | |
| 31 | +· Workspace Panel | |
| 32 | +· File Tree | |
| 33 | +· Monaco Editor | |
| 34 | +· Terminal (xterm.js) | |
| 35 | + </div> | |
| 36 | + </div> | |
| 37 | + </div> | |
| 38 | + </foreignObject> | |
| 39 | + <text x="111" y="211" fill="#15202b" font-family="Helvetica" font-size="17px" text-anchor="middle" font-weight="bold"> | |
| 40 | + UI Components... | |
| 41 | + </text> | |
| 42 | + </switch> | |
| 43 | + </g> | |
| 44 | + <rect x="443" y="1" width="280" height="90" rx="10.8" ry="10.8" fill="#15202b" stroke="#15202b" stroke-width="2" pointer-events="all"/> | |
| 45 | + <g transform="translate(-0.5 -0.5)"> | |
| 46 | + <switch> | |
| 47 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | |
| 48 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 278px; height: 1px; padding-top: 46px; margin-left: 444px;"> | |
| 49 | + <div data-drawio-colors="color: #fdfdfb; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | |
| 50 | + <div style="display: inline-block; font-size: 17px; font-family: Helvetica; color: rgb(253, 253, 251); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; overflow-wrap: normal;"> | |
| 51 | + httpserver | |
| 52 | +Serves SPA + /ws | |
| 53 | + </div> | |
| 54 | + </div> | |
| 55 | + </div> | |
| 56 | + </foreignObject> | |
| 57 | + <text x="583" y="51" fill="#fdfdfb" font-family="Helvetica" font-size="17px" text-anchor="middle" font-weight="bold"> | |
| 58 | + httpserver... | |
| 59 | + </text> | |
| 60 | + </switch> | |
| 61 | + </g> | |
| 62 | + <rect x="442" y="121" width="280" height="130" rx="15.6" ry="15.6" fill="#15202b" stroke="#15202b" stroke-width="2" pointer-events="all"/> | |
| 63 | + <g transform="translate(-0.5 -0.5)"> | |
| 64 | + <switch> | |
| 65 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | |
| 66 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 278px; height: 1px; padding-top: 186px; margin-left: 443px;"> | |
| 67 | + <div data-drawio-colors="color: #fdfdfb; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | |
| 68 | + <div style="display: inline-block; font-size: 17px; font-family: Helvetica; color: rgb(253, 253, 251); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; overflow-wrap: normal;"> | |
| 69 | + bridge | |
| 70 | +· WebSocket ⇄ ACP | |
| 71 | +· Event broadcast | |
| 72 | +· Permission routing | |
| 73 | +· History replay | |
| 74 | + </div> | |
| 75 | + </div> | |
| 76 | + </div> | |
| 77 | + </foreignObject> | |
| 78 | + <text x="582" y="191" fill="#fdfdfb" font-family="Helvetica" font-size="17px" text-anchor="middle" font-weight="bold"> | |
| 79 | + bridge... | |
| 80 | + </text> | |
| 81 | + </switch> | |
| 82 | + </g> | |
| 83 | + <rect x="351" y="341" width="135" height="90" rx="10.8" ry="10.8" fill="#15202b" stroke="#15202b" stroke-width="2" pointer-events="all"/> | |
| 84 | + <g transform="translate(-0.5 -0.5)"> | |
| 85 | + <switch> | |
| 86 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | |
| 87 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 133px; height: 1px; padding-top: 386px; margin-left: 352px;"> | |
| 88 | + <div data-drawio-colors="color: #fdfdfb; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | |
| 89 | + <div style="display: inline-block; font-size: 17px; font-family: Helvetica; color: rgb(253, 253, 251); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; overflow-wrap: normal;"> | |
| 90 | + agent | |
| 91 | +ACP session | |
| 92 | +lifecycle | |
| 93 | + </div> | |
| 94 | + </div> | |
| 95 | + </div> | |
| 96 | + </foreignObject> | |
| 97 | + <text x="419" y="391" fill="#fdfdfb" font-family="Helvetica" font-size="17px" text-anchor="middle" font-weight="bold"> | |
| 98 | + agent... | |
| 99 | + </text> | |
| 100 | + </switch> | |
| 101 | + </g> | |
| 102 | + <rect x="546" y="281" width="135" height="90" rx="10.8" ry="10.8" fill="#15202b" stroke="#15202b" stroke-width="2" pointer-events="all"/> | |
| 103 | + <g transform="translate(-0.5 -0.5)"> | |
| 104 | + <switch> | |
| 105 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | |
| 106 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 133px; height: 1px; padding-top: 326px; margin-left: 547px;"> | |
| 107 | + <div data-drawio-colors="color: #fdfdfb; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | |
| 108 | + <div style="display: inline-block; font-size: 17px; font-family: Helvetica; color: rgb(253, 253, 251); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; overflow-wrap: normal;"> | |
| 109 | + files | |
| 110 | +Workspace | |
| 111 | +file API | |
| 112 | + </div> | |
| 113 | + </div> | |
| 114 | + </div> | |
| 115 | + </foreignObject> | |
| 116 | + <text x="614" y="331" fill="#fdfdfb" font-family="Helvetica" font-size="17px" text-anchor="middle" font-weight="bold"> | |
| 117 | + files... | |
| 118 | + </text> | |
| 119 | + </switch> | |
| 120 | + </g> | |
| 121 | + <rect x="351" y="441" width="135" height="90" rx="10.8" ry="10.8" fill="#15202b" stroke="#15202b" stroke-width="2" pointer-events="all"/> | |
| 122 | + <g transform="translate(-0.5 -0.5)"> | |
| 123 | + <switch> | |
| 124 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | |
| 125 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 133px; height: 1px; padding-top: 486px; margin-left: 352px;"> | |
| 126 | + <div data-drawio-colors="color: #fdfdfb; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | |
| 127 | + <div style="display: inline-block; font-size: 17px; font-family: Helvetica; color: rgb(253, 253, 251); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; overflow-wrap: normal;"> | |
| 128 | + terminal | |
| 129 | +PTY per | |
| 130 | +connection | |
| 131 | + </div> | |
| 132 | + </div> | |
| 133 | + </div> | |
| 134 | + </foreignObject> | |
| 135 | + <text x="419" y="491" fill="#fdfdfb" font-family="Helvetica" font-size="17px" text-anchor="middle" font-weight="bold"> | |
| 136 | + terminal... | |
| 137 | + </text> | |
| 138 | + </switch> | |
| 139 | + </g> | |
| 140 | + <rect x="781" y="211" width="400" height="130" rx="15.6" ry="15.6" fill="#fdfdfb" stroke="#0062ff" stroke-width="2" pointer-events="all"/> | |
| 141 | + <g transform="translate(-0.5 -0.5)"> | |
| 142 | + <switch> | |
| 143 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | |
| 144 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 276px; margin-left: 782px;"> | |
| 145 | + <div data-drawio-colors="color: #0062FF; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | |
| 146 | + <div style="display: inline-block; font-size: 17px; font-family: Helvetica; color: rgb(0, 98, 255); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; overflow-wrap: normal;"> | |
| 147 | + ACP Agent | |
| 148 | + <br/> | |
| 149 | + (claude-code-acp) | |
| 150 | + <br/> | |
| 151 | + <br/> | |
| 152 | + JSON-RPC over stdio | |
| 153 | + <br/> | |
| 154 | + session_update · permission_request | |
| 155 | + </div> | |
| 156 | + </div> | |
| 157 | + </div> | |
| 158 | + </foreignObject> | |
| 159 | + <text x="981" y="281" fill="#0062FF" font-family="Helvetica" font-size="17px" text-anchor="middle" font-weight="bold"> | |
| 160 | + ACP Agent... | |
| 161 | + </text> | |
| 162 | + </switch> | |
| 163 | + </g> | |
| 164 | + <rect x="1" y="541" width="1180" height="60" rx="7.2" ry="7.2" fill="#fdfdfb" stroke="#15202b" stroke-width="2" stroke-dasharray="6 6" pointer-events="all"/> | |
| 165 | + <g transform="translate(-0.5 -0.5)"> | |
| 166 | + <switch> | |
| 167 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | |
| 168 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1178px; height: 1px; padding-top: 571px; margin-left: 2px;"> | |
| 169 | + <div data-drawio-colors="color: #15202b; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | |
| 170 | + <div style="display: inline-block; font-size: 15px; font-family: Helvetica; color: rgb(21, 32, 43); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> | |
| 171 | + Go backend bridges browser WebSockets to ACP stdio, broadcasting agent updates to all connected browsers while routing permissions back to the waiting call. | |
| 172 | + </div> | |
| 173 | + </div> | |
| 174 | + </div> | |
| 175 | + </foreignObject> | |
| 176 | + <text x="591" y="576" fill="#15202b" font-family="Helvetica" font-size="15px" text-anchor="middle"> | |
| 177 | + Go backend bridges browser WebSockets to ACP stdio, broadcasting agent updates to all connected browsers while routing permissions back to the waiting call. | |
| 178 | + </text> | |
| 179 | + </switch> | |
| 180 | + </g> | |
| 181 | + <path d="M 221 56 L 322 56 Q 332 56 332 51 L 332 48.5 Q 332 46 342 46 L 434.76 46" fill="none" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/> | |
| 182 | + <path d="M 440.76 46 L 432.76 50 L 434.76 46 L 432.76 42 Z" fill="#15202b" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> | |
| 183 | + <g transform="translate(-0.5 -0.5)"> | |
| 184 | + <switch> | |
| 185 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | |
| 186 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 51px; margin-left: 332px;"> | |
| 187 | + <div data-drawio-colors="color: #15202b; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | |
| 188 | + <div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(21, 32, 43); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> | |
| 189 | + 1. load SPA | |
| 190 | + </div> | |
| 191 | + </div> | |
| 192 | + </div> | |
| 193 | + </foreignObject> | |
| 194 | + <text x="332" y="55" fill="#15202b" font-family="Helvetica" font-size="14px" text-anchor="middle"> | |
| 195 | + 1. load SPA | |
| 196 | + </text> | |
| 197 | + </switch> | |
| 198 | + </g> | |
| 199 | + <path d="M 221 81 L 321.5 81 Q 331.5 81 331.5 91 L 331.5 151 Q 331.5 161 341.5 161 L 433.76 161" fill="none" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/> | |
| 200 | + <path d="M 439.76 161 L 431.76 165 L 433.76 161 L 431.76 157 Z" fill="#15202b" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> | |
| 201 | + <g transform="translate(-0.5 -0.5)"> | |
| 202 | + <switch> | |
| 203 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | |
| 204 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 122px; margin-left: 332px;"> | |
| 205 | + <div data-drawio-colors="color: #15202b; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | |
| 206 | + <div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(21, 32, 43); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> | |
| 207 | + 2. WebSocket | |
| 208 | +/ws | |
| 209 | + </div> | |
| 210 | + </div> | |
| 211 | + </div> | |
| 212 | + </foreignObject> | |
| 213 | + <text x="332" y="126" fill="#15202b" font-family="Helvetica" font-size="14px" text-anchor="middle"> | |
| 214 | + 2. WebSocket... | |
| 215 | + </text> | |
| 216 | + </switch> | |
| 217 | + </g> | |
| 218 | + <path d="M 221 206 L 433.76 206" fill="none" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/> | |
| 219 | + <path d="M 439.76 206 L 431.76 210 L 433.76 206 L 431.76 202 Z" fill="#15202b" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> | |
| 220 | + <g transform="translate(-0.5 -0.5)"> | |
| 221 | + <switch> | |
| 222 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | |
| 223 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 181px; margin-left: 331px;"> | |
| 224 | + <div data-drawio-colors="color: #15202b; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | |
| 225 | + <div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(21, 32, 43); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> | |
| 226 | + 3. prompt + | |
| 227 | +permission | |
| 228 | +responses | |
| 229 | + </div> | |
| 230 | + </div> | |
| 231 | + </div> | |
| 232 | + </foreignObject> | |
| 233 | + <text x="331" y="185" fill="#15202b" font-family="Helvetica" font-size="14px" text-anchor="middle"> | |
| 234 | + 3. prompt +... | |
| 235 | + </text> | |
| 236 | + </switch> | |
| 237 | + </g> | |
| 238 | + <path d="M 442 231 L 331 231 Q 321 231 311 231 L 229.24 231" fill="none" stroke="#0062ff" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="stroke"/> | |
| 239 | + <path d="M 223.24 231 L 231.24 227 L 229.24 231 L 231.24 235 Z" fill="#0062ff" stroke="#0062ff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> | |
| 240 | + <g transform="translate(-0.5 -0.5)"> | |
| 241 | + <switch> | |
| 242 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | |
| 243 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 251px; margin-left: 374px;"> | |
| 244 | + <div data-drawio-colors="color: #0062FF; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | |
| 245 | + <div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(0, 98, 255); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> | |
| 246 | + 4. session_update | |
| 247 | +events (replay) | |
| 248 | + </div> | |
| 249 | + </div> | |
| 250 | + </div> | |
| 251 | + </foreignObject> | |
| 252 | + <text x="374" y="255" fill="#0062FF" font-family="Helvetica" font-size="14px" text-anchor="middle"> | |
| 253 | + 4. session_update... | |
| 254 | + </text> | |
| 255 | + </switch> | |
| 256 | + </g> | |
| 257 | + <path d="M 522 251 L 522 286 Q 522 296 512 296 L 428 296 Q 418 296 418 306 L 418 332.76" fill="none" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/> | |
| 258 | + <path d="M 418 338.76 L 414 330.76 L 418 332.76 L 422 330.76 Z" fill="#15202b" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> | |
| 259 | + <g transform="translate(-0.5 -0.5)"> | |
| 260 | + <switch> | |
| 261 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | |
| 262 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 296px; margin-left: 470px;"> | |
| 263 | + <div data-drawio-colors="color: #15202b; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | |
| 264 | + <div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(21, 32, 43); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> | |
| 265 | + 5. ACP | |
| 266 | +lifecycle | |
| 267 | + </div> | |
| 268 | + </div> | |
| 269 | + </div> | |
| 270 | + </foreignObject> | |
| 271 | + <text x="470" y="300" fill="#15202b" font-family="Helvetica" font-size="14px" text-anchor="middle"> | |
| 272 | + 5. ACP... | |
| 273 | + </text> | |
| 274 | + </switch> | |
| 275 | + </g> | |
| 276 | + <path d="M 486 386 L 486 336 Q 486 326 496 326 L 671 326 Q 681 326 681 316 L 681 286 Q 681 276 691 276 L 772.76 276" fill="none" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/> | |
| 277 | + <path d="M 778.76 276 L 770.76 280 L 772.76 276 L 770.76 272 Z" fill="#15202b" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> | |
| 278 | + <g transform="translate(-0.5 -0.5)"> | |
| 279 | + <switch> | |
| 280 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | |
| 281 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 381px; margin-left: 671px;"> | |
| 282 | + <div data-drawio-colors="color: #15202b; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | |
| 283 | + <div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(21, 32, 43); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> | |
| 284 | + 6. stdio | |
| 285 | +JSON-RPC | |
| 286 | + </div> | |
| 287 | + </div> | |
| 288 | + </div> | |
| 289 | + </foreignObject> | |
| 290 | + <text x="671" y="385" fill="#15202b" font-family="Helvetica" font-size="14px" text-anchor="middle"> | |
| 291 | + 6. stdio... | |
| 292 | + </text> | |
| 293 | + </switch> | |
| 294 | + </g> | |
| 295 | + <path d="M 981 211 L 981 191 Q 981 181 971 181 L 730.24 181" fill="none" stroke="#0062ff" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="stroke"/> | |
| 296 | + <path d="M 724.24 181 L 732.24 177 L 730.24 181 L 732.24 185 Z" fill="#0062ff" stroke="#0062ff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> | |
| 297 | + <g transform="translate(-0.5 -0.5)"> | |
| 298 | + <switch> | |
| 299 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | |
| 300 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 181px; margin-left: 866px;"> | |
| 301 | + <div data-drawio-colors="color: #0062FF; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | |
| 302 | + <div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(0, 98, 255); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> | |
| 303 | + 7. updates + | |
| 304 | +permissions | |
| 305 | + </div> | |
| 306 | + </div> | |
| 307 | + </div> | |
| 308 | + </foreignObject> | |
| 309 | + <text x="866" y="185" fill="#0062FF" font-family="Helvetica" font-size="14px" text-anchor="middle"> | |
| 310 | + 7. updates +... | |
| 311 | + </text> | |
| 312 | + </switch> | |
| 313 | + </g> | |
| 314 | + <path d="M 166 281 L 346 281 Q 356 281 356 291 L 356 316 Q 356 326 366 326 L 537.76 326" fill="none" stroke="#0062ff" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="stroke"/> | |
| 315 | + <path d="M 543.76 326 L 535.76 330 L 537.76 326 L 535.76 322 Z" fill="#0062ff" stroke="#0062ff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> | |
| 316 | + <g transform="translate(-0.5 -0.5)"> | |
| 317 | + <switch> | |
| 318 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | |
| 319 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 312px; margin-left: 326px;"> | |
| 320 | + <div data-drawio-colors="color: #0062FF; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | |
| 321 | + <div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(0, 98, 255); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> | |
| 322 | + file ops | |
| 323 | + </div> | |
| 324 | + </div> | |
| 325 | + </div> | |
| 326 | + </foreignObject> | |
| 327 | + <text x="326" y="316" fill="#0062FF" font-family="Helvetica" font-size="14px" text-anchor="middle"> | |
| 328 | + file ops | |
| 329 | + </text> | |
| 330 | + </switch> | |
| 331 | + </g> | |
| 332 | + <path d="M 111 281 L 111 476 Q 111 486 121 486 L 342.76 486" fill="none" stroke="#0062ff" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="stroke"/> | |
| 333 | + <path d="M 348.76 486 L 340.76 490 L 342.76 486 L 340.76 482 Z" fill="#0062ff" stroke="#0062ff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> | |
| 334 | + <g transform="translate(-0.5 -0.5)"> | |
| 335 | + <switch> | |
| 336 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | |
| 337 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 486px; margin-left: 129px;"> | |
| 338 | + <div data-drawio-colors="color: #0062FF; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | |
| 339 | + <div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(0, 98, 255); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> | |
| 340 | + shell I/O | |
| 341 | + </div> | |
| 342 | + </div> | |
| 343 | + </div> | |
| 344 | + </foreignObject> | |
| 345 | + <text x="129" y="490" fill="#0062FF" font-family="Helvetica" font-size="14px" text-anchor="middle"> | |
| 346 | + shell I/O | |
| 347 | + </text> | |
| 348 | + </switch> | |
| 349 | + </g> | |
| 350 | + </g> | |
| 351 | + <switch> | |
| 352 | + <g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/> | |
| 353 | + <a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"> | |
| 354 | + <text text-anchor="middle" font-size="10px" x="50%" y="100%"> | |
| 355 | + Text is not SVG - cannot display | |
| 356 | + </text> | |
| 357 | + </a> | |
| 358 | + </switch> | |
| 359 | +</svg> | |
| \ No newline at end of file | ||
| @@ -1,80 +1,359 @@ | |||
| 1 | -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1220" height="640" viewBox="0 0 1220 640" content="<mxfile host="Electron" agent="make-diagram.mjs" type="device"><diagram name="Ori Architecture" id="diagram-1"><mxGraphModel dx="1000" dy="600" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="826" math="0" shadow="0"><root><mxCell id="0"/><mxCell id="1" parent="0"/><mxCell id="3" value="Browser&amp;#10;React SPA" style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#fdfdfb;strokeColor=#15202b;fontColor=#15202b;fontSize=17;fontStyle=0;strokeWidth=2;" vertex="1" parent="1"><mxGeometry x="20" y="20" width="220" height="110" as="geometry"/></mxCell><mxCell id="4" value="UI Components&amp;#10;· Agent Panel&amp;#10;· Workspace Panel&amp;#10;· File Tree&amp;#10;· Monaco Editor&amp;#10;· Terminal (xterm.js)" style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#e8ebda;strokeColor=#15202b;fontColor=#15202b;fontSize=17;fontStyle=1;strokeWidth=2;" vertex="1" parent="1"><mxGeometry x="20" y="150" width="220" height="150" as="geometry"/></mxCell><mxCell id="5" value="httpserver&amp;#10;Serves SPA + /ws" style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#15202b;strokeColor=#15202b;fontColor=#fdfdfb;fontSize=17;fontStyle=1;strokeWidth=2;" vertex="1" parent="1"><mxGeometry x="370" y="20" width="280" height="90" as="geometry"/></mxCell><mxCell id="6" value="bridge&amp;#10;· WebSocket ⇄ ACP&amp;#10;· Event broadcast&amp;#10;· Permission routing&amp;#10;· History replay" style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#15202b;strokeColor=#15202b;fontColor=#fdfdfb;fontSize=17;fontStyle=1;strokeWidth=2;" vertex="1" parent="1"><mxGeometry x="370" y="140" width="280" height="130" as="geometry"/></mxCell><mxCell id="7" value="agent&amp;#10;ACP session&amp;#10;lifecycle" style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#15202b;strokeColor=#15202b;fontColor=#fdfdfb;fontSize=17;fontStyle=1;strokeWidth=2;" vertex="1" parent="1"><mxGeometry x="370" y="300" width="135" height="90" as="geometry"/></mxCell><mxCell id="8" value="files&amp;#10;Workspace&amp;#10;file API" style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#15202b;strokeColor=#15202b;fontColor=#fdfdfb;fontSize=17;fontStyle=1;strokeWidth=2;" vertex="1" parent="1"><mxGeometry x="515" y="300" width="135" height="90" as="geometry"/></mxCell><mxCell id="9" value="terminal&amp;#10;PTY per&amp;#10;connection" style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#15202b;strokeColor=#15202b;fontColor=#fdfdfb;fontSize=17;fontStyle=1;strokeWidth=2;" vertex="1" parent="1"><mxGeometry x="370" y="410" width="135" height="90" as="geometry"/></mxCell><mxCell id="10" value="mockagent&amp;#10;Demo agent&amp;#10;(testing)" style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#e8ebda;strokeColor=#15202b;fontColor=#15202b;fontSize=17;fontStyle=1;strokeWidth=2;" vertex="1" parent="1"><mxGeometry x="515" y="410" width="135" height="90" as="geometry"/></mxCell><mxCell id="11" value="ACP Agent&amp;#10;(claude-code-acp / Gemini CLI)&amp;#10;&amp;#10;JSON-RPC over stdio&amp;#10;session_update · permission_request" style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#fdfdfb;strokeColor=#0062FF;fontColor=#0062FF;fontSize=17;fontStyle=1;strokeWidth=2;" vertex="1" parent="1"><mxGeometry x="800" y="230" width="400" height="130" as="geometry"/></mxCell><mxCell id="12" value="Go backend bridges browser WebSockets to ACP stdio, broadcasting agent updates to all connected browsers while routing permissions back to the waiting call." style="rounded=1;arcSize=12;whiteSpace=wrap;html=1;fillColor=#fdfdfb;strokeColor=#15202b;fontColor=#15202b;fontSize=15;fontStyle=0;strokeWidth=2;dashed=1;" vertex="1" parent="1"><mxGeometry x="20" y="560" width="1180" height="60" as="geometry"/></mxCell><mxCell id="13" value="1. load SPA" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeWidth=2;strokeColor=#15202b;fontSize=14;fontColor=#15202b;" edge="1" parent="1" source="3" target="5"><mxGeometry relative="1" as="geometry"></mxGeometry></mxCell><mxCell id="14" value="2. WebSocket&amp;#10;/ws" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeWidth=2;strokeColor=#15202b;fontSize=14;fontColor=#15202b;exitX=1;exitY=0.7272727272727273;exitDx=0;exitDy=0;entryX=0;entryY=0.3076923076923077;entryDx=0;entryDy=0;" edge="1" parent="1" source="3" target="6"><mxGeometry relative="1" as="geometry"></mxGeometry></mxCell><mxCell id="15" value="3. prompt +&amp;#10;permission&amp;#10;responses" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeWidth=2;strokeColor=#15202b;fontSize=14;fontColor=#15202b;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.6538461538461539;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="6"><mxGeometry relative="1" as="geometry"></mxGeometry></mxCell><mxCell id="16" value="4. session_update&amp;#10;events (replay)" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeWidth=2;strokeColor=#0062FF;fontSize=14;fontColor=#0062FF;dashed=1;" edge="1" parent="1" source="6" target="4"><mxGeometry relative="1" as="geometry"><Array as="points"><mxPoint x="310" y="230"/><mxPoint x="280" y="230"/></Array></mxGeometry></mxCell><mxCell id="17" value="5. ACP&amp;#10;lifecycle" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeWidth=2;strokeColor=#15202b;fontSize=14;fontColor=#15202b;exitX=0.2857142857142857;exitY=1;exitDx=0;exitDy=0;entryX=0.4962962962962963;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="7"><mxGeometry relative="1" as="geometry"></mxGeometry></mxCell><mxCell id="18" value="6. stdio&amp;#10;JSON-RPC" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeWidth=2;strokeColor=#15202b;fontSize=14;fontColor=#15202b;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="7" target="11"><mxGeometry relative="1" as="geometry"></mxGeometry></mxCell><mxCell id="19" value="7. updates +&amp;#10;permissions" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeWidth=2;strokeColor=#0062FF;fontSize=14;fontColor=#0062FF;dashed=1;" edge="1" parent="1" source="11" target="6"><mxGeometry relative="1" as="geometry"><Array as="points"><mxPoint x="720" y="200"/><mxPoint x="650" y="200"/></Array></mxGeometry></mxCell><mxCell id="20" value="file ops" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeWidth=2;strokeColor=#0062FF;fontSize=14;fontColor=#0062FF;dashed=1;exitX=1;exitY=0.8666666666666667;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="8"><mxGeometry relative="1" as="geometry"></mxGeometry></mxCell><mxCell id="21" value="shell I/O" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeWidth=2;strokeColor=#0062FF;fontSize=14;fontColor=#0062FF;dashed=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="9"><mxGeometry relative="1" as="geometry"></mxGeometry></mxCell></root></mxGraphModel></diagram></mxfile>"> | 1 | +<svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1182px" height="602px" viewBox="-0.5 -0.5 1182 602" content="<mxfile><diagram name="Ori Architecture" id="diagram-1">7Vpbc9o4FP41nkkfwsh38xgoSbsz3TIlO2mfOsIW4I2xvLIgsL9+JVvyTTYF1pBmJkPGsY6OZUnfp3MDzRyvdw8EJqsvOECRZoBgp5kfNcPQdXfI/nHJPpfYnpcLliQMhFIpmIX/IiEEQroJA5TWFCnGEQ2TutDHcYx8WpNBQvBLXW2Bo/pbE7hEimDmw0iVPoUBXcl1OcOy4xMKlyvxas9w8o41lMpiJekKBvilIjInmjkmGNP8br0bo4hvntyX/Ln7jt5iYgTF9JgHzPyBLYw2Ym0jvj2IaIYD14lmjjTDZNtujr4hyHbSALPpnZg63cv9IHgTB4gPqTNNSHwBmc7WM3pZhRTNEuhzyQsjBJOt6DoS2oswisY4wiQbylwE7DNn8pQS/IwqPbptAIP3LHBMu+Tyxa5si0mCYkQJmJGtrblbYgO3iFC0q4jE7j0gvEaU7JmK6JVA7uvNl5IWhWxVYYQuqQwFFZfFyCVa7EYA1g6epYD312fWHuN1gmO2pFQBURsb2shlOndLvmQDTGHMz2aX2hMmz2kG3S9V78OIaz0ShLqVvuAY+pjdTIKQYpVkheIjIuswhny1NzvKGoO/0w+X5B3y0DyAvfNOvxLvdPtY4tk9EM9WiLeiNGFWY9tiOGZcnErLwd4+yq73zAhfEM8CnaPxLCzPq+BpOcYvDYnXguewBzgdBc45c7vLA+f4Cc1n2H9G3IRoE0PzXM2zuFkZT7sfmmxzmzMnGAY+TGm36pQf/zQNccwajBU0jJfd2p/ClBkTvpkEJRHcv/Oqyiu9biisI4mlmz0wy1WYBXPH04Ay4w1IkYC80RuFC+Tvfe5f3oGVwJpu3QOYjgqsbtqXsRiegivbTaTGG5X4odGzyMOFu+nnd1BLUG3HroMKrgjqUAGVFlFYA73p4w++1BZvL1Ku7Bi/49p1WK1rHlZdV4DN7a1IApyIvWw0J3xAw1nyxo0fwU2Abn2Wut9CP/nQqtUq/GP29c/bb1M2K4CzcJBRIAhxq64w+D83SQApNweFS0+KAOAnQf9sEA8WXiPpBMAx7u9VOtXkV6eTBxpZp6nSyQKXcuq6ofDpged0c8giwjjIIjwePqZ5rJdXE8qQkYsplsGiZMe4Ghhm0R4QoQLI2VE8BrPJCDuDgvIlXIPhnvmVImasMCkVc5QD0RXXfIGh0PTZyIPXodlJOaZ9VG0jgOmqmHYPnGsknHabBdPbAkmnD8qpdSqdQQUiRhitvSaFGAPlDmFCV3iJmSeblNJRHdkKbOpmHgZMAmMdALATgRRviC/mLFZJIVkioSV8Al/NQZQIiiANt/UC5f/acrW6ZAzqqV8zH2vN6X8zHNAupN/F+Pz+Bz9AA9eofUzR+XEnjlfW2MtGzLbye7WRD2IC1xkaxdWVveUoWUsOcy4jnFdjhFr2MTkjEoLXSVYJ4KWdBimSSibf6CIoTZhVRm+UM/ZZJHFs02M5ubwO+yCJdT5JhHG/BQMArHruIU3P0TwSo09xmLltqYIXixRRhWjFJI7jnlqjsgZlyaCIIBsUQ9u8DA5u8sqQWkK+LNVaw8QWqhV6x3ntKviOCr51MvicjXXwwTng3xHCq2+FQsKpkLZwQ6ZFViOOtRvfVp2mz27yGVyUiWpNyx5o7aXP7sLVb2rhwMDwbFe3ymvF5OlHGryBNXSMyp9Zs4B9GLwWzruv5hXVWpgzqGS9dUaU2fHbIEQfLs/uA3JXhVzWNY61c4zcYDisGZBb+ywnd6qdcxv5uilcbZeda+obQ1u7up1Ty4HuoJaNHw73rh3VXcHVSsJdNBo/j2DKzxAOO1LHPqhfJ9gZ5JHTaXxBwCQ4eVvE6N2oVcnjnWrAgFU3X+ZZYZpCB93r+NpBDpGfAvFUG696NT2GWrBmiGQqn9mzX98WgYrQSnrPU2KpC3jSlmxxeKXgiTXLn7blxCh/IGhO/gM=</diagram></mxfile>"> |
| 2 | - <defs><marker id="arrow-dark" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M 0 0 L 10 5 L 0 10 z" fill="#15202b"/></marker><marker id="arrow-blue" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M 0 0 L 10 5 L 0 10 z" fill="#0062FF"/></marker></defs> | 2 | + <defs/> |
| 3 | - <path d="M 242 75 L 364 75" fill="none" stroke="#15202b" stroke-width="2" marker-end="url(#arrow-dark)"/> | 3 | + <g> |
| 4 | - <rect x="254.2" y="62.5" width="97.6" height="25" rx="4" fill="#fdfdfb" opacity="0.92"/> | 4 | + <rect x="1" y="1" width="220" height="110" rx="13.2" ry="13.2" fill="#fdfdfb" stroke="#15202b" stroke-width="2" pointer-events="all"/> |
| 5 | - <text x="303" y="75" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">1. load SPA</text> | 5 | + <g transform="translate(-0.5 -0.5)"> |
| 6 | - <path d="M 242 100 L 364 180" fill="none" stroke="#15202b" stroke-width="2" marker-end="url(#arrow-dark)"/> | 6 | + <switch> |
| 7 | - <rect x="250.4" y="119" width="105.19999999999999" height="42" rx="4" fill="#fdfdfb" opacity="0.92"/> | 7 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> |
| 8 | - <text x="303" y="131.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">2. WebSocket</text> | 8 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 56px; margin-left: 2px;"> |
| 9 | - <text x="303" y="148.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">/ws</text> | 9 | + <div data-drawio-colors="color: #15202b; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> |
| 10 | - <path d="M 242 225 L 364 225" fill="none" stroke="#15202b" stroke-width="2" marker-end="url(#arrow-dark)"/> | 10 | + <div style="display: inline-block; font-size: 17px; font-family: Helvetica; color: rgb(21, 32, 43); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> |
| 11 | - <rect x="254.2" y="195.5" width="97.6" height="59" rx="4" fill="#fdfdfb" opacity="0.92"/> | 11 | + Browser |
| 12 | - <text x="303" y="208" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">3. prompt +</text> | 12 | +React SPA |
| 13 | - <text x="303" y="225" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">permission</text> | 13 | + </div> |
| 14 | - <text x="303" y="242" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">responses</text> | 14 | + </div> |
| 15 | - <path d="M 368 205 L 310 230 L 280 230 L 246 225" fill="none" stroke="#0062FF" stroke-width="2" stroke-dasharray="6 5" marker-end="url(#arrow-blue)"/> | 15 | + </div> |
| 16 | - <rect x="267.4" y="196.5" width="143.2" height="42" rx="4" fill="#fdfdfb" opacity="0.92"/> | 16 | + </foreignObject> |
| 17 | - <text x="339" y="209" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#0062FF">4. session_update</text> | 17 | + <text x="111" y="61" fill="#15202b" font-family="Helvetica" font-size="17px" text-anchor="middle"> |
| 18 | - <text x="339" y="226" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#0062FF">events (replay)</text> | 18 | + Browser... |
| 19 | - <path d="M 450 272 L 437 294" fill="none" stroke="#15202b" stroke-width="2" marker-end="url(#arrow-dark)"/> | 19 | + </text> |
| 20 | - <rect x="402.3" y="262" width="82.39999999999999" height="42" rx="4" fill="#fdfdfb" opacity="0.92"/> | 20 | + </switch> |
| 21 | - <text x="443.5" y="274.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">5. ACP</text> | 21 | + </g> |
| 22 | - <text x="443.5" y="291.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">lifecycle</text> | 22 | + <rect x="1" y="131" width="220" height="150" rx="18" ry="18" fill="#e8ebda" stroke="#15202b" stroke-width="2" pointer-events="all"/> |
| 23 | - <path d="M 507 345 L 794 295" fill="none" stroke="#15202b" stroke-width="2" marker-end="url(#arrow-dark)"/> | 23 | + <g transform="translate(-0.5 -0.5)"> |
| 24 | - <rect x="613.1" y="299" width="74.8" height="42" rx="4" fill="#fdfdfb" opacity="0.92"/> | 24 | + <switch> |
| 25 | - <text x="650.5" y="311.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">6. stdio</text> | 25 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> |
| 26 | - <text x="650.5" y="328.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#15202b">JSON-RPC</text> | 26 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 206px; margin-left: 2px;"> |
| 27 | - <path d="M 798 295 L 720 200 L 650 200 L 656 205" fill="none" stroke="#0062FF" stroke-width="2" stroke-dasharray="6 5" marker-end="url(#arrow-blue)"/> | 27 | + <div data-drawio-colors="color: #15202b; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> |
| 28 | - <rect x="706.4" y="226.5" width="105.19999999999999" height="42" rx="4" fill="#fdfdfb" opacity="0.92"/> | 28 | + <div style="display: inline-block; font-size: 17px; font-family: Helvetica; color: rgb(21, 32, 43); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; overflow-wrap: normal;"> |
| 29 | - <text x="759" y="239" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#0062FF">7. updates +</text> | 29 | + UI Components |
| 30 | - <text x="759" y="256" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#0062FF">permissions</text> | 30 | +· Agent Panel |
| 31 | - <path d="M 242 280 L 509 345" fill="none" stroke="#0062FF" stroke-width="2" stroke-dasharray="6 5" marker-end="url(#arrow-blue)"/> | 31 | +· Workspace Panel |
| 32 | - <rect x="338.1" y="300" width="74.8" height="25" rx="4" fill="#fdfdfb" opacity="0.92"/> | 32 | +· File Tree |
| 33 | - <text x="375.5" y="312.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#0062FF">file ops</text> | 33 | +· Monaco Editor |
| 34 | - <path d="M 130 302 L 364 455" fill="none" stroke="#0062FF" stroke-width="2" stroke-dasharray="6 5" marker-end="url(#arrow-blue)"/> | 34 | +· Terminal (xterm.js) |
| 35 | - <rect x="205.8" y="366" width="82.39999999999999" height="25" rx="4" fill="#fdfdfb" opacity="0.92"/> | 35 | + </div> |
| 36 | - <text x="247" y="378.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="14" fill="#0062FF">shell I/O</text> | 36 | + </div> |
| 37 | - <rect x="20" y="20" width="220" height="110" rx="10" ry="10" fill="#fdfdfb" stroke="#15202b" stroke-width="2"/> | 37 | + </div> |
| 38 | - <text x="130" y="64.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="normal" fill="#15202b">Browser</text> | 38 | + </foreignObject> |
| 39 | - <text x="130" y="85.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="normal" fill="#15202b">React SPA</text> | 39 | + <text x="111" y="211" fill="#15202b" font-family="Helvetica" font-size="17px" text-anchor="middle" font-weight="bold"> |
| 40 | - <rect x="20" y="150" width="220" height="150" rx="10" ry="10" fill="#e8ebda" stroke="#15202b" stroke-width="2"/> | 40 | + UI Components... |
| 41 | - <text x="130" y="172.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#15202b">UI Components</text> | 41 | + </text> |
| 42 | - <text x="130" y="193.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#15202b">· Agent Panel</text> | 42 | + </switch> |
| 43 | - <text x="130" y="214.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#15202b">· Workspace Panel</text> | 43 | + </g> |
| 44 | - <text x="130" y="235.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#15202b">· File Tree</text> | 44 | + <rect x="443" y="1" width="280" height="90" rx="10.8" ry="10.8" fill="#15202b" stroke="#15202b" stroke-width="2" pointer-events="all"/> |
| 45 | - <text x="130" y="256.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#15202b">· Monaco Editor</text> | 45 | + <g transform="translate(-0.5 -0.5)"> |
| 46 | - <text x="130" y="277.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#15202b">· Terminal (xterm.js)</text> | 46 | + <switch> |
| 47 | - <rect x="370" y="20" width="280" height="90" rx="10" ry="10" fill="#15202b" stroke="#15202b" stroke-width="2"/> | 47 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> |
| 48 | - <text x="510" y="54.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">httpserver</text> | 48 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 278px; height: 1px; padding-top: 46px; margin-left: 444px;"> |
| 49 | - <text x="510" y="75.5" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">Serves SPA + /ws</text> | 49 | + <div data-drawio-colors="color: #fdfdfb; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> |
| 50 | - <rect x="370" y="140" width="280" height="130" rx="10" ry="10" fill="#15202b" stroke="#15202b" stroke-width="2"/> | 50 | + <div style="display: inline-block; font-size: 17px; font-family: Helvetica; color: rgb(253, 253, 251); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; overflow-wrap: normal;"> |
| 51 | - <text x="510" y="163" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">bridge</text> | 51 | + httpserver |
| 52 | - <text x="510" y="184" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">· WebSocket ⇄ ACP</text> | 52 | +Serves SPA + /ws |
| 53 | - <text x="510" y="205" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">· Event broadcast</text> | 53 | + </div> |
| 54 | - <text x="510" y="226" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">· Permission routing</text> | 54 | + </div> |
| 55 | - <text x="510" y="247" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">· History replay</text> | 55 | + </div> |
| 56 | - <rect x="370" y="300" width="135" height="90" rx="10" ry="10" fill="#15202b" stroke="#15202b" stroke-width="2"/> | 56 | + </foreignObject> |
| 57 | - <text x="437.5" y="324" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">agent</text> | 57 | + <text x="583" y="51" fill="#fdfdfb" font-family="Helvetica" font-size="17px" text-anchor="middle" font-weight="bold"> |
| 58 | - <text x="437.5" y="345" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">ACP session</text> | 58 | + httpserver... |
| 59 | - <text x="437.5" y="366" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">lifecycle</text> | 59 | + </text> |
| 60 | - <rect x="515" y="300" width="135" height="90" rx="10" ry="10" fill="#15202b" stroke="#15202b" stroke-width="2"/> | 60 | + </switch> |
| 61 | - <text x="582.5" y="324" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">files</text> | 61 | + </g> |
| 62 | - <text x="582.5" y="345" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">Workspace</text> | 62 | + <rect x="442" y="121" width="280" height="130" rx="15.6" ry="15.6" fill="#15202b" stroke="#15202b" stroke-width="2" pointer-events="all"/> |
| 63 | - <text x="582.5" y="366" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">file API</text> | 63 | + <g transform="translate(-0.5 -0.5)"> |
| 64 | - <rect x="370" y="410" width="135" height="90" rx="10" ry="10" fill="#15202b" stroke="#15202b" stroke-width="2"/> | 64 | + <switch> |
| 65 | - <text x="437.5" y="434" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">terminal</text> | 65 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> |
| 66 | - <text x="437.5" y="455" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">PTY per</text> | 66 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 278px; height: 1px; padding-top: 186px; margin-left: 443px;"> |
| 67 | - <text x="437.5" y="476" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#fdfdfb">connection</text> | 67 | + <div data-drawio-colors="color: #fdfdfb; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> |
| 68 | - <rect x="515" y="410" width="135" height="90" rx="10" ry="10" fill="#e8ebda" stroke="#15202b" stroke-width="2"/> | 68 | + <div style="display: inline-block; font-size: 17px; font-family: Helvetica; color: rgb(253, 253, 251); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; overflow-wrap: normal;"> |
| 69 | - <text x="582.5" y="434" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#15202b">mockagent</text> | 69 | + bridge |
| 70 | - <text x="582.5" y="455" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#15202b">Demo agent</text> | 70 | +· WebSocket ⇄ ACP |
| 71 | - <text x="582.5" y="476" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#15202b">(testing)</text> | 71 | +· Event broadcast |
| 72 | - <rect x="800" y="230" width="400" height="130" rx="10" ry="10" fill="#fdfdfb" stroke="#0062FF" stroke-width="2"/> | 72 | +· Permission routing |
| 73 | - <text x="1000" y="253" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#0062FF">ACP Agent</text> | 73 | +· History replay |
| 74 | - <text x="1000" y="274" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#0062FF">(claude-code-acp / Gemini CLI)</text> | 74 | + </div> |
| 75 | - <text x="1000" y="295" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#0062FF"></text> | 75 | + </div> |
| 76 | - <text x="1000" y="316" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#0062FF">JSON-RPC over stdio</text> | 76 | + </div> |
| 77 | - <text x="1000" y="337" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="17" font-weight="bold" fill="#0062FF">session_update · permission_request</text> | 77 | + </foreignObject> |
| 78 | - <rect x="20" y="560" width="1180" height="60" rx="10" ry="10" fill="#fdfdfb" stroke="#15202b" stroke-width="2" stroke-dasharray="6 5"/> | 78 | + <text x="582" y="191" fill="#fdfdfb" font-family="Helvetica" font-size="17px" text-anchor="middle" font-weight="bold"> |
| 79 | - <text x="610" y="590" text-anchor="middle" dominant-baseline="central" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="15" font-weight="normal" fill="#15202b">Go backend bridges browser WebSockets to ACP stdio, broadcasting agent updates to all connected browsers while routing permissions back to the waiting call.</text> | 79 | + bridge... |
| 80 | -</svg> | 80 | + </text> |
| 81 | + </switch> | ||
| 82 | + </g> | ||
| 83 | + <rect x="351" y="341" width="135" height="90" rx="10.8" ry="10.8" fill="#15202b" stroke="#15202b" stroke-width="2" pointer-events="all"/> | ||
| 84 | + <g transform="translate(-0.5 -0.5)"> | ||
| 85 | + <switch> | ||
| 86 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | ||
| 87 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 133px; height: 1px; padding-top: 386px; margin-left: 352px;"> | ||
| 88 | + <div data-drawio-colors="color: #fdfdfb; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | ||
| 89 | + <div style="display: inline-block; font-size: 17px; font-family: Helvetica; color: rgb(253, 253, 251); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; overflow-wrap: normal;"> | ||
| 90 | + agent | ||
| 91 | +ACP session | ||
| 92 | +lifecycle | ||
| 93 | + </div> | ||
| 94 | + </div> | ||
| 95 | + </div> | ||
| 96 | + </foreignObject> | ||
| 97 | + <text x="419" y="391" fill="#fdfdfb" font-family="Helvetica" font-size="17px" text-anchor="middle" font-weight="bold"> | ||
| 98 | + agent... | ||
| 99 | + </text> | ||
| 100 | + </switch> | ||
| 101 | + </g> | ||
| 102 | + <rect x="546" y="281" width="135" height="90" rx="10.8" ry="10.8" fill="#15202b" stroke="#15202b" stroke-width="2" pointer-events="all"/> | ||
| 103 | + <g transform="translate(-0.5 -0.5)"> | ||
| 104 | + <switch> | ||
| 105 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | ||
| 106 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 133px; height: 1px; padding-top: 326px; margin-left: 547px;"> | ||
| 107 | + <div data-drawio-colors="color: #fdfdfb; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | ||
| 108 | + <div style="display: inline-block; font-size: 17px; font-family: Helvetica; color: rgb(253, 253, 251); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; overflow-wrap: normal;"> | ||
| 109 | + files | ||
| 110 | +Workspace | ||
| 111 | +file API | ||
| 112 | + </div> | ||
| 113 | + </div> | ||
| 114 | + </div> | ||
| 115 | + </foreignObject> | ||
| 116 | + <text x="614" y="331" fill="#fdfdfb" font-family="Helvetica" font-size="17px" text-anchor="middle" font-weight="bold"> | ||
| 117 | + files... | ||
| 118 | + </text> | ||
| 119 | + </switch> | ||
| 120 | + </g> | ||
| 121 | + <rect x="351" y="441" width="135" height="90" rx="10.8" ry="10.8" fill="#15202b" stroke="#15202b" stroke-width="2" pointer-events="all"/> | ||
| 122 | + <g transform="translate(-0.5 -0.5)"> | ||
| 123 | + <switch> | ||
| 124 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | ||
| 125 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 133px; height: 1px; padding-top: 486px; margin-left: 352px;"> | ||
| 126 | + <div data-drawio-colors="color: #fdfdfb; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | ||
| 127 | + <div style="display: inline-block; font-size: 17px; font-family: Helvetica; color: rgb(253, 253, 251); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; overflow-wrap: normal;"> | ||
| 128 | + terminal | ||
| 129 | +PTY per | ||
| 130 | +connection | ||
| 131 | + </div> | ||
| 132 | + </div> | ||
| 133 | + </div> | ||
| 134 | + </foreignObject> | ||
| 135 | + <text x="419" y="491" fill="#fdfdfb" font-family="Helvetica" font-size="17px" text-anchor="middle" font-weight="bold"> | ||
| 136 | + terminal... | ||
| 137 | + </text> | ||
| 138 | + </switch> | ||
| 139 | + </g> | ||
| 140 | + <rect x="781" y="211" width="400" height="130" rx="15.6" ry="15.6" fill="#fdfdfb" stroke="#0062ff" stroke-width="2" pointer-events="all"/> | ||
| 141 | + <g transform="translate(-0.5 -0.5)"> | ||
| 142 | + <switch> | ||
| 143 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | ||
| 144 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 276px; margin-left: 782px;"> | ||
| 145 | + <div data-drawio-colors="color: #0062FF; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | ||
| 146 | + <div style="display: inline-block; font-size: 17px; font-family: Helvetica; color: rgb(0, 98, 255); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; overflow-wrap: normal;"> | ||
| 147 | + ACP Agent | ||
| 148 | + <br/> | ||
| 149 | + (claude-code-acp) | ||
| 150 | + <br/> | ||
| 151 | + <br/> | ||
| 152 | + JSON-RPC over stdio | ||
| 153 | + <br/> | ||
| 154 | + session_update · permission_request | ||
| 155 | + </div> | ||
| 156 | + </div> | ||
| 157 | + </div> | ||
| 158 | + </foreignObject> | ||
| 159 | + <text x="981" y="281" fill="#0062FF" font-family="Helvetica" font-size="17px" text-anchor="middle" font-weight="bold"> | ||
| 160 | + ACP Agent... | ||
| 161 | + </text> | ||
| 162 | + </switch> | ||
| 163 | + </g> | ||
| 164 | + <rect x="1" y="541" width="1180" height="60" rx="7.2" ry="7.2" fill="#fdfdfb" stroke="#15202b" stroke-width="2" stroke-dasharray="6 6" pointer-events="all"/> | ||
| 165 | + <g transform="translate(-0.5 -0.5)"> | ||
| 166 | + <switch> | ||
| 167 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | ||
| 168 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1178px; height: 1px; padding-top: 571px; margin-left: 2px;"> | ||
| 169 | + <div data-drawio-colors="color: #15202b; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | ||
| 170 | + <div style="display: inline-block; font-size: 15px; font-family: Helvetica; color: rgb(21, 32, 43); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> | ||
| 171 | + Go backend bridges browser WebSockets to ACP stdio, broadcasting agent updates to all connected browsers while routing permissions back to the waiting call. | ||
| 172 | + </div> | ||
| 173 | + </div> | ||
| 174 | + </div> | ||
| 175 | + </foreignObject> | ||
| 176 | + <text x="591" y="576" fill="#15202b" font-family="Helvetica" font-size="15px" text-anchor="middle"> | ||
| 177 | + Go backend bridges browser WebSockets to ACP stdio, broadcasting agent updates to all connected browsers while routing permissions back to the waiting call. | ||
| 178 | + </text> | ||
| 179 | + </switch> | ||
| 180 | + </g> | ||
| 181 | + <path d="M 221 56 L 322 56 Q 332 56 332 51 L 332 48.5 Q 332 46 342 46 L 434.76 46" fill="none" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/> | ||
| 182 | + <path d="M 440.76 46 L 432.76 50 L 434.76 46 L 432.76 42 Z" fill="#15202b" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> | ||
| 183 | + <g transform="translate(-0.5 -0.5)"> | ||
| 184 | + <switch> | ||
| 185 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | ||
| 186 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 51px; margin-left: 332px;"> | ||
| 187 | + <div data-drawio-colors="color: #15202b; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | ||
| 188 | + <div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(21, 32, 43); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> | ||
| 189 | + 1. load SPA | ||
| 190 | + </div> | ||
| 191 | + </div> | ||
| 192 | + </div> | ||
| 193 | + </foreignObject> | ||
| 194 | + <text x="332" y="55" fill="#15202b" font-family="Helvetica" font-size="14px" text-anchor="middle"> | ||
| 195 | + 1. load SPA | ||
| 196 | + </text> | ||
| 197 | + </switch> | ||
| 198 | + </g> | ||
| 199 | + <path d="M 221 81 L 321.5 81 Q 331.5 81 331.5 91 L 331.5 151 Q 331.5 161 341.5 161 L 433.76 161" fill="none" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/> | ||
| 200 | + <path d="M 439.76 161 L 431.76 165 L 433.76 161 L 431.76 157 Z" fill="#15202b" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> | ||
| 201 | + <g transform="translate(-0.5 -0.5)"> | ||
| 202 | + <switch> | ||
| 203 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | ||
| 204 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 122px; margin-left: 332px;"> | ||
| 205 | + <div data-drawio-colors="color: #15202b; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | ||
| 206 | + <div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(21, 32, 43); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> | ||
| 207 | + 2. WebSocket | ||
| 208 | +/ws | ||
| 209 | + </div> | ||
| 210 | + </div> | ||
| 211 | + </div> | ||
| 212 | + </foreignObject> | ||
| 213 | + <text x="332" y="126" fill="#15202b" font-family="Helvetica" font-size="14px" text-anchor="middle"> | ||
| 214 | + 2. WebSocket... | ||
| 215 | + </text> | ||
| 216 | + </switch> | ||
| 217 | + </g> | ||
| 218 | + <path d="M 221 206 L 433.76 206" fill="none" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/> | ||
| 219 | + <path d="M 439.76 206 L 431.76 210 L 433.76 206 L 431.76 202 Z" fill="#15202b" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> | ||
| 220 | + <g transform="translate(-0.5 -0.5)"> | ||
| 221 | + <switch> | ||
| 222 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | ||
| 223 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 181px; margin-left: 331px;"> | ||
| 224 | + <div data-drawio-colors="color: #15202b; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | ||
| 225 | + <div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(21, 32, 43); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> | ||
| 226 | + 3. prompt + | ||
| 227 | +permission | ||
| 228 | +responses | ||
| 229 | + </div> | ||
| 230 | + </div> | ||
| 231 | + </div> | ||
| 232 | + </foreignObject> | ||
| 233 | + <text x="331" y="185" fill="#15202b" font-family="Helvetica" font-size="14px" text-anchor="middle"> | ||
| 234 | + 3. prompt +... | ||
| 235 | + </text> | ||
| 236 | + </switch> | ||
| 237 | + </g> | ||
| 238 | + <path d="M 442 231 L 331 231 Q 321 231 311 231 L 229.24 231" fill="none" stroke="#0062ff" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="stroke"/> | ||
| 239 | + <path d="M 223.24 231 L 231.24 227 L 229.24 231 L 231.24 235 Z" fill="#0062ff" stroke="#0062ff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> | ||
| 240 | + <g transform="translate(-0.5 -0.5)"> | ||
| 241 | + <switch> | ||
| 242 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | ||
| 243 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 251px; margin-left: 374px;"> | ||
| 244 | + <div data-drawio-colors="color: #0062FF; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | ||
| 245 | + <div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(0, 98, 255); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> | ||
| 246 | + 4. session_update | ||
| 247 | +events (replay) | ||
| 248 | + </div> | ||
| 249 | + </div> | ||
| 250 | + </div> | ||
| 251 | + </foreignObject> | ||
| 252 | + <text x="374" y="255" fill="#0062FF" font-family="Helvetica" font-size="14px" text-anchor="middle"> | ||
| 253 | + 4. session_update... | ||
| 254 | + </text> | ||
| 255 | + </switch> | ||
| 256 | + </g> | ||
| 257 | + <path d="M 522 251 L 522 286 Q 522 296 512 296 L 428 296 Q 418 296 418 306 L 418 332.76" fill="none" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/> | ||
| 258 | + <path d="M 418 338.76 L 414 330.76 L 418 332.76 L 422 330.76 Z" fill="#15202b" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> | ||
| 259 | + <g transform="translate(-0.5 -0.5)"> | ||
| 260 | + <switch> | ||
| 261 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | ||
| 262 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 296px; margin-left: 470px;"> | ||
| 263 | + <div data-drawio-colors="color: #15202b; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | ||
| 264 | + <div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(21, 32, 43); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> | ||
| 265 | + 5. ACP | ||
| 266 | +lifecycle | ||
| 267 | + </div> | ||
| 268 | + </div> | ||
| 269 | + </div> | ||
| 270 | + </foreignObject> | ||
| 271 | + <text x="470" y="300" fill="#15202b" font-family="Helvetica" font-size="14px" text-anchor="middle"> | ||
| 272 | + 5. ACP... | ||
| 273 | + </text> | ||
| 274 | + </switch> | ||
| 275 | + </g> | ||
| 276 | + <path d="M 486 386 L 486 336 Q 486 326 496 326 L 671 326 Q 681 326 681 316 L 681 286 Q 681 276 691 276 L 772.76 276" fill="none" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/> | ||
| 277 | + <path d="M 778.76 276 L 770.76 280 L 772.76 276 L 770.76 272 Z" fill="#15202b" stroke="#15202b" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> | ||
| 278 | + <g transform="translate(-0.5 -0.5)"> | ||
| 279 | + <switch> | ||
| 280 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | ||
| 281 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 381px; margin-left: 671px;"> | ||
| 282 | + <div data-drawio-colors="color: #15202b; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | ||
| 283 | + <div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(21, 32, 43); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> | ||
| 284 | + 6. stdio | ||
| 285 | +JSON-RPC | ||
| 286 | + </div> | ||
| 287 | + </div> | ||
| 288 | + </div> | ||
| 289 | + </foreignObject> | ||
| 290 | + <text x="671" y="385" fill="#15202b" font-family="Helvetica" font-size="14px" text-anchor="middle"> | ||
| 291 | + 6. stdio... | ||
| 292 | + </text> | ||
| 293 | + </switch> | ||
| 294 | + </g> | ||
| 295 | + <path d="M 981 211 L 981 191 Q 981 181 971 181 L 730.24 181" fill="none" stroke="#0062ff" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="stroke"/> | ||
| 296 | + <path d="M 724.24 181 L 732.24 177 L 730.24 181 L 732.24 185 Z" fill="#0062ff" stroke="#0062ff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> | ||
| 297 | + <g transform="translate(-0.5 -0.5)"> | ||
| 298 | + <switch> | ||
| 299 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | ||
| 300 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 181px; margin-left: 866px;"> | ||
| 301 | + <div data-drawio-colors="color: #0062FF; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | ||
| 302 | + <div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(0, 98, 255); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> | ||
| 303 | + 7. updates + | ||
| 304 | +permissions | ||
| 305 | + </div> | ||
| 306 | + </div> | ||
| 307 | + </div> | ||
| 308 | + </foreignObject> | ||
| 309 | + <text x="866" y="185" fill="#0062FF" font-family="Helvetica" font-size="14px" text-anchor="middle"> | ||
| 310 | + 7. updates +... | ||
| 311 | + </text> | ||
| 312 | + </switch> | ||
| 313 | + </g> | ||
| 314 | + <path d="M 166 281 L 346 281 Q 356 281 356 291 L 356 316 Q 356 326 366 326 L 537.76 326" fill="none" stroke="#0062ff" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="stroke"/> | ||
| 315 | + <path d="M 543.76 326 L 535.76 330 L 537.76 326 L 535.76 322 Z" fill="#0062ff" stroke="#0062ff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> | ||
| 316 | + <g transform="translate(-0.5 -0.5)"> | ||
| 317 | + <switch> | ||
| 318 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | ||
| 319 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 312px; margin-left: 326px;"> | ||
| 320 | + <div data-drawio-colors="color: #0062FF; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | ||
| 321 | + <div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(0, 98, 255); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> | ||
| 322 | + file ops | ||
| 323 | + </div> | ||
| 324 | + </div> | ||
| 325 | + </div> | ||
| 326 | + </foreignObject> | ||
| 327 | + <text x="326" y="316" fill="#0062FF" font-family="Helvetica" font-size="14px" text-anchor="middle"> | ||
| 328 | + file ops | ||
| 329 | + </text> | ||
| 330 | + </switch> | ||
| 331 | + </g> | ||
| 332 | + <path d="M 111 281 L 111 476 Q 111 486 121 486 L 342.76 486" fill="none" stroke="#0062ff" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="stroke"/> | ||
| 333 | + <path d="M 348.76 486 L 340.76 490 L 342.76 486 L 340.76 482 Z" fill="#0062ff" stroke="#0062ff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> | ||
| 334 | + <g transform="translate(-0.5 -0.5)"> | ||
| 335 | + <switch> | ||
| 336 | + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> | ||
| 337 | + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 486px; margin-left: 129px;"> | ||
| 338 | + <div data-drawio-colors="color: #0062FF; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> | ||
| 339 | + <div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(0, 98, 255); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> | ||
| 340 | + shell I/O | ||
| 341 | + </div> | ||
| 342 | + </div> | ||
| 343 | + </div> | ||
| 344 | + </foreignObject> | ||
| 345 | + <text x="129" y="490" fill="#0062FF" font-family="Helvetica" font-size="14px" text-anchor="middle"> | ||
| 346 | + shell I/O | ||
| 347 | + </text> | ||
| 348 | + </switch> | ||
| 349 | + </g> | ||
| 350 | + </g> | ||
| 351 | + <switch> | ||
| 352 | + <g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/> | ||
| 353 | + <a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"> | ||
| 354 | + <text text-anchor="middle" font-size="10px" x="50%" y="100%"> | ||
| 355 | + Text is not SVG - cannot display | ||
| 356 | + </text> | ||
| 357 | + </a> | ||
| 358 | + </switch> | ||
| 359 | +</svg> | ||
| \ No newline at end of file | \ No newline at end of file | ||
modified
ori-desktop/README.fr.md +1 -1 | @@ -70,7 +70,7 @@ premier lancement, les fichiers invalides et la normalisation d'URL ; `internal/ | ||
| 70 | 70 | ## Comment il se connecte à ori |
| 71 | 71 | |
| 72 | 72 | ``` |
| 73 | -┌──────────────── ori-desktop (fenêtre Wails) ───────────────┐ | |
| 73 | +┌──────────────── ori-desktop (fenêtre Wails) ────────────────┐ | |
| 74 | 74 | │ frontend/src (embarqué, origine wails://) │ |
| 75 | 75 | │ écran de connexion ──► window.go.main.App.Connect(url) │ |
| 76 | 76 | │ │ Go : NormalizeURL → GET /healthz → sauvegarde des réglages |
| @@ -70,7 +70,7 @@ premier lancement, les fichiers invalides et la normalisation d'URL ; `internal/ | |||
| 70 | ## Comment il se connecte à ori | 70 | ## Comment il se connecte à ori |
| 71 | 71 | ||
| 72 | ``` | 72 | ``` |
| 73 | -┌──────────────── ori-desktop (fenêtre Wails) ───────────────┐ | 73 | +┌──────────────── ori-desktop (fenêtre Wails) ────────────────┐ |
| 74 | │ frontend/src (embarqué, origine wails://) │ | 74 | │ frontend/src (embarqué, origine wails://) │ |
| 75 | │ écran de connexion ──► window.go.main.App.Connect(url) │ | 75 | │ écran de connexion ──► window.go.main.App.Connect(url) │ |
| 76 | │ │ Go : NormalizeURL → GET /healthz → sauvegarde des réglages | 76 | │ │ Go : NormalizeURL → GET /healthz → sauvegarde des réglages |
modified
ori-desktop/README.md +1 -1 | @@ -68,7 +68,7 @@ non-ori, unreachable, cancelled). | ||
| 68 | 68 | ## How it connects to ori |
| 69 | 69 | |
| 70 | 70 | ``` |
| 71 | -┌──────────────── ori-desktop (Wails window) ────────────────┐ | |
| 71 | +┌──────────────── ori-desktop (Wails window) ─────────────────┐ | |
| 72 | 72 | │ frontend/src (embedded, wails:// origin) │ |
| 73 | 73 | │ connection screen ──► window.go.main.App.Connect(url) │ |
| 74 | 74 | │ │ Go: NormalizeURL → GET /healthz → Save settings |
| @@ -68,7 +68,7 @@ non-ori, unreachable, cancelled). | |||
| 68 | ## How it connects to ori | 68 | ## How it connects to ori |
| 69 | 69 | ||
| 70 | ``` | 70 | ``` |
| 71 | -┌──────────────── ori-desktop (Wails window) ────────────────┐ | 71 | +┌──────────────── ori-desktop (Wails window) ─────────────────┐ |
| 72 | │ frontend/src (embedded, wails:// origin) │ | 72 | │ frontend/src (embedded, wails:// origin) │ |
| 73 | │ connection screen ──► window.go.main.App.Connect(url) │ | 73 | │ connection screen ──► window.go.main.App.Connect(url) │ |
| 74 | │ │ Go: NormalizeURL → GET /healthz → Save settings | 74 | │ │ Go: NormalizeURL → GET /healthz → Save settings |
added
ori-desktop/how-to-build.md +218 -0 | new file mode 100644 | ||
| @@ -0,0 +1,218 @@ | ||
| 1 | +# How to build ori-desktop | |
| 2 | + | |
| 3 | +This guide shows how to build the [ori-desktop](./README.md) Wails shell on each platform, and | |
| 4 | +what to watch out for. See [README.md](./README.md) for what the app does and | |
| 5 | +[README.fr.md](./README.fr.md) for the French version of that overview. | |
| 6 | + | |
| 7 | +## Prerequisites (every platform) | |
| 8 | + | |
| 9 | +- **Go 1.25 or newer** — `go.mod` requires `go 1.25.0`. | |
| 10 | +- **The Wails v2 CLI**, matching the module's Wails version: | |
| 11 | + | |
| 12 | + ```bash | |
| 13 | + go install github.com/wailsapp/wails/v2/cmd/wails@v2.16.0 | |
| 14 | + export PATH="$PATH:$(go env GOPATH)/bin" | |
| 15 | + wails version # → v2.16.0 | |
| 16 | + ``` | |
| 17 | + | |
| 18 | +- **No Node or npm.** The frontend is plain HTML/CSS/JS embedded as-is; `wails.json` leaves | |
| 19 | + `frontend:install` and `frontend:build` empty on purpose. | |
| 20 | + | |
| 21 | +Everything below is run from the `ori-desktop/` directory, which is a **separate Go module** | |
| 22 | +(`rickub.com/bots-garden/ori-desktop`). The repository root's `make build` and `go test ./...` | |
| 23 | +never touch it. | |
| 24 | + | |
| 25 | +## What can be built from where | |
| 26 | + | |
| 27 | +Wails compiles the native window through cgo against the platform's webview, so the host decides | |
| 28 | +what is reachable: | |
| 29 | + | |
| 30 | +| Target | From macOS | From Linux | From Windows | | |
| 31 | +| --- | --- | --- | --- | | |
| 32 | +| `darwin/*` (`.app`) | ✅ | ❌ needs the macOS SDK | ❌ | | |
| 33 | +| `linux/*` | ❌ | ✅ | ❌ | | |
| 34 | +| `windows/*` (`.exe`) | ✅ | ✅ | ✅ | | |
| 35 | + | |
| 36 | +Windows is the only free cross-build: WebView2 is loaded at runtime, so no C toolchain is | |
| 37 | +involved. macOS needs Cocoa and WKWebView from Xcode, and Linux needs WebKitGTK — neither is | |
| 38 | +cross-compilable in practice. | |
| 39 | + | |
| 40 | +All outputs land in `build/bin/` and can coexist there, since each target has a distinct name: | |
| 41 | +`ori-desktop` (Linux), `ori-desktop.app` (macOS), `ori-desktop.exe` (Windows). | |
| 42 | + | |
| 43 | +## macOS | |
| 44 | + | |
| 45 | +1. Install the Xcode command line tools, if they are not already there: | |
| 46 | + | |
| 47 | + ```bash | |
| 48 | + xcode-select --install | |
| 49 | + ``` | |
| 50 | + | |
| 51 | +2. Build and launch: | |
| 52 | + | |
| 53 | + ```bash | |
| 54 | + cd ori-desktop | |
| 55 | + wails build | |
| 56 | + xattr -cr build/bin/ori-desktop.app # clear the quarantine attribute | |
| 57 | + open build/bin/ori-desktop.app | |
| 58 | + ``` | |
| 59 | + | |
| 60 | + No build tag is needed: `-tags webkit2_41` is a Linux-only concern (see below). | |
| 61 | + | |
| 62 | +3. The app opens on its connection screen and needs an ori server to reach. From the repository | |
| 63 | + root: `make run` (Claude Code) or `make run-mock` (demo agent, no network). The | |
| 64 | + `scripts/launch-ori.applescript` launcher does the whole sequence — start the sandbox, wait | |
| 65 | + for `/healthz`, open the `.app`. | |
| 66 | + | |
| 67 | +### Choosing the architecture | |
| 68 | + | |
| 69 | +`wails build` alone targets the architecture of the machine you build on. To be explicit: | |
| 70 | + | |
| 71 | +```bash | |
| 72 | +wails build -platform darwin/universal # one .app running on Apple Silicon and Intel | |
| 73 | +wails build -platform darwin/arm64 # Apple Silicon only | |
| 74 | +wails build -platform darwin/amd64 # Intel only | |
| 75 | +``` | |
| 76 | + | |
| 77 | +A `universal` build runs the Go compiler twice and merges the results with `lipo`, so it takes | |
| 78 | +about twice as long and produces a noticeably larger bundle. | |
| 79 | + | |
| 80 | +### Bundle details | |
| 81 | + | |
| 82 | +`build/darwin/Info.plist` is a Go template filled from the `info` block of `wails.json` | |
| 83 | +(product name `ori`, version `0.1.0`, company `bots-garden`). It sets | |
| 84 | +`NSAppTransportSecurity/NSAllowsLocalNetworking` so App Transport Security allows the app to load | |
| 85 | +ori over plain HTTP on the loopback interface — without it the iframe stays blank. | |
| 86 | +`build/darwin/Info.dev.plist` is the variant `wails dev` uses. | |
| 87 | + | |
| 88 | +## Linux | |
| 89 | + | |
| 90 | +1. Install the GUI toolchain. On Ubuntu 26.04 (and any distribution that has moved past | |
| 91 | + WebKitGTK 4.0): | |
| 92 | + | |
| 93 | + ```bash | |
| 94 | + sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev | |
| 95 | + ``` | |
| 96 | + | |
| 97 | +2. Build with the matching build tag: | |
| 98 | + | |
| 99 | + ```bash | |
| 100 | + cd ori-desktop | |
| 101 | + wails build -tags webkit2_41 | |
| 102 | + ``` | |
| 103 | + | |
| 104 | +**The build tag is mandatory on any system without WebKitGTK 4.0.** Wails' default cgo | |
| 105 | +`pkg-config` line asks for `webkit2gtk-4.0`; where only 4.1 is packaged, a bare `wails build` | |
| 106 | +stops with: | |
| 107 | + | |
| 108 | +``` | |
| 109 | +# [pkg-config --cflags -- gtk+-3.0 gio-unix-2.0 webkit2gtk-4.0 …] | |
| 110 | +Package 'webkit2gtk-4.0' not found | |
| 111 | +``` | |
| 112 | + | |
| 113 | +`-tags webkit2_41` switches Wails to the `webkit2gtk-4.1` pkg-config name. On an older | |
| 114 | +distribution that still ships `libwebkit2gtk-4.0-dev`, drop the tag. | |
| 115 | + | |
| 116 | +Two traps: | |
| 117 | + | |
| 118 | +- **`wails doctor` reports a false negative.** It probes `webkit2gtk-4.0` only, so even with 4.1 | |
| 119 | + correctly installed it prints `libwebkit | Unknown | Not Found` and | |
| 120 | + `Fatal: Required dependencies missing: libwebkit`. Ignore it and check the real thing: | |
| 121 | + | |
| 122 | + ```bash | |
| 123 | + pkg-config --modversion gtk+-3.0 webkit2gtk-4.1 | |
| 124 | + ``` | |
| 125 | + | |
| 126 | +- **`make desktop` runs a bare `wails build`**, so it fails on those distributions. Build from | |
| 127 | + `ori-desktop/` with the tag instead. The target is correct on macOS, where it is normally used. | |
| 128 | + | |
| 129 | +## Windows | |
| 130 | + | |
| 131 | +Cross-build from anywhere, no C toolchain required: | |
| 132 | + | |
| 133 | +```bash | |
| 134 | +cd ori-desktop | |
| 135 | +wails build -platform windows/amd64 # → build/bin/ori-desktop.exe | |
| 136 | +wails build -platform windows/arm64 | |
| 137 | +``` | |
| 138 | + | |
| 139 | +The resulting binary needs the WebView2 runtime, which is preinstalled on Windows 10 and 11. The | |
| 140 | +`-webview2` flag picks the strategy for machines without it (`download`, the default, `embed`, | |
| 141 | +`browser` or `error`), and `-nsis` produces an installer — that one needs NSIS on the build | |
| 142 | +machine (`sudo apt-get install nsis` on Debian-family systems). | |
| 143 | + | |
| 144 | +`build/windows/` holds the manifest, icon and NSIS assets. | |
| 145 | + | |
| 146 | +## Useful flags | |
| 147 | + | |
| 148 | +`wails build -help` lists them all; these are the ones that matter here. | |
| 149 | + | |
| 150 | +| Flag | Use | | |
| 151 | +| --- | --- | | |
| 152 | +| `-clean` | Empties `build/bin/` first. **It removes the other platforms' outputs too** — the `.app`, the `.exe` and the Linux binary all live in that one directory. | | |
| 153 | +| `-platform os/arch` | Target something other than the host; comma-separate several. Defaults to the host. | | |
| 154 | +| `-tags "…"` | Go build tags — this is how `webkit2_41` is passed. | | |
| 155 | +| `-dryrun` | Prints the `go build` command Wails would run, without running it. Handy for diagnosing a cgo or pkg-config failure. | | |
| 156 | +| `-debug` / `-devtools` | Keep the webview devtools available in a production build. | | |
| 157 | +| `-race`, `-trimpath`, `-ldflags`, `-o` | Passed through to the Go compiler / output name. | | |
| 158 | +| `-s` | Skip the frontend step — a no-op here, since there is no frontend build. | | |
| 159 | + | |
| 160 | +`wails build` also regenerates `frontend/wailsjs/` (the typed JS wrappers for the bound Go | |
| 161 | +methods). Nothing imports them and they are gitignored; the frontend calls | |
| 162 | +`window.go.main.App.<Method>()` directly. | |
| 163 | + | |
| 164 | +## Development mode | |
| 165 | + | |
| 166 | +```bash | |
| 167 | +cd ori-desktop | |
| 168 | +wails dev # add -tags webkit2_41 on Linux, as for build | |
| 169 | +``` | |
| 170 | + | |
| 171 | +This opens the window and reloads it whenever a file under `frontend/src/` changes (`assetdir` in | |
| 172 | +`wails.json`). It also serves the app on http://localhost:34115, so it can be opened in a normal | |
| 173 | +browser with devtools while still calling the Go methods. | |
| 174 | + | |
| 175 | +## Tests | |
| 176 | + | |
| 177 | +The connection logic is pure Go and needs no GUI dependency at all — it can be run on a machine | |
| 178 | +where the build itself is impossible: | |
| 179 | + | |
| 180 | +```bash | |
| 181 | +cd ori-desktop && go test ./internal/... | |
| 182 | +# or, from the repository root: | |
| 183 | +make desktop-test | |
| 184 | +``` | |
| 185 | + | |
| 186 | +## Troubleshooting | |
| 187 | + | |
| 188 | +**`Package 'webkit2gtk-4.0' not found` (Linux)** — add `-tags webkit2_41`; see above. | |
| 189 | + | |
| 190 | +**`wails: command not found`** — `$(go env GOPATH)/bin` is not on `PATH`. | |
| 191 | + | |
| 192 | +**macOS refuses to open the `.app`** — two distinct causes: | |
| 193 | + | |
| 194 | +- *"cannot be opened"* / nothing happens: the executable inside the bundle lost its execute bit. | |
| 195 | + This happens when `build/bin/` sits in a cloud-synced folder (iCloud Drive, kDrive, Dropbox), | |
| 196 | + which does not always preserve POSIX modes. Restore it with: | |
| 197 | + | |
| 198 | + ```bash | |
| 199 | + chmod +x build/bin/ori-desktop.app/Contents/MacOS/ori-desktop | |
| 200 | + ``` | |
| 201 | + | |
| 202 | + That invalidates the bundle's signature, so if macOS then calls the app damaged, rebuild with | |
| 203 | + `wails build -clean`. | |
| 204 | + | |
| 205 | +- *"cannot be opened because it is from an unidentified developer"* / *"damaged"*: Gatekeeper. | |
| 206 | + `xattr -cr build/bin/ori-desktop.app` clears the quarantine flag on the machine that built it. | |
| 207 | + Wails only signs the bundle ad hoc, so distributing it to other Macs requires a Developer ID | |
| 208 | + certificate, `codesign` and notarisation with `notarytool`. | |
| 209 | + | |
| 210 | +**The window opens but stays empty** — that is the connection screen failing to reach ori, not a | |
| 211 | +build problem. Check that an ori server answers on the URL shown (`curl http://localhost:8888/healthz`) | |
| 212 | +and use the "Open in browser" button to confirm. | |
| 213 | + | |
| 214 | +## See also | |
| 215 | + | |
| 216 | +- What the app is and how it talks to ori: [README.md](./README.md) / [README.fr.md](./README.fr.md) | |
| 217 | +- Running the ori server itself: the repository's [quickstart](../quickstart.md) | |
| 218 | +- Running the test suites: [docs/en/how-to/run-the-tests.md](../docs/en/how-to/run-the-tests.md) | |
| new file mode 100644 | |||
| @@ -0,0 +1,218 @@ | |||
| 1 | +# How to build ori-desktop | ||
| 2 | + | ||
| 3 | +This guide shows how to build the [ori-desktop](./README.md) Wails shell on each platform, and | ||
| 4 | +what to watch out for. See [README.md](./README.md) for what the app does and | ||
| 5 | +[README.fr.md](./README.fr.md) for the French version of that overview. | ||
| 6 | + | ||
| 7 | +## Prerequisites (every platform) | ||
| 8 | + | ||
| 9 | +- **Go 1.25 or newer** — `go.mod` requires `go 1.25.0`. | ||
| 10 | +- **The Wails v2 CLI**, matching the module's Wails version: | ||
| 11 | + | ||
| 12 | + ```bash | ||
| 13 | + go install github.com/wailsapp/wails/v2/cmd/wails@v2.16.0 | ||
| 14 | + export PATH="$PATH:$(go env GOPATH)/bin" | ||
| 15 | + wails version # → v2.16.0 | ||
| 16 | + ``` | ||
| 17 | + | ||
| 18 | +- **No Node or npm.** The frontend is plain HTML/CSS/JS embedded as-is; `wails.json` leaves | ||
| 19 | + `frontend:install` and `frontend:build` empty on purpose. | ||
| 20 | + | ||
| 21 | +Everything below is run from the `ori-desktop/` directory, which is a **separate Go module** | ||
| 22 | +(`rickub.com/bots-garden/ori-desktop`). The repository root's `make build` and `go test ./...` | ||
| 23 | +never touch it. | ||
| 24 | + | ||
| 25 | +## What can be built from where | ||
| 26 | + | ||
| 27 | +Wails compiles the native window through cgo against the platform's webview, so the host decides | ||
| 28 | +what is reachable: | ||
| 29 | + | ||
| 30 | +| Target | From macOS | From Linux | From Windows | | ||
| 31 | +| --- | --- | --- | --- | | ||
| 32 | +| `darwin/*` (`.app`) | ✅ | ❌ needs the macOS SDK | ❌ | | ||
| 33 | +| `linux/*` | ❌ | ✅ | ❌ | | ||
| 34 | +| `windows/*` (`.exe`) | ✅ | ✅ | ✅ | | ||
| 35 | + | ||
| 36 | +Windows is the only free cross-build: WebView2 is loaded at runtime, so no C toolchain is | ||
| 37 | +involved. macOS needs Cocoa and WKWebView from Xcode, and Linux needs WebKitGTK — neither is | ||
| 38 | +cross-compilable in practice. | ||
| 39 | + | ||
| 40 | +All outputs land in `build/bin/` and can coexist there, since each target has a distinct name: | ||
| 41 | +`ori-desktop` (Linux), `ori-desktop.app` (macOS), `ori-desktop.exe` (Windows). | ||
| 42 | + | ||
| 43 | +## macOS | ||
| 44 | + | ||
| 45 | +1. Install the Xcode command line tools, if they are not already there: | ||
| 46 | + | ||
| 47 | + ```bash | ||
| 48 | + xcode-select --install | ||
| 49 | + ``` | ||
| 50 | + | ||
| 51 | +2. Build and launch: | ||
| 52 | + | ||
| 53 | + ```bash | ||
| 54 | + cd ori-desktop | ||
| 55 | + wails build | ||
| 56 | + xattr -cr build/bin/ori-desktop.app # clear the quarantine attribute | ||
| 57 | + open build/bin/ori-desktop.app | ||
| 58 | + ``` | ||
| 59 | + | ||
| 60 | + No build tag is needed: `-tags webkit2_41` is a Linux-only concern (see below). | ||
| 61 | + | ||
| 62 | +3. The app opens on its connection screen and needs an ori server to reach. From the repository | ||
| 63 | + root: `make run` (Claude Code) or `make run-mock` (demo agent, no network). The | ||
| 64 | + `scripts/launch-ori.applescript` launcher does the whole sequence — start the sandbox, wait | ||
| 65 | + for `/healthz`, open the `.app`. | ||
| 66 | + | ||
| 67 | +### Choosing the architecture | ||
| 68 | + | ||
| 69 | +`wails build` alone targets the architecture of the machine you build on. To be explicit: | ||
| 70 | + | ||
| 71 | +```bash | ||
| 72 | +wails build -platform darwin/universal # one .app running on Apple Silicon and Intel | ||
| 73 | +wails build -platform darwin/arm64 # Apple Silicon only | ||
| 74 | +wails build -platform darwin/amd64 # Intel only | ||
| 75 | +``` | ||
| 76 | + | ||
| 77 | +A `universal` build runs the Go compiler twice and merges the results with `lipo`, so it takes | ||
| 78 | +about twice as long and produces a noticeably larger bundle. | ||
| 79 | + | ||
| 80 | +### Bundle details | ||
| 81 | + | ||
| 82 | +`build/darwin/Info.plist` is a Go template filled from the `info` block of `wails.json` | ||
| 83 | +(product name `ori`, version `0.1.0`, company `bots-garden`). It sets | ||
| 84 | +`NSAppTransportSecurity/NSAllowsLocalNetworking` so App Transport Security allows the app to load | ||
| 85 | +ori over plain HTTP on the loopback interface — without it the iframe stays blank. | ||
| 86 | +`build/darwin/Info.dev.plist` is the variant `wails dev` uses. | ||
| 87 | + | ||
| 88 | +## Linux | ||
| 89 | + | ||
| 90 | +1. Install the GUI toolchain. On Ubuntu 26.04 (and any distribution that has moved past | ||
| 91 | + WebKitGTK 4.0): | ||
| 92 | + | ||
| 93 | + ```bash | ||
| 94 | + sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev | ||
| 95 | + ``` | ||
| 96 | + | ||
| 97 | +2. Build with the matching build tag: | ||
| 98 | + | ||
| 99 | + ```bash | ||
| 100 | + cd ori-desktop | ||
| 101 | + wails build -tags webkit2_41 | ||
| 102 | + ``` | ||
| 103 | + | ||
| 104 | +**The build tag is mandatory on any system without WebKitGTK 4.0.** Wails' default cgo | ||
| 105 | +`pkg-config` line asks for `webkit2gtk-4.0`; where only 4.1 is packaged, a bare `wails build` | ||
| 106 | +stops with: | ||
| 107 | + | ||
| 108 | +``` | ||
| 109 | +# [pkg-config --cflags -- gtk+-3.0 gio-unix-2.0 webkit2gtk-4.0 …] | ||
| 110 | +Package 'webkit2gtk-4.0' not found | ||
| 111 | +``` | ||
| 112 | + | ||
| 113 | +`-tags webkit2_41` switches Wails to the `webkit2gtk-4.1` pkg-config name. On an older | ||
| 114 | +distribution that still ships `libwebkit2gtk-4.0-dev`, drop the tag. | ||
| 115 | + | ||
| 116 | +Two traps: | ||
| 117 | + | ||
| 118 | +- **`wails doctor` reports a false negative.** It probes `webkit2gtk-4.0` only, so even with 4.1 | ||
| 119 | + correctly installed it prints `libwebkit | Unknown | Not Found` and | ||
| 120 | + `Fatal: Required dependencies missing: libwebkit`. Ignore it and check the real thing: | ||
| 121 | + | ||
| 122 | + ```bash | ||
| 123 | + pkg-config --modversion gtk+-3.0 webkit2gtk-4.1 | ||
| 124 | + ``` | ||
| 125 | + | ||
| 126 | +- **`make desktop` runs a bare `wails build`**, so it fails on those distributions. Build from | ||
| 127 | + `ori-desktop/` with the tag instead. The target is correct on macOS, where it is normally used. | ||
| 128 | + | ||
| 129 | +## Windows | ||
| 130 | + | ||
| 131 | +Cross-build from anywhere, no C toolchain required: | ||
| 132 | + | ||
| 133 | +```bash | ||
| 134 | +cd ori-desktop | ||
| 135 | +wails build -platform windows/amd64 # → build/bin/ori-desktop.exe | ||
| 136 | +wails build -platform windows/arm64 | ||
| 137 | +``` | ||
| 138 | + | ||
| 139 | +The resulting binary needs the WebView2 runtime, which is preinstalled on Windows 10 and 11. The | ||
| 140 | +`-webview2` flag picks the strategy for machines without it (`download`, the default, `embed`, | ||
| 141 | +`browser` or `error`), and `-nsis` produces an installer — that one needs NSIS on the build | ||
| 142 | +machine (`sudo apt-get install nsis` on Debian-family systems). | ||
| 143 | + | ||
| 144 | +`build/windows/` holds the manifest, icon and NSIS assets. | ||
| 145 | + | ||
| 146 | +## Useful flags | ||
| 147 | + | ||
| 148 | +`wails build -help` lists them all; these are the ones that matter here. | ||
| 149 | + | ||
| 150 | +| Flag | Use | | ||
| 151 | +| --- | --- | | ||
| 152 | +| `-clean` | Empties `build/bin/` first. **It removes the other platforms' outputs too** — the `.app`, the `.exe` and the Linux binary all live in that one directory. | | ||
| 153 | +| `-platform os/arch` | Target something other than the host; comma-separate several. Defaults to the host. | | ||
| 154 | +| `-tags "…"` | Go build tags — this is how `webkit2_41` is passed. | | ||
| 155 | +| `-dryrun` | Prints the `go build` command Wails would run, without running it. Handy for diagnosing a cgo or pkg-config failure. | | ||
| 156 | +| `-debug` / `-devtools` | Keep the webview devtools available in a production build. | | ||
| 157 | +| `-race`, `-trimpath`, `-ldflags`, `-o` | Passed through to the Go compiler / output name. | | ||
| 158 | +| `-s` | Skip the frontend step — a no-op here, since there is no frontend build. | | ||
| 159 | + | ||
| 160 | +`wails build` also regenerates `frontend/wailsjs/` (the typed JS wrappers for the bound Go | ||
| 161 | +methods). Nothing imports them and they are gitignored; the frontend calls | ||
| 162 | +`window.go.main.App.<Method>()` directly. | ||
| 163 | + | ||
| 164 | +## Development mode | ||
| 165 | + | ||
| 166 | +```bash | ||
| 167 | +cd ori-desktop | ||
| 168 | +wails dev # add -tags webkit2_41 on Linux, as for build | ||
| 169 | +``` | ||
| 170 | + | ||
| 171 | +This opens the window and reloads it whenever a file under `frontend/src/` changes (`assetdir` in | ||
| 172 | +`wails.json`). It also serves the app on http://localhost:34115, so it can be opened in a normal | ||
| 173 | +browser with devtools while still calling the Go methods. | ||
| 174 | + | ||
| 175 | +## Tests | ||
| 176 | + | ||
| 177 | +The connection logic is pure Go and needs no GUI dependency at all — it can be run on a machine | ||
| 178 | +where the build itself is impossible: | ||
| 179 | + | ||
| 180 | +```bash | ||
| 181 | +cd ori-desktop && go test ./internal/... | ||
| 182 | +# or, from the repository root: | ||
| 183 | +make desktop-test | ||
| 184 | +``` | ||
| 185 | + | ||
| 186 | +## Troubleshooting | ||
| 187 | + | ||
| 188 | +**`Package 'webkit2gtk-4.0' not found` (Linux)** — add `-tags webkit2_41`; see above. | ||
| 189 | + | ||
| 190 | +**`wails: command not found`** — `$(go env GOPATH)/bin` is not on `PATH`. | ||
| 191 | + | ||
| 192 | +**macOS refuses to open the `.app`** — two distinct causes: | ||
| 193 | + | ||
| 194 | +- *"cannot be opened"* / nothing happens: the executable inside the bundle lost its execute bit. | ||
| 195 | + This happens when `build/bin/` sits in a cloud-synced folder (iCloud Drive, kDrive, Dropbox), | ||
| 196 | + which does not always preserve POSIX modes. Restore it with: | ||
| 197 | + | ||
| 198 | + ```bash | ||
| 199 | + chmod +x build/bin/ori-desktop.app/Contents/MacOS/ori-desktop | ||
| 200 | + ``` | ||
| 201 | + | ||
| 202 | + That invalidates the bundle's signature, so if macOS then calls the app damaged, rebuild with | ||
| 203 | + `wails build -clean`. | ||
| 204 | + | ||
| 205 | +- *"cannot be opened because it is from an unidentified developer"* / *"damaged"*: Gatekeeper. | ||
| 206 | + `xattr -cr build/bin/ori-desktop.app` clears the quarantine flag on the machine that built it. | ||
| 207 | + Wails only signs the bundle ad hoc, so distributing it to other Macs requires a Developer ID | ||
| 208 | + certificate, `codesign` and notarisation with `notarytool`. | ||
| 209 | + | ||
| 210 | +**The window opens but stays empty** — that is the connection screen failing to reach ori, not a | ||
| 211 | +build problem. Check that an ori server answers on the URL shown (`curl http://localhost:8888/healthz`) | ||
| 212 | +and use the "Open in browser" button to confirm. | ||
| 213 | + | ||
| 214 | +## See also | ||
| 215 | + | ||
| 216 | +- What the app is and how it talks to ori: [README.md](./README.md) / [README.fr.md](./README.fr.md) | ||
| 217 | +- Running the ori server itself: the repository's [quickstart](../quickstart.md) | ||
| 218 | +- Running the test suites: [docs/en/how-to/run-the-tests.md](../docs/en/how-to/run-the-tests.md) | ||
modified
template/build.sh +0 -0 | old mode 100755 | ||
| new mode 100644 |
| old mode 100755 | |||
| new mode 100644 |