docs: correct stale architecture references

Found by a docs/ staleness audit:
- architecture.md: Claude no longer runs under tmux — it's driven over
  the stream-json control protocol with --resume (D-75/D-77/D-78); and
  the IPC socket server is implemented, not "currently unimplemented".
- testing/README.md + claude-ui-workflow.md: drop the dissolved app/
  two-package paths (D-56) — tests live at test/ and the web build at
  build/web/.
- design/multitab-pane.md: the Claude pane spawns a stream-json session,
  not a tmux one; ClaudeSessionRef carries the session id.

Frozen historical snapshots (initial-plan.md, the HISTORICAL pty docs,
dated spikes/audits) left as-is.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-10 17:39:31 +02:00
co-authored by Claude Opus 4.8
parent 4a9f57b14a
commit 62f9975b06
4 changed files with 20 additions and 16 deletions
+12 -8
View File
@@ -33,9 +33,12 @@ One OS process. The Flutter app hosts:
- every subsystem handler (pane/files/editor/git/pql),
- the extension manager and all built-in extensions.
`tmux` is the only external long-lived process — it owns Claude
session persistence so panes survive app restarts (D-41). The app
re-attaches via `tmux new-session -A` on boot.
The Claude pane is driven over Claude Code's stream-json stdio control
protocol — clide spawns the `claude` child directly and renders its
event stream natively (D-75/D-77/D-78). Session continuity is
`--resume <session-id>` (state lives in Claude's transcript files), not
a long-lived wrapper process. `tmux` is no longer in the Claude path; it
is retained only by the general-purpose terminal builtin.
PTYs are spawned natively from Dart. `lib/src/pty/native_pty.dart`
calls `posix_openpt()` + `posix_spawn()` via FFI; the child inherits
@@ -74,11 +77,12 @@ state-changing command emits one or more events on a long-lived
event stream; every UI affordance has a matching CLI verb. See D-6
for the subsystem/verb/event contract.
> **Caveat (2026-05):** the Unix-socket server that exposes the
> dispatcher to a thin `clide` C client is currently unimplemented.
> Today's working path is in-process direct dispatch. See **T-99**
> (IPC server implementation) and **D-68** (dual integration surface
> — Bash CLI primary, MCP secondary).
The Unix-socket server that exposes the dispatcher to a thin `clide` C
client (`native/clide-cli/clide.c`) is implemented in
`lib/src/ipc/server.dart`; the socket path, access control, and dispatch
model are pinned by D-70/D-71/D-72. In-process direct dispatch remains
the path for the Flutter app's own subsystem calls. See **D-68** (dual
integration surface — Bash CLI primary, MCP secondary).
### User-facing — Flutter desktop
+3 -3
View File
@@ -79,8 +79,8 @@ The widget is a thin shell:
- Calls `bodyBuilder(active)` for the visible content
- Routes user gestures to controller methods or callbacks
- Emits `onCloseRequested` / `onAddRequested` so the host decides
the actual lifecycle (e.g. Claude pane spawns a new tmux session,
doesn't just append a UI tab)
the actual lifecycle (e.g. the Claude pane spawns a new stream-json
session, doesn't just append a UI tab)
The host owns the controller and the payload type. The widget never
touches PTY, IPC, or Claude session naming.
@@ -138,7 +138,7 @@ ClaudePane (host)
)
```
`ClaudeSessionRef` carries the tmux session name + isPrimary. The
`ClaudeSessionRef` carries the stream-json session id + isPrimary. The
controller is seeded with `[primary]` on boot; secondaries get
appended as the user clicks `+`. Closing a secondary triggers
`pane.close` IPC and removes the entry; closing the primary is not
+4 -4
View File
@@ -8,10 +8,10 @@ on any Linux or macOS dev box without network access or shared state.
| layer | location | runner | time | when |
|---|---|---|---|---|
| unit (root) | `test/` | `dart test` | ~5s | `make test` |
| unit + widget + golden (app) | `app/test/` | `flutter test` | ~30s | `make test` |
| a11y contract | `app/test/a11y/` | `flutter test` | ~5s | `make test-a11y` |
| integration (startup gate) | `app/integration_test/` | `flutter test integration_test/` | ~60s | `make test-integration` |
| unit (Flutter-free core) | `test/ipc/`, `test/daemon/`, `test/pty/` | `dart test` | ~5s | `make test-core` |
| unit + widget + golden | `test/` | `flutter test` | ~30s | `make test` |
| a11y contract | `test/a11y/` | `flutter test` | ~5s | `make test-a11y` |
| integration (startup gate) | `integration_test/` | `flutter test integration_test/` | ~60s | `make test-integration` |
| daemon E2E + web WASM smoke | `test/daemon/` + `tools/ui/tests/` | `dart test` + Playwright | ~60s | `make test-e2e` |
| startup bundle smoke | `ci/smoke_bundle.sh` | xvfb-run, 5s timeout | ~30s | `make smoke-bundle` |
+1 -1
View File
@@ -4,7 +4,7 @@ Claude Code needs to *actually use* the app while building features.
The pipeline:
1. **Flutter builds the app to WASM.** `flutter build web --wasm` ships
a CanvasKit/Skwasm bundle under `app/build/web/`.
a CanvasKit/Skwasm bundle under `build/web/`.
2. **A local server serves it.** `tools/ui/serve.sh` starts
`http://localhost:4280` in the background with a pidfile.
3. **Playwright drives a headless Chromium.** Instead of click-by-pixel