forked from bots-garden/ori
| ✨ Workspace panel, selectors, previews, desktop app, sandbox template, resizable file tree, light/dark theme | 1 | # History |
| 2 | ||
| 3 | ## 2026-09-17 — Ticket 0004: ACP web client (initial implementation) | |
| 4 | ||
| 5 | - **Goal**: implement `.tickets/issues/0004-specifications.yaml` — a webapp (Go backend + SPA) acting as an ACP client for a code agent (Claude Code first), UI following the principles of Zed's agent panel, designed to evolve. Driven with the `methodical-dev` skill, all checkpoints user-approved. | |
| 6 | - **Changes**: whole codebase created — `cmd/ori`, `cmd/ori-mock-agent`, `internal/{config,httpserver,agent,bridge,mockagent}`, `ui/` (Vite + React 19 + TS SPA with reducer/store/ws-client and panel components), `Makefile`, `biome.json`, `.qlty/qlty.toml`, bilingual `docs/` (en+fr, Diátaxis, 7 pages each), `docs/diagrams/packages.drawio`, root `README.md`. | |
| 7 | - **Decisions**: `coder/acp-go-sdk` for ACP (no official Go lib exists; the claude CLI has no native ACP mode — the user initially chose "native CLI", reversed after verification, and approved the `claude-code-acp` adapter); ACP payloads relayed verbatim to the browser; server as single source of truth with history replay + `user_message` echo; one shared session in v1. Mid-session the user corrected the Go module path from `github.com/bots-garden/ori` to `rickub.com/bots-garden/ori` (repo not on GitHub) — renamed everywhere, tests green. | |
| 8 | - **Tests**: 7 config + 6 httpserver + 10 agent (in-memory mock ACP agent) + 15 bridge (incl. 4 real-WebSocket integration) + 2 mockagent + 1 full e2e (compiled mock binary, real subprocess, real WS, permission round-trip, late-joiner replay) — all green incl. `-race`; 28 frontend tests (reducer, ws client with fake WebSocket, components) — green. One command: `make test`. | |
| 9 | - **Quality**: gate **PASS** (0 errors / 0 warnings / 0 smells, total complexity 145; started at 13/4/5/158). Config adjustments user-approved (see summary). Two environment fights: the 488MB `~/.qlty` volume (cache symlinked to main disk) and a partial JDK extraction. | |
| 10 | - **Docs**: `docs/en/` + `docs/fr/` complete four-quadrant sets; package diagram in draw.io; root README quick start. | |
| 11 | ||
| 12 | ## 2026-09-17 — Live thinking block + working spinner (same session, follow-up) | |
| 13 | ||
| 14 | - **Goal**: after testing against real Claude Code, the user asked for (1) the agent's thinking content visible live while it streams, (2) a spinner with rotating phrases while the agent works, Claude-style. | |
| 15 | - **Changes**: new `ui/src/components/WorkingIndicator.tsx` (spinner + `workingPhrases` rotating every 2.5s), `ChatThread` refactored with a `ThoughtEntry` component (live open block `💭 Thinking…` while streaming, collapsible `💭 Thought for a moment` once the turn ends), CSS spinner/thought-live, tutorials updated in both languages. | |
| 16 | - **Decisions**: live-vs-collapsed decided by the existing `closed` flag on thought items (no reducer change needed); phrases exported for deterministic tests. | |
| 17 | - **Tests**: +3 WorkingIndicator (fake timers: first phrase, rotation, wrap-around) and +2 App (thought open→collapsed across turn end; spinner present during a turn, gone after) — 33 frontend tests green, Go suite untouched. | |
| 18 | - **Quality**: gate PASS again (a first re-run flagged `ThreadEntry` at 6 returns; fixed by extracting `ThoughtEntry`). | |
| 19 | - **Also verified this session**: real Claude Code works end to end via `env -u CLAUDECODE ./bin/ori` (nested-session guard); adapter package renamed upstream to `@agentclientprotocol/claude-agent-acp` (default not changed yet). | |
| 20 | ||
| 21 | ## 2026-09-17 — Workspace panel: preview, editor, terminal, monospace command output (same session, follow-up 2) | |
| 22 | ||
| 23 | - **Goal**: user-requested evolutions — a preview panel (syntax-highlighted code + rendered Markdown/AsciiDoc), a terminal panel, a file editor panel (Monaco), and monospace rendering for system-command output in the chat. | |
| 24 | - **Changes**: backend `internal/files` (list/read/write file API, unrestricted access per user's explicit choice) and `internal/terminal` (PTY shell per WebSocket, creack/pty); frontend workspace layout (chat left + collapsible right panel: file tree with lazy directories, Preview/Editor/Terminal tabs kept mounted when inactive), `MonacoViewer` shared by read-only preview and editor (bundled workers, lazy chunk), AsciiDoc rendering via lazy `@asciidoctor/core`, xterm.js terminal, `tool-output` monospace block for `execute` tool calls. New deps: creack/pty, monaco-editor + @monaco-editor/react, @asciidoctor/core, @xterm/xterm + addon-fit. | |
| 25 | - **Decisions**: layout chat+workspace (user), interactive user terminal only in v1 (ACP terminals later, user), free filesystem/terminal access (user — sandbox assumed isolated), Monaco over CodeMirror (user); panes hidden not unmounted so the shell survives tab switches; monaco 0.56 import specifiers go through its exports map (no `esm/vs/` prefix). | |
| 26 | - **Tests**: +9 files API, +5 terminal PTY integration (real shell over real WS: command output, cwd, resize via stty, malformed frames, exit closes socket) → 46 Go tests incl. e2e; front +5 workspace store, +4 FileTree, +8 lang detection, +6 PreviewPane, +6 EditorPane, +4 TerminalPane (xterm/WS mocked), +2 ToolCallCard mono/markdown → 66 front tests. All green, `-race` clean. | |
| 27 | - **Quality**: gate PASS (0/0/0, total complexity 281). Iterations: biome 1.9 rejects the `noStaticElementInteractions` suppression (rule doesn't exist there — removed), the dangerouslySetInnerHTML suppression must sit between JSX attributes, EditorPane/ToolContent refactored (extracted EditorHeader/editorPlaceholder/TextToolContent) to clear return/complexity smells. | |
| 28 | - **Docs**: new how-to `use-the-workspace` + reference `workspace-api` in both languages; architecture pages and indexes updated; drawio diagram extended (files, terminal, pty, SPA runtime edges); root README. | |
| 29 | ||
| 30 | ## 2026-09-17 — Source code analysis document (new session) | |
| 31 | ||
| 32 | - **Goal**: analyse the source code and produce a summary as an AsciiDoc document. | |
| 33 | - **Changes**: new `docs/source-code-analysis.adoc` — overview, backend package table, frontend module/component inventory, HTTP/WS endpoints, bridge protocol summary, test counts (55 Go tests + 1 e2e, ~215 vitest cases), Makefile targets, design decisions, known limitations. No code changed. | |
| 34 | - **Method**: read `.memory/` first, then an Explore agent verified the memory picture against the sources (LOC: ~3,064 Go / ~3,252 TS-TSX). | |
| 35 | - **Tests / quality**: not run — documentation-only session, no code touched. | |
| 36 | ||
| 37 | ## 2026-09-17 — Workspace polish: AsciiDoc fix, VS Code-style tree with Material icons, dark terminal (same session, follow-up 3) | |
| 38 | ||
| 39 | - **Goal**: user feedback after trying the workspace — AsciiDoc preview broken in production ("m is not a function"), file tree should look like VS Code's with Material icons, terminal should always be dark. | |
| 40 | - **Changes**: AsciiDocView now uses @asciidoctor/core v4's real API — `convert` is a **named export and asynchronous** (the v3 `asciidoctor()` factory no longer exists; my CJS-default cast called `undefined()`); added a **non-mocked** AsciiDocView test rendering with the real converter — the mocked-only tests were exactly why the breakage reached production. FileTree restyled VS Code-like: `vscode-material-icons` (910 SVGs copied to `ui/public/material-icons/` by `ui/scripts/copy-icons.mjs`, npm pre-hooks on dev/build, gitignored), chevrons, indent guides, open-folder icons, active-file highlight. Terminal always dark (`#1e1e1e`) whatever the app theme. | |
| 41 | - **Tests**: +2 real AsciiDoc render, +2 FileTree (icons present, active highlight) → 70 front tests, all green; Go untouched (46). | |
| 42 | - **Quality**: gate PASS. | |
| 43 | ||
| 44 | ## 2026-09-17 — Inline monospace for backticked commands (same session, follow-up 4) | |
| 45 | ||
| 46 | - **Goal**: user feedback — tool titles like ``Run `ls .memory/` `` showed literal backticks in a proportional font. | |
| 47 | - **Changes**: new `InlineText` component (backtick spans → `<code class="inline-code">`, no markdown pipeline), applied to tool call titles, permission titles and plan entries; `.inline-code` CSS. | |
| 48 | - **Tests**: +4 InlineText (spans, multiples, plain, unpaired backtick) and +1 ToolCallCard title assertion → 75 front tests green. | |
| 49 | ||
| 50 | ## 2026-09-17 — sbx template + kit for ori (same session, follow-up 5) | |
| 51 | ||
| 52 | - **Goal**: package ori as a Docker Sandboxes template (image `k33g/ori`, the user builds it under their handle) and add a kit to launch it easily from sbx. | |
| 53 | - **Changes**: `template/Dockerfile` (multi-stage: node builds the SPA, go builds the binaries, final layer = `docker/sandbox-templates:claude-code` + globally installed `@zed-industries/claude-code-acp` + `/usr/local/bin/{ori,ori-mock-agent}`, EXPOSE 8888, standalone CMD), `.dockerignore` (excludes the 635MB `sandboxes/` checkout, node_modules, .git…), `kits/ori/spec.yaml` (schemaVersion 2 mixin: idempotent `setup.startup` launching ori as the agent user on :8888, agentInstructions), `kits/ori/README.md`, `make template`, how-to `run-in-a-sandbox` in docs en+fr. | |
| 54 | - **Decisions**: no `sbx template build` exists — a template IS a container image passed via `sbx create claude --template k33g/ori`, and `--kit` accepts a mixin directory (verified in `sandboxes/docs/yml/sbx_create_claude.yaml`); the ori kit adds no network permissions (Anthropic hosts come from the claude agent kit, the adapter is baked into the image); kit startup guarded by `pgrep -x ori` because startup commands re-run on every container start. | |
| 55 | - **Tests/validation**: image built locally (2.81GB) and smoke-tested standalone with the mock agent (healthz + session OK); the kit's exact startup command exec'd in a sleeping container of the image → adapter session created, healthz OK; idempotency check OK; kit YAML parse-validated. | |
| 56 | ||
| 57 | ## 2026-09-17 — Kit refinements from the sbx source deep-dive (same session, follow-up 5b) | |
| 58 | ||
| 59 | - A thorough exploration of the sbx source confirmed the template/kit design and yielded three refinements applied to `kits/ori/spec.yaml`: `requires: {agent: claude}` (mixin-only field, enforces composition with the claude agent kit), a `ports:` block (container 8888 — kits auto-publish an ephemeral localhost port at create; Dockerfile EXPOSE is read by nothing), and dropping `user: "agent"` from the startup step (StartupCommand.user defaults to "1000", the agent uid; "agent" is non-standard). | |
| 60 | - Also learned and documented: sandboxd has its own image store — a never-pushed local image reaches it via `docker save` + `sbx template load`; kit references resolve fresh each create (no local kit registry); `sbx kit validate/pack/push` exist for distribution; an alternative shape (kind:sandbox + `extends: claude` + `sandbox.image: k33g/ori`) would allow `sbx create ./kits/ori .` in one argument — not adopted, the mixin matches the dev-toolkit pattern already in use. | |
| 61 | ||
| 62 | ## 2026-09-17 — build.sh, Hub publication at 0.0.0, parameterized kit port, quickstart (same session, follow-up 5c) | |
| 63 | ||
| 64 | - **Goal**: user wants to push `k33g/ori` to Docker Hub — a `template/build.sh` they run themselves, image tagged `0.0.0`; the kit's listen port made configurable; a `quickstart.md` with the sandbox-creation commands. | |
| 65 | - **Changes**: `template/build.sh` (multi-arch buildx --push, tags 0.0.0 + latest, VERSION as $1, PLATFORMS overridable); `kits/ori/spec.yaml` gained `args.port` (default "8888", pattern-validated) substituted into `ports.container` (unquoted `${{ kit.args.port }}` — the source's expand.go explicitly re-infers it as an integer), the startup `--addr`, and the agentInstructions; `quickstart.md` at the repo root; kit README and both run-in-a-sandbox pages now reference `k33g/ori:0.0.0` and `--kit-arg ori.port=`. | |
| 66 | - **Validation**: spec YAML parses with the arg refs; build.sh is the push path, `make template` stays the local-only path. The actual Hub push is the user's action (their Docker login). | |
| 67 | ||
| 68 | ## 2026-09-17 — Multi-arch build fix: no qemu in the template build (same session, follow-up 5d) | |
| 69 | ||
| 70 | - **Problem**: the user's `./template/build.sh` failed on the linux/amd64 half — on an arm64 host that stage runs under qemu, where Vite bundling Monaco exhausts Node's 2GB heap ("FATAL ERROR: Ineffective mark-compacts near heap limit", "qemu: uncaught target signal 6"). | |
| 71 | - **Fix**: every build stage now runs on `--platform=$BUILDPLATFORM`: the SPA build is platform-independent (built once, natively), Go cross-compiles with `GOOS=$TARGETOS GOARCH=$TARGETARCH`, and the ACP adapter is npm-installed in a native stage then COPY'd into the template's npm prefix (`/usr/local/share/npm-global`, agent-owned, on PATH). The final stage contains no RUN at all, so a multi-arch build never invokes qemu. | |
| 72 | - **Validation**: native rebuild green; smoke tests pass (healthz with mock agent; `claude-code-acp` resolves from the copied prefix and initializes a real ACP session). | |
| 73 | ||
| 74 | ## 2026-09-17 — Kit startup fix: su resets PATH (same session, follow-up 5e) | |
| 75 | ||
| 76 | - **Problem**: the user's real `sbx create … --kit ./kits/ori -p 5555:8888` came up with nothing listening. Root cause read from the sbx source (`sandboxlib/kit/durable_startup.go`): startup commands are rendered as `exec su -s /bin/sh -c '<script>' agent`, and util-linux `su` always resets PATH to the login.defs default — which lacks `/usr/local/share/npm-global/bin`, so ori died instantly with "claude-code-acp: executable file not found". Reproduced in the image (`su -c 'command -v claude-code-acp' agent` → missing); my earlier validation had used `docker exec`, which preserves image ENV — that's why it passed. | |
| 77 | - **Fix**: the kit's startup script now exports `PATH="/usr/local/share/npm-global/bin:/home/agent/.local/bin:$PATH"` first (comment marks it load-bearing). Re-validated through the exact `su` path: healthz OK, ACP session created. | |
| 78 | - **No image rebuild needed** — kit-side only; the user must `sbx rm` and recreate the sandbox for the new kit to apply. Debug window for kit startup: `/var/log/sbx-kit-startup.log` (dispatcher log) + `/home/agent/.ori.log`. | |
| 79 | ||
| 80 | ## 2026-09-17 — Session end inside the sandbox: WS-offline investigation in flight (follow-up 5f) | |
| 81 | ||
| 82 | - After the su-PATH fix, the user's sandbox serves the SPA on localhost:5555 but the UI shows "offline" (the WebSocket to /ws does not stay up). Established before stopping: ori's WS handshake is correct against browser-like Origin headers (101 for localhost:* origins, 403 for foreign — tested with curl against the image); sbx port publishing goes through gvisor's port mapper (raw L4, so the upgrade should pass). Three discriminating diagnostics were handed to the user (server log; WS handshake from inside the sandbox; WS handshake through the forward) — answers not yet received. The session ends here: the user is relaunching the assistant outside sbx. | |
| 83 | - Everything since commit 2434cc7 is still uncommitted (user's call, repeatedly deferred). | |
| 84 | ||
| 85 | ## 2026-09-17 — Why the ori sandbox stops on its own: sbx auto-stop investigation (follow-up 6, read-only) | |
| 86 | ||
| 87 | - **Asked**: the sandbox created with `sbx create claude . --template k33g/ori:0.0.0 --kit ./kits/ori --name ori -p 8888:8888` serves the webapp then goes `stopped` by itself; find the auto-stop mode in the sbx source and a way to disable it. | |
| 88 | - **Found** (in `sandboxes/`, the vendored sbx checkout, v0.43.0 daemon on this Mac): sandboxd counts "sentinel" long-poll sessions per sandbox (`GET /sandbox/{name}/session`, `holdSession` in `sandboxd/pkg/server/backend_dockernext.go`); when the count hits zero it stops the container after a hard-coded 30 s grace (`WithAutoStopDelay(30*time.Second)` in `setupDockerNextBackend`). `sbx create` holds a sentinel only for its own lifetime (`executeCreateAndReleaseSession` in `cli-plugin/commands/create.go`), so the stop fires 30 s after the command returns — confirmed by the daemon log (`session disconnected, deferring auto-stop` → `auto-stopped runtime` 30 s later for `ori` and `ori2`). Port publishing and browser traffic hold no session. | |
| 89 | - **Escape hatch**: the create-time spec field `detached: true` (openapi `SandboxCreateRequest.detached`) makes `holdSession` never auto-stop. Only `sbx run -d/--detached` sets it (`create_daemon.go: Detached: opts.detached`); `sbx create` has no such flag; there is no update API, no `sbx settings` key and no env var for the delay. | |
| 90 | - **Recommendation given**: `sbx rm ori` then `sbx run -d claude . --template k33g/ori:0.0.0 --kit ./kits/ori --name ori -p 8888:8888`. | |
| 91 | - **Docs switched (same session, at the user's request while they tested)**: `quickstart.md`, `kits/ori/README.md`, `docs/en|fr/how-to/run-in-a-sandbox.md` now use `sbx run -d`, explain the 30 s auto-stop and why detached is the fix, and add a restart line (`sbx run -d --name <name>`) plus a daemon-log diagnostic hint. No `sbx create` invocation remains in project docs. No code change. | |
| 92 | - **Also observed**: the WS-"offline" symptom from follow-up 5f is very plausibly this same stop (the page was already loaded when the container died), still to be confirmed by the user. | |
| 93 | ||
| 94 | ## 2026-09-17 — Three parallel agents: ori-desktop (Wails), @/skill selectors + draw.io/image previews, ACP command inventory | |
| 95 | ||
| 96 | - **Asked**: (bob) create `ori-desktop/`, a Wails app connecting to the ori webapp; (riker) add an `@` file selector, a skill selector, draw.io and image previews; (milo, read-only) list the ACP commands exposed. Then the user built ori-desktop on their Mac: Check OK, Connect "did nothing". | |
| 97 | - **bob**: new module `ori-desktop/` (Wails v2.16.0, plain template, iframe embed of the ori SPA, settings JSON, bound methods, `internal/settings` + `internal/health` with 12 tests, EN+FR READMEs, `make desktop`/`desktop-test`, .gitignore, ticket 0005 filled). Verified: tests, vet, gofmt, Windows cross-build, root `make build`/`make test` unaffected. Not verifiable in the sandbox: running the window (no gcc/webkit2gtk). | |
| 98 | - **riker**: `GET /api/files/search`, `GET /api/raw`, new `internal/skills` + `GET /api/skills`; `prompt.attachments` → ACP `resource_link` blocks (`Prompter.Prompt(blocks)` replaces `PromptText`, `Bridge.SetWorkspaceRoot`); reducer stores `available_commands_update` commands; `mentions.ts`, `useCompletion.ts`, `CompletionPopup`, rewritten `PromptInput`, `ImageView`, `DrawioView` (embed.diagrams.net + Source fallback), `lang.ts` kinds `image`/`drawio`; mock agent emits commands and echoes attachments; Vite dev proxy gained `/api`; `biome format --write` reformatted 11 files. Docs EN+FR: workspace-api, websocket-protocol, use-the-workspace, new how-to `mention-files-and-skills`, architecture sections, READMEs. Tickets 0008/0009/0011/0012 filled. | |
| 99 | - **milo**: ori calls `initialize`, `session/new`, `session/prompt`, `session/cancel`; serves `session/update`, `session/request_permission`, `fs/read_text_file`, `fs/write_text_file`; refuses `terminal/*`; unused stable methods: `authenticate`, `logout`, `session/load|resume|list|close|set_mode|set_config_option`. "Agent commands" are not ACP methods: `available_commands_update` → `/name` text in the prompt. Relayed to riker, who implemented it (ticket 0008). | |
| 100 | - **Bug fixed after the user's test**: `ori-desktop/frontend/src/main.css` — `#connect-screen {display:grid}` outranked `.screen[hidden]`, so Connect (and the startup auto-connect) rendered the viewer below the fold; now class `.connect` + `.screen[hidden] {display:none !important}`. Rebuild needed (`wails build`); iframe content in WKWebView still unconfirmed. | |
| 101 | - **Tests**: `make test` → 9 Go packages ok, vitest 16 files / 102 tests (was 66); `go test -race ./...` ok (riker installed gcc + libc6-dev via apt in the sandbox for it). | |
| 102 | - **Quality gate**: NOT run — qlty absent from this sandbox (`~/.qlty` missing). gofmt / go vet / biome check clean. | |
| 103 | - Nothing committed (still everything since 2434cc7). | |
| 104 | ||
| 105 | ## 2026-09-17 — Launch ori for manual testing of the new features (evening session) | |
| 106 | ||
| 107 | - **Asked**: "lance ori que je puisse tester les nouveautés". No code change: `make build` (SPA + binaries), then `env -u CLAUDECODE nohup ./bin/ori --addr 0.0.0.0:8888 > /tmp/ori.log 2>&1 &` inside the `claude-ori` sandbox. Adapter `@zed-industries/claude-code-acp@0.16.2` resolved via npx (npm now flags it deprecated → renamed `@agentclientprotocol/claude-agent-acp`; still works). ACP session ready, `/healthz` ok, `/api/skills` lists the skills. Port 8888 must be published on the host with `sbx ports claude-ori --publish 8888:8888/tcp` (not doable from inside the sandbox). | |
| 108 | - Trap hit: a `curl` WebSocket handshake against `/ws` never returns on success (101 keeps the socket open) — use `-m` or check the log instead. | |
| 109 | - **Follow-up (same session)**: first real prompt failed with `-32603 There's an issue with the selected model (fable[1m])`. Root cause: `@zed-industries/claude-code-acp@0.16.2` bundles `@anthropic-ai/claude-agent-sdk@0.2.44`, whose embedded Claude Code CLI is **2.1.44** (zero mentions of Fable), while `~/.claude/settings.json` sets `"model": "fable[1m]"` and the adapter forwards it verbatim. The system CLI (2.1.275) accepts `fable[1m]` fine. Fix without touching the user's settings: the adapter honours `CLAUDE_CODE_EXECUTABLE` → `pathToClaudeCodeExecutable`; ori relaunched with `CLAUDE_CODE_EXECUTABLE=/home/agent/.local/share/claude/versions/2.1.275`; a WS prompt round-trip returned `pong` (`turn_ended end_turn`). No code change. | |
| 110 | ||
| 111 | ## 2026-09-17 — Resizable file explorer column (ticket 0015), via methodical-dev | |
| 112 | ||
| 113 | - **Goal**: make the workspace file tree column resizable with the mouse; user chose localStorage persistence and the file-tree divider only (not the chat/workspace split). | |
| 114 | - **Changes**: `ui/src/workspace.ts` (`fileTreeWidth`, `setFileTreeWidth`, `resetFileTreeWidth`, `clampFileTreeWidth`, constants, guarded localStorage), new `ui/src/components/ResizeHandle.tsx` (+ test), `Workspace.tsx` (handle between tree and tabs, `--filetree-width` on the aside; new `Workspace.test.tsx`), `app.css` (`.filetree` width from the variable, `.resize-handle` styles). Ticket 0015 closed. | |
| 115 | - **Decisions**: width in px (drag produces px; comparable with bounds); FileTree untouched — width reaches CSS via a custom property; handle owns no width, the store clamps. jsdom 26 has no PointerEvent → test-local MouseEvent polyfill. | |
| 116 | - **Quality gate** (first run of qlty on the tree since the parallel-agents session): 12 errors / 1 warning / 2 smells, all pre-existing — fixed without weakening anything: `ori-desktop/frontend/src/main.js` became an ES module (`type="module"`, IIFE and `"use strict"` dropped, optional chains, template literals, `reloadFrame()` instead of `src = src`), `internal/files/raw.go` explicit `_ = file.Close()` with rationale, `internal/files/search.go` walk callback → `searchWalker.visit/visitDir/collect`, `PreviewPane.tsx` loading effect → `usePreviewFile` hook; `qlty fmt` on main.css / main.js / wails.json. Run #15 PASS (0/0/0, complex 507). | |
| 117 | - **Tests**: 118 vitest (18 files), 9 Go packages, ori-desktop 2 packages — green. `make test`. | |
| 118 | - **Docs**: how-to `use-the-workspace` (step 5 + keyboard/persistence variant) and architecture explanation, EN + FR; root README; ori-desktop READMEs (ES module). | |
| 119 | - **Not verifiable here**: the ori-desktop frontend change (ES module) needs a `wails build` + launch on the user's Mac. | |
| 120 | ||
| 121 | ## 2026-09-17 — Light / dark theme selector, light by default (ticket 0013) | |
| 122 | ||
| 123 | - **Goal**: user request received mid-session; choices made via AskUserQuestion: two themes only (no "system" option), single review at the end. | |
| 124 | - **Changes**: new `ui/src/theme.ts` (+ `theme.test.ts`), `app.css` (dark palette on `:root[data-theme="dark"]`, `color-scheme` per theme, `.topbar-theme`), `App.tsx` (☾/☀ button, aria-label "Switch to dark/light theme"), `MonacoViewer.tsx` (store instead of `matchMedia`), `main.tsx` (side-effect import so the theme is stamped before the first render), `App.test.tsx` (+1). Ticket 0013 closed. | |
| 125 | - **Decisions**: dropping `prefers-color-scheme` is a behaviour change (dark-OS users now get light until they toggle) — accepted by the user ("light par défaut"); documented in the architecture explanation. Terminal keeps its dark background (pre-existing decision). | |
| 126 | - **Tests**: 124 vitest / 19 files green; Go untouched. **Quality**: run #16 PASS (0/0/0, complex 514). | |
| 127 | - **Docs**: new how-to `switch-the-theme.md` EN + FR, both indexes, architecture explanation paragraph EN + FR, root README. | |
| 128 | - ori rebuilt and restarted on :8888 for the user's review. | |
| 📝 Update project memory after the merge into main | 129 | |
| 130 | ## 2026-09-17 — Commit and merge into main | |
| 131 | ||
| 132 | - User asked to merge `feat/acp-webapp` into `main`. Everything since 2434cc7 committed as `76d62ac` (203 files, +21 595 lines), excluding `hello.md` (test artefact) and `.claude/settings.local.json` (local permissions). `main` fast-forwarded (merge base was 4edda86, no divergence). Not pushed to `origin` (git.rickub.com) — not asked. This memory update itself is a follow-up commit on main. | |
| 🛟 Updated. | 133 | |
| 134 | ## 2026-09-18 — Diagnose `git push --set-upstream origin main` hanging | |
| 135 | ||
| 136 | - **Asked**: why the first push to `origin` never finishes. Diagnostic only; no code or config changed. | |
| 137 | - **Finding**: `origin` is `https://git.rickub.com/bots-garden/ori.git`; the server answers 401 on `git-receive-pack`, the macOS keychain has no entry for that host, and the session (launched from VSCodium's terminal) exports `GIT_ASKPASS` → VSCodium's `askpass.sh`. Git therefore hands the password prompt to VSCodium's input box, which is easy to miss, so the push waits forever. Confirmed with `ps`: `git-remote-https` → `askpass.sh "Password for 'https://git.rickub.com'"` blocked. | |
| 138 | - **Also verified**: network fine (DNS, 443, 22 all open); anonymous read over HTTPS works; SSH key `~/.ssh/id_ed25519` is accepted by `git@git.rickub.com` (server replies "serves git only"); `git ls-remote` over SSH succeeds and shows the remote repo is **empty** (no branches yet). Local `main` = 34e69b5. | |
| 139 | - **Recommendation left to the user**: switch `origin` to `git@git.rickub.com:bots-garden/ori.git` (no password, key already trusted), or run the push in a plain terminal with `GIT_ASKPASS` unset so osxkeychain stores the credentials. Not applied — awaiting the user's choice. |