diff --git a/.cursor/skills/verify-pace/SKILL.md b/.cursor/skills/verify-pace/SKILL.md
index fd0a3187..a0ecada5 100644
--- a/.cursor/skills/verify-pace/SKILL.md
+++ b/.cursor/skills/verify-pace/SKILL.md
@@ -11,7 +11,7 @@ Read `features/README.md` before driving. One feature file is the recipe. A proo
## Launch
-Human quickstart (hot reload, writes `~/.pace-dev` and a `Pace-dev` userData profile) is `bun install` then `bun run dev`. See README "Quick start" and `docs/dogfooding.md`. Do not use that process for a scripted proof.
+Human quickstart (hot reload, writes `~/.pace-dev` and a `Pace-dev` userData profile) is `bun install` then `bun run dev`. See "Setup" in `CONTRIBUTING.md` and `docs/dogfooding.md`. Do not use that process for a scripted proof.
Verification launch:
diff --git a/AGENTS.md b/AGENTS.md
index 0e50e133..eaaee7ae 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -6,7 +6,7 @@ Pace is the desktop workbench for the [Pi coding agent](https://pi.dev). Pi is t
## Orientation
-The "Architecture" section of `README.md` is the canonical map: the event-pipeline diagram, the "Where things live" table (which file to edit for which concern), and the step-by-step prompt flow. Consult it before searching the codebase. Backend modules mirror that map: `packages/backend/src/{drivers,gateway,persistence,workspace}` with `service.ts` as the composition root.
+`docs/architecture.md` is the canonical map: the event-pipeline diagram, the "代码在哪里" (Where things live) table (which file to edit for which concern), and the step-by-step prompt flow. Consult it before searching the codebase. Backend modules mirror that map: `packages/backend/src/{drivers,gateway,persistence,workspace}` with `service.ts` as the composition root.
Process conventions, each documented in its own file:
@@ -17,7 +17,7 @@ Process conventions, each documented in its own file:
## Verification
-Before opening a PR, `bun run typecheck`, `bun run lint`, `bun run test` and `bun run build` must be green (see "Development and verification" in `README.md` for the full command list, including E2E and packaging).
+Before opening a PR, `bun run typecheck`, `bun run lint`, `bun run test` and `bun run build` must be green (see `CONTRIBUTING.md` for the full command list, including E2E and packaging).
## Design system discipline
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 7f01ed60..06f6b31b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -61,10 +61,46 @@ All four must be green. Also:
UI work has extra rules in [`docs/design/`](docs/design/). Discover Astryx components before writing new ones; reusable pieces live only in `shared/ui/`.
+## Testing, packaging and dev tools
+
+The four commands above are the PR gate. Two more suites cover the edges:
+
+```bash
+bun run test:e2e # Playwright smoke tests against the dev Electron build
+bun run test:release # release script and publish behavior tests
+```
+
+The manual `Validate macOS ARM64` workflow runs packaging and the packaged-app E2E on demand.
+
+Packaging:
+
+```bash
+bun run package:mac:unsigned # unsigned .app + zip, for local testing
+bun run dist:mac # signed + notarized DMG (needs Apple credentials)
+bun run dist:linux # AppImage + deb (x64)
+```
+
+The signing, notarization and release pipeline is documented in [`docs/release/macos.md`](docs/release/macos.md). Linux AppImage and deb builds ship on the same tag: [`docs/release/linux.md`](docs/release/linux.md).
+
+Two dev-only tools help when working on the UI locally:
+
+- The `/design` route: a live gallery of the design system, showing every base component under `shared/ui/` with all of its states and variants.
+- The **UI Intent Picker**: press `Cmd/Ctrl+Shift+X` to activate a crosshair, then click any element to copy its CONTEXT.md term, its component stack with file and line, and the nearest `data-testid` (see [`docs/ui-intent-picker.md`](docs/ui-intent-picker.md)).
+
## A good first PR
Add a new fixture stream to the event normalizer (`packages/backend/src/gateway/agent-runtime-event-normalizer.test.ts`): record a Pi session, add the raw events, and assert the normalized `AgentRuntimeEvent` sequence. That exercises the protocol without touching UI.
+## Documentation map
+
+- [`docs/architecture.md`](docs/architecture.md): the canonical code map — the event pipeline, which file owns which concern, and the step-by-step prompt flow.
+- [`CONTEXT.md`](CONTEXT.md): domain glossary. The terms here are the names used in code, tests and issues.
+- [`docs/adr/`](docs/adr/): architecture decision records, from the control-plane pivot ([ADR-0001](docs/adr/0001-agent-workspace-control-plane.md)) to the current surfaces.
+- [`docs/design/`](docs/design/): which tokens, which Astryx variants, which self-built components.
+- [`docs/release/macos.md`](docs/release/macos.md), [`docs/release/linux.md`](docs/release/linux.md), [`docs/dogfooding.md`](docs/dogfooding.md): shipping and daily-driving Pace.
+- [`docs/agents/`](docs/agents/): how issues, triage labels and domain docs are organized for both human and agent contributors.
+- [`.scratch//PRD.md`](.scratch/): point-in-time product requirement records.
+
## License
Contributions are accepted under the [Apache License 2.0](LICENSE). There is no CLA. The Pace name and icon are not covered by that grant.
diff --git a/README.md b/README.md
index 7982ad3d..2f76ac2c 100644
--- a/README.md
+++ b/README.md
@@ -10,9 +10,10 @@
+
-Pi is a coding agent that runs in the terminal, with a highly extensible system in the spirit of VS Code: packages contribute tools, commands, skills, prompts and themes. We want to bring that flexibility to a desktop application, so that developers can freely shape a desktop agent that is truly their own. The name comes from *move at your own pace*: in the age of AI, developers should keep full ownership of their agent, and set their own rhythm for how they build and collaborate.
+Pi is a coding agent that runs in the terminal, extensible in the spirit of VS Code: packages contribute tools, commands, skills, prompts and themes. Pace brings that flexibility to the desktop, so you can shape a desktop agent that is truly your own. The name comes from *move at your own pace*: developers should keep full ownership of their agent and set their own rhythm.
> [!NOTE]
> Pace is in early `0.y.z` development. Only the latest version on GitHub Releases is supported. Journal and projection formats may change between minor versions; the in-app updater handles upgrades. Pi's session data is unaffected (see [Local data and recovery](#local-data-and-recovery)).
@@ -23,191 +24,56 @@ Pi is a coding agent that runs in the terminal, with a highly extensible system
## Highlights
-- **Session timeline**: follow the agent's chain of thought and tool calls in order, alongside token usage and cost for each turn. Watch execution live or replay recorded sessions to see what happened at each step and what it cost.
-- **Session Dock panels**: Changes, Files, Terminal and the embedded Browser share one sidebar. Pi extensions can also contribute their own panels.
-- **A consistent, customizable interface**: [Astryx](https://github.com/facebook/astryx) components and open design tokens give built-in views and custom components shared colors, spacing and interaction conventions. Astryx's component styles are precompiled by [StyleX](https://engineering.fb.com/2025/11/11/web/stylex-a-styling-library-for-css-at-scale/) into reusable atomic CSS, reducing duplicate rules without generating stylesheets at runtime. Developers and agents can use the Astryx CLI to look up components and choose templates, following the same design conventions when building new views.
-- **Pi remains the only engine**: Pace is not a fork of Pi or a separate runtime. Pi's local logs remain the source of truth for sessions; uninstalling Pace does not delete Pi sessions.
+- **Session timeline**: follow the agent's chain of thought and tool calls in order, with token usage and cost for every turn. Watch a run live, or replay a recorded session to see what each step did and what it cost.
+- **Session Dock**: Changes, Files, Terminal and an embedded Browser share one sidebar next to the conversation.
+- **Your Pi setup, as is**: Pace shares the sessions, auth and extensions under `~/.pi/agent`, and the Packages page manages Pi packages without leaving the app.
+- **Pi remains the only engine**: Pace is not a fork of Pi or a separate runtime. Pi's local logs stay the source of truth; uninstalling Pace never deletes a Pi session.
-## Quick start
-
-### Install
+## When Pace is not a fit
-**Prebuilt installers (recommended).** Each [GitHub Release](https://github.com/BubblePtr/pace/releases) ships a signed and notarized DMG for Apple Silicon Macs, plus a Linux x64 AppImage and deb.
+- You use Pi in the terminal and do not need a graphical view of cost, chain of thought or tool calls.
+- You are on Windows or an Intel Mac. Installers exist for Apple Silicon Macs and 64-bit Linux only.
+- You want an agent client that does not depend on Pi. Pace has no agent loop of its own; Pi handles inference and context management.
-- **macOS.** Open the DMG and drag Pace into Applications. Later updates install from the app (ADR-0033).
-- **Linux AppImage.** `chmod +x` the AppImage and run it. This is the build that receives in-app updates. If it fails to start because FUSE is missing, run it with `--appimage-extract-and-run`.
-- **Linux deb.** Install with `apt`. Deb builds do not auto-update; install the new package when you want to upgrade.
+## Quick start
-Details: [`docs/release/linux.md`](docs/release/linux.md).
+### Install
-**Run from source.** Requires Bun 1.3.x and Node 24:
+Each [GitHub Release](https://github.com/BubblePtr/pace/releases) ships a signed and notarized DMG for Apple Silicon Macs, plus a Linux x64 AppImage and deb.
-```bash
-git clone https://github.com/BubblePtr/pace.git pace
-cd pace
-bun install
-bun run dev
-```
+| Platform | Install | Updates |
+| --- | --- | --- |
+| macOS 12+ (Apple Silicon) | Open the DMG and drag Pace into Applications. | In-app |
+| Linux AppImage (x64) | `chmod +x` the file and run it. Without FUSE, add `--appimage-extract-and-run`. | In-app |
+| Linux deb (x64) | Install with `apt`. | Install the new package manually |
-**Requirements.** An Apple Silicon Mac running macOS 12 or later, or 64-bit Linux. The Pi runtime is bundled with the app (ADR-0031), so no separate `pi` install is needed. If Pi is already installed, Pace shares the sessions, auth configuration and extensions under `~/.pi/agent`. Windows and Intel Macs are not supported yet.
+The Pi runtime is bundled, so no separate `pi` install is needed. More Linux details: [`docs/release/linux.md`](docs/release/linux.md). To run from source instead, follow [Setup in CONTRIBUTING.md](CONTRIBUTING.md#setup).
### Start your first session
-1. On first launch, Pace checks the bundled Pi runtime, data directory and model provider login status, and shows where data will be saved (ADR-0025). If you have not signed in to a model provider, you can do so through `pi` in the terminal. Pace detects the new login state without a restart.
-2. After preflight passes, select a project directory and create a session.
-3. Send your first message, such as asking the agent to explain the repository's structure.
+1. On first launch, Pace checks the bundled Pi runtime, the data directory and your model provider login, and shows where data will be saved. If you are not signed in to a provider, run `pi` in a terminal and sign in there; Pace picks up the new login without a restart.
+2. Select a project directory and create a session.
+3. Send a first message, for example: *Explain this repo's architecture*.
4. Read the conversation in Live Chat, inspect the chain of thought and tool calls in Trajectory, and check the turn's token usage and cost in the status bar.
-## When Pace is not a fit
-
-- You use Pi in the terminal and do not need a graphical view of costs, chain of thought or tool calls.
-- You use Windows or an Intel Mac. Installers are Apple Silicon Macs and 64-bit Linux.
-- You want a standalone agent client that does not depend on Pi. Pace does not implement an agent loop; Pi handles inference and context management.
-
## Design principles
-- **Pace is a projection of session events; it never intrudes on the core context.** Pi's local session log (`~/.pi`) is the single source of truth, and Pi is always the real host of the session and its context. On resume, Pi rebuilds the LLM context from that log on its own. Pace never assembles a prompt and never modifies that log. Everything Pace persists is only a projection of Pi's event stream, kept in Pace's own directory.
-
-- **The UI is driven entirely by the event journal.** Every raw event Pi emits is normalized into an `AgentRuntimeEvent`, assigned a monotonically increasing sequence number and deterministic run / turn / message ids, and persisted to a journal. The live timeline, history replay, and token and cost accounting are all derived from that journal, never from volatile renderer state.
-
-- **Panels and behavior are decoupled from the client, and both can come from extensions.** The Pace client itself ships only a small set of core panels (Surfaces). The underlying event routing, the Session Dock registry and the Runtime Gateway capability model all follow a plugin-oriented design: a Pi extension can register its own panels, controls or workflow visualizations without waiting for a Pace release. This follows the same "everything is a plugin" idea as [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness); as their plugin model matures, Pace intends to borrow from it heavily.
-
-- **Monitoring and interaction never block the engine.** The backend runs in a separate Electron `utilityProcess`: heavy log parsing and driver crashes cannot make the GUI window stutter or hang. The backend protocol is decoupled from any specific transport, so it can later move behind a remote socket service without a rewrite.
-
-## Architecture
-
-The whole system is one unidirectional event pipeline plus two persistence tracks whose roles never swap ([ADR-0021](docs/adr/0021-session-fork-resume-persistence-layering.md)):
-
-```mermaid
-flowchart TB
- subgraph R["Renderer — apps/desktop · React 19 · FSD (pages → entities → shared)"]
- direction LR
- pages["Pages + entities
consume envelopes, route by surface stamp:
chat · trace · status · composer · hidden"]
- dock["Session Dock
Changes · Files · Terminal · Browser
+ extension surfaces (provider field reserved)"]
- pages --- dock
- end
-
- subgraph S["Electron main — apps/desktop/electron"]
- relay["preload.ts contextBridge + IPC relay
invoke ⇄ backend-event"]
- host["windows · updater · browser host · app menu"]
- relay --- host
- end
-
- subgraph B["Backend — packages/backend · utilityProcess (Node)"]
- svc["service.ts — composition root
RPC dispatch + event fan-out"]
- subgraph PL["the one event pipeline"]
- direction LR
- drv["SessionProcessDriver
one process per root Session"]
- gw["Runtime Gateway
seq + deterministic run/turn/message ids
+ capability advertisement"]
- drv --> gw
- end
- ws["workspace
sessions · execution checkouts · resources
preflight · provider auth · terminal pty"]
- svc --- gw
- svc --- ws
- gw -. "commands: prompt · queue · steer · stop · model" .-> drv
- end
-
- subgraph W["Root Session process — bundled Node"]
- pi["Pi SDK · tools · extensions
plugins own their subagents"]
- nz["Normalizer
raw events → AgentRuntimeEvent"]
- pi --> nz
- end
- drv -. "SDK driver commands" .-> pi
- nz -->|"IPC events"| drv
-
- R <-->|"contextBridge"| S
- S <-->|"MessageChannel port"| B
-
- gw ==>|"append boundary envelopes only"| jrnl[("Session Event Journal
~/.pace — presentation truth")]
- gw -->|"update"| proj[("Session Projection
~/.pace — query model")]
- pi -->|"owns"| pilog[("Pi session jsonl
~/.pi — context truth")]
-```
-
-- **Driver**: `SessionProcessDriver` gives every root Session its own process and working directory. Each process hosts the Pi SDK driver; plugins own their child Sessions ([ADR-0040](docs/adr/0040-root-session-process-isolation.md)). The SDK driver is the only Pi driver; the earlier CLI RPC driver was removed ([ADR-0041](docs/adr/0041-remove-pi-rpc-driver.md)).
-
-- **Normalizer**: converts the raw events Pi emits into a unified `AgentRuntimeEvent`, attaching a phase, a target surface and globally deterministic message ids ([ADR-0020](docs/adr/0020-agent-runtime-event-model.md)). The recorded fixture contract tests are the executable spec of this protocol.
-
-- **Runtime Gateway**: the only protocol interface the renderer talks to. Control commands go up; sequenced envelopes with monotonically increasing sequence numbers come down. The gateway dynamically advertises the capabilities of the current runtime (model switching, thinking controls, queueing and steering), so the UI follows what the runtime actually supports instead of static assumptions ([ADR-0024](docs/adr/0024-model-thinking-controls-follow-runtime-capabilities.md)).
-
-- **Persistence**: maintains the Session Event Journal (append-only, replayable as a timeline) and the Session Projection (a query model for fast list rendering and state statistics).
-
-- **Renderer**: routes each event by its `surface` stamp into Live Chat, the Trajectory (chain of thought and tool calls), the status bar or hidden background state. It also hosts the Session Dock sidebar, where both built-in and extension-contributed panels are mounted ([ADR-0032](docs/adr/0032-session-dock-and-trajectory-vocabulary.md)).
-
-### How a prompt flows
-
-1. The renderer issues a `send_prompt` request through the Runtime Gateway client (`apps/desktop/src/entities/runtime/runtime-gateway-client.ts`).
-
-2. The command crosses the MessagePort channel into the backend `utilityProcess` (`apps/desktop/electron/preload.ts`, `backend.ts`).
-
-3. `createBackendService()` dispatches it to the Runtime Gateway instance (`packages/backend/src/service.ts`).
-
-4. The Gateway assigns a globally deterministic user message id and forwards the command to the active driver (`packages/backend/src/gateway/runtime-gateway.ts`).
-
-5. The process driver forwards the command to that Session's worker, where the SDK driver calls Pi's `AgentSession` (`packages/backend/src/drivers/session-process-driver.ts`, `pi-sdk-driver.ts`).
-
-6. The worker's Normalizer converts Pi events into the standard format and sends them back over IPC (`packages/backend/src/gateway/agent-runtime-event-normalizer.ts`).
-
-7. The Gateway stamps each event with a monotonically increasing sequence number, records lifecycle boundaries and updates the projection (`packages/backend/src/persistence/`).
-
-8. Events stream back over the same transport, and the renderer routes each one to its UI component by its `surface` stamp (`apps/desktop/src/entities/runtime/`).
+- **Pi owns the context.** Pi's session log under `~/.pi` is the single source of truth. Pace never assembles a prompt and never writes to that log; it stores only projections of Pi's event stream, in its own directory.
+- **The event journal drives the UI.** Every Pi event is normalized, sequenced and appended to a journal. The live timeline, history replay and cost accounting are all derived from it.
+- **The GUI never blocks the agent.** The backend runs in a separate Electron `utilityProcess` and each root session runs Pi in its own process, so heavy log parsing or a crashing session cannot freeze the window.
+- **Built to be extended.** Event routing, the Session Dock and the gateway's capability model are designed so Pi extensions can add their own panels and controls. The protocol for that is the first item on the roadmap below.
-### Where things live
+How these principles turn into code: [`docs/architecture.md`](docs/architecture.md).
-| To change… | Go to… |
-| --- | --- |
-| UI, pages, interactions | [`apps/desktop/src/`](apps/desktop/src/), FSD layers `pages` → `widgets` → `features` → `entities` → `shared` ([ADR-0016](docs/adr/0016-fsd-layers-in-apps-desktop.md), [ADR-0045](docs/adr/0045-slice-agent-workspace-into-fsd.md)); `bun run lint` enforces the direction |
-| Live Session View / Session Draft / Session Dock | [`apps/desktop/src/widgets/live-chat/`](apps/desktop/src/widgets/live-chat/), [`features/session-draft/`](apps/desktop/src/features/session-draft/), [`widgets/session-dock/`](apps/desktop/src/widgets/session-dock/) |
-| Event semantics (what counts as a message / run / turn) | [`packages/backend/src/gateway/agent-runtime-event-normalizer.ts`](packages/backend/src/gateway/) and its fixture tests |
-| Gateway protocol (commands, event contract, identity) | [`packages/core/src/`](packages/core/src/): `runtime-gateway.ts`, `agent-runtime-event.ts` |
-| How Pi is driven | [`packages/backend/src/drivers/`](packages/backend/src/drivers/) |
-| Persistence and replay | [`packages/backend/src/persistence/`](packages/backend/src/persistence/) |
-| Packages page (sidebar): packages, resources, update checks and journal diagnostics | [`apps/desktop/src/pages/setup.tsx`](apps/desktop/src/pages/setup.tsx), [`packages/backend/src/workspace/resource-management.ts`](packages/backend/src/workspace/resource-management.ts), [`resource-diagnostics.ts`](packages/backend/src/workspace/resource-diagnostics.ts) ([ADR-0037](docs/adr/0037-resource-management.md)) |
-| Model availability (catalog, capability mapping, credential-driven refresh) | [`packages/backend/src/workspace/model-catalog.ts`](packages/backend/src/workspace/model-catalog.ts), mapping in [`packages/core/src/model-capabilities.ts`](packages/core/src/model-capabilities.ts) ([ADR-0043](docs/adr/0043-model-catalog-owns-model-availability.md)) |
-| MCP server management (global `mcp.json`, probes, OAuth sign-in) | [`packages/backend/src/workspace/mcp-servers.ts`](packages/backend/src/workspace/mcp-servers.ts), contracts in [`packages/core/src/mcp-servers.ts`](packages/core/src/mcp-servers.ts) |
-| Sessions on disk, git worktrees, config inventory | [`packages/backend/src/workspace/`](packages/backend/src/workspace/) |
-| Electron shell and transport | [`apps/desktop/electron/`](apps/desktop/electron/): `main.ts`, `preload.ts`, `backend.ts` |
-| Dock surfaces (Changes, Files, Terminal, Browser) | [`apps/desktop/src/shared/ui/session-dock/surface-registry.ts`](apps/desktop/src/shared/ui/session-dock/surface-registry.ts) |
-| Design system rules | [`docs/design/`](docs/design/), inventory of self-built components in [`docs/self-built-ui.md`](docs/self-built-ui.md) |
-| Why it is designed this way | [`docs/adr/`](docs/adr/), vocabulary in [`CONTEXT.md`](CONTEXT.md) |
+## Extensibility
-## Extensibility: where the GUI meets Pi's extension ecosystem
+Pace reuses Pi's `Package → Extension / Skill / Prompt / Theme` model unchanged. The **Packages** page in the sidebar installs, removes and updates packages, toggles individual resources, and adds local resources to Pi's convention directories. Package rows flag available updates, and resource details show extension errors from the most recently active session. Changes apply to the next new session.
-Pi's extension ecosystem is built on the `Package → Extension / Skill / Prompt / Theme` model. Pace follows and reuses that model as is; it only defines what an extension can contribute to the desktop GUI in terms of visuals and interaction. The **Packages** page in the sidebar provides Resource Management: install, remove and update user packages, toggle their resources, and add local resources to Pi convention directories. Package rows show available updates; resource details show extension errors from the most recently active Session. Settings changes apply to the next new Session ([ADR-0037](docs/adr/0037-resource-management.md)).
+Extensions cannot contribute GUI panels yet. The roadmap, in priority order:
-The extension points that exist today:
-
-- **The `surface` routing stamp on every event**: the `chat | trace | status | composer | hidden` stamp an event carries decides how it is presented in the UI. Today it is a fixed, predefined set; it is also the standard mounting slot for future extension panels.
-
-- **The Session Dock panel registry**: every interactive panel in the Session Dock sidebar is a Surface with a unique id, title, icon and hint, declared centrally in `surface-registry.ts`. The registry currently holds four built-in panels (Changes, Files, Terminal and the embedded Browser). Per [ADR-0032](docs/adr/0032-session-dock-and-trajectory-vocabulary.md), the registry already reserves a `provider` field (`builtin` or a specific Pi extension id), so panels contributed by external extensions mount into the same sidebar with no extra mechanism.
-
-- **The Runtime Gateway capability model**: the UI adapts to the features the current runtime advertises. For Pi SDK "extension UI requests", the gateway already reserves a slot at the protocol level ([ADR-0018](docs/adr/0018-runtime-gateway-api-and-pi-drivers.md)); support will be filled in step by step.
-
-The roadmap on this track, in priority order:
-
-1. **Extension Surface protocol**: a standardized protocol that lets a Pi extension register a custom panel fed directly by the same underlying event stream.
-
-2. **Multi-agent dynamic workflow visualization**: when Pi runs multi-step tasks or coordinates multiple agents, render the work as a clear execution topology instead of interleaved text logs.
-
-3. **Pluggable runtime tuning**: open up the controls in Pace that shape agent behavior (prompt injection, permission management, interruption policy and so on) as extension points, so developers can customize agent behavior by installing a package rather than modifying the client repository.
-
-Alongside this, Pace aims to deliver the GUI-native experience a terminal cannot host: an embedded browser with DOM-level annotation and interaction ([ADR-0029](docs/adr/0029-embedded-browser-surface.md)). That is also the core reason Pace is built on Electron.
-
-## Repository layout
-
-```plaintext
-apps/desktop/ Electron app: electron/ (main, preload, backend host) + src/ (React, FSD)
-apps/server/ placeholder: headless backend behind a WebSocket (ADR-0015)
-apps/web/ placeholder: browser client for apps/server
-packages/core/ shared kernel: gateway protocol, event model, session types (ADR-0014)
-packages/backend/ drivers, gateway, persistence, workspace; service.ts is the composition root
-e2e/ Playwright smoke tests against the real Electron app
-build/ icons, entitlements, Icon Composer source
-scripts/ release, packaging and runtime-bundling scripts
-docs/ ADRs, design system rules, release and dogfooding guides
-CONTEXT.md the domain glossary; every UI region and concept has a term here
-```
-
-Stack: Electron + electron-vite, React 19, TypeScript, TanStack (Query / Router / Virtual), the Astryx design system (component styles precompiled by StyleX) and Tailwind v4, Bun workspaces, Vitest, Playwright.
+1. **Extension Surface protocol**: let a Pi extension register its own panel, fed by the same event stream as the built-in views.
+2. **Multi-agent workflow visualization**: render multi-step and multi-agent runs as an execution topology instead of interleaved logs.
+3. **Pluggable runtime tuning**: expose prompt injection, permissions and interruption policy as extension points, so behavior changes ship as packages rather than client patches.
## Local data and recovery
@@ -217,74 +83,17 @@ Stack: Electron + electron-vite, React 19, TypeScript, TanStack (Query / Router
| Session journal, projections, preflight state | `~/.pace` | `~/.pace-dev` | Pace. Override with `PACE_DATA_DIR` (`PIGUI_DATA_DIR` is a deprecated alias). |
| Renderer preferences (project registry, drafts, model choice), Chromium profile | Electron userData | userData `-dev` | Pace. |
-Deleting Pace's local data directory only loses the UI history and cost statistics. It never damages the underlying Pi session data: Pi can fully rebuild its state from its own session log at any time. Any later change to the journal or projection storage format must stay backward compatible with the old format or ship a migration script (see [`docs/dogfooding.md`](docs/dogfooding.md)).
-
-## Development and verification
-
-Toolchain: Bun 1.3.x (workspaces and scripts), Node 24 (Electron's runtime and Vitest), Electron 42. `bun run dev` starts electron-vite with hot reload. The dev instance writes to `~/.pace-dev` and a userData directory with a `-dev` suffix, keeping installed-app data separate. See [`docs/dogfooding.md`](docs/dogfooding.md) for the isolation rules when developing Pace with Pace.
-
-```bash
-bun run typecheck # tsc --noEmit across the workspace
-bun run lint # ESLint: FSD import direction in apps/desktop/src (ADR-0045)
-bun run test # vitest: unit + contract tests (normalizer fixtures, gateway, persistence)
-bun run test:e2e # Playwright smoke tests against the dev Electron build
-bun run test:release # release script and publish behavior tests
-bun run build # typecheck + electron-vite build
-```
-
-Before opening a PR, `typecheck`, `lint`, `test` and `build` must be green; the manual `Validate macOS ARM64` workflow runs packaging and the packaged-app E2E on demand.
-
-Packaging:
-
-```bash
-bun run package:mac:unsigned # unsigned .app + zip, for local testing
-bun run dist:mac # signed + notarized DMG (needs Apple credentials)
-bun run dist:linux # AppImage + deb (x64)
-```
-
-The signing, notarization and release pipeline is documented in [`docs/release/macos.md`](docs/release/macos.md). Linux AppImage and deb builds ship on the same tag: [`docs/release/linux.md`](docs/release/linux.md).
-
-Two dev-only tools help when working on the UI locally:
-
-- The `/design` route: a live gallery of the design system, showing every base component under `shared/ui/` with all of its states and variants.
-
-- The **UI Intent Picker**: press `Cmd/Ctrl+Shift+X` to activate a crosshair, then click any element to copy its CONTEXT.md term, its component stack with file and line, and the nearest `data-testid` (see [`docs/ui-intent-picker.md`](docs/ui-intent-picker.md)).
-
-> **Note**: do not debug the terminal PTY driver directly under Bun. The production backend runs on Node, and Bun's current Node-API compatibility layer can crash `node-pty`.
-
-## Documentation
-
-- [`CONTEXT.md`](CONTEXT.md): domain glossary. The terms here are the names used in code, tests and issues.
-
-- [`docs/adr/`](docs/adr/): architecture decision records, from the control-plane pivot ([ADR-0001](docs/adr/0001-agent-workspace-control-plane.md)) to the current surfaces.
-
-- [`docs/design/`](docs/design/): which tokens, which Astryx variants, which self-built components.
-
-- [`docs/release/macos.md`](docs/release/macos.md), [`docs/release/linux.md`](docs/release/linux.md), [`docs/dogfooding.md`](docs/dogfooding.md): shipping and daily-driving Pace.
-
-- [`docs/agents/`](docs/agents/): how issues, triage labels and domain docs are organized for both human and agent contributors.
-
-- [`.scratch//PRD.md`](.scratch/): point-in-time product requirement records.
+Deleting Pace's data directory loses only UI history and cost statistics. Pi session data is never touched, and Pi can rebuild its state from its own log at any time.
## Support and security
-- **Bugs and feature requests**: submit them to [GitHub Issues](https://github.com/BubblePtr/pace/issues).
-- **Security vulnerabilities**: do not open a public issue. Follow [SECURITY.md](SECURITY.md) to report vulnerabilities privately through GitHub. Only the latest release is supported.
-- **Release notes**: see [GitHub Releases](https://github.com/BubblePtr/pace/releases) for changes in each version.
+- **Bugs and feature requests**: [GitHub Issues](https://github.com/BubblePtr/pace/issues).
+- **Security vulnerabilities**: do not open a public issue. Report privately through GitHub as described in [SECURITY.md](SECURITY.md). Only the latest release is supported.
+- **Release notes**: [GitHub Releases](https://github.com/BubblePtr/pace/releases).
## Contributing
-- **Issues**: tasks and bugs are tracked on GitHub Issues. Labels follow a role-based triage flow (`needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `wontfix`); anything marked `ready-for-human` is open for community members to pick up.
-
-- **Branches and commits**: features and fixes are developed on `feat/`, `fix/` and `chore/` branches; `main` is the only long-lived branch, and releases are cut from git tags. Dependent PRs should be managed with `gh stack`. Commit messages strictly follow Conventional Commits.
-
-- **Architecture decision records**: any change that moves an architectural boundary or adjusts a key domain term ships with an ADR; if it touches concept definitions, update `CONTEXT.md` in the same PR.
-
-- **UI components**: reusable components go in `apps/desktop/src/shared/ui/` and are added to the `/design` gallery in the same PR. Style tokens come through the semantic bridge layer; hard-coded values are not allowed.
-
-- **Good first issue**: a recommended entry point is adding a fixture test for the event Normalizer: record a raw Pi session log, add a test case and assert the normalized events. It needs no UI work and is a fast way to learn the core protocol.
-
-See [CONTRIBUTING.md](CONTRIBUTING.md), [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) and [SECURITY.md](SECURITY.md). [`AGENTS.md`](AGENTS.md) holds the full contributor rules, written to be followed by humans and coding agents alike.
+Start with [CONTRIBUTING.md](CONTRIBUTING.md): setup, verification commands, branch rules and a good first PR. [`docs/architecture.md`](docs/architecture.md) maps the event pipeline and where each concern lives in the code; [`AGENTS.md`](AGENTS.md) holds the full rule set, written for humans and coding agents alike. By participating you agree to the [Code of Conduct](CODE_OF_CONDUCT.md).
## License
diff --git a/README.zh-CN.md b/README.zh-CN.md
index 0d11f593..c148eeed 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -2,20 +2,21 @@
Pace
-Pi coding agent 的桌面 GUI。将 Pi 的设计与灵活性带到桌面端。
+Pi coding agent 的桌面 GUI。把 Pi 的设计与灵活性带到桌面端。
English | 简体中文
+
-Pi 是运行在终端里的编程智能体,拥有类似 VS Code 的扩展体系:扩展包可以提供工具、命令、技能、提示词和主题。Pace 将这份灵活性带到桌面端,让开发者自由定制属于自己的智能体。Pace 的名字取自 *move at your own pace*,意为“按自己的节奏前进”。在 AI 时代,开发者也应当保有对智能体的完全自主权,按自己的节奏开发与协作。
+Pi 是运行在终端里的 coding agent,拥有类似 VS Code 的扩展体系:扩展包可以提供工具、命令、技能、提示词和主题。Pace 把这份灵活性带到桌面端,让你自由定制一个真正属于自己的桌面 agent。Pace 的名字取自 *move at your own pace*(按自己的节奏前进):开发者应当完全拥有自己的 agent,按自己的节奏开发与协作。
> [!NOTE]
-> Pace 处于 `0.y.z` 早期阶段,仅支持 GitHub Releases 上的最新版本。事件日志(journal)与查询投影(projection)的存储格式可能随次版本更新而变化,应用内更新器负责完成升级;Pi 的会话数据不受影响(见[本地数据与恢复](#本地数据与恢复))。
+> Pace 处于 `0.y.z` 早期开发阶段,仅支持 GitHub Releases 上的最新版本。journal 与 projection 的存储格式可能随次版本更新而变化,应用内更新器负责完成升级;Pi 的 session 数据不受影响(见[本地数据与恢复](#本地数据与恢复))。
@@ -23,239 +24,76 @@ Pi 是运行在终端里的编程智能体,拥有类似 VS Code 的扩展体
## 亮点
-- **会话时间线**:按时间查看智能体的思维链和工具调用,以及每轮的 Token 用量与费用。既能实时跟进执行过程,也能回放已记录的会话,查看每一步做了什么、花了多少。
-- **Session Dock 面板**:代码变更(Changes)、文件(Files)、终端(Terminal)、内嵌浏览器(Browser)集中在同一个侧边栏,Pi 扩展也可以提供自己的面板。
-- **统一且可定制的界面**:基于 [Astryx](https://github.com/facebook/astryx) 的组件与开放设计变量,让内置界面和自定义组件共享配色、间距与交互规范。Astryx 的组件样式由 [StyleX](https://engineering.fb.com/2025/11/11/web/stylex-a-styling-library-for-css-at-scale/) 预编译为可复用的原子 CSS,减少重复样式,无需在运行时动态生成样式表。开发者和智能体还可以通过 Astryx CLI 查阅组件、选用模板,沿用同一套设计规范构建新界面。
-- **Pi 仍是唯一引擎**:Pace 不是 Pi 的分支项目,也不是另一套独立运行时。会话数据以 Pi 的本地日志为准,卸载 Pace 不会丢失 Pi 的会话。
+- **Session 时间线**:按顺序查看 agent 的思维链和工具调用,以及每一轮的 token 用量与费用。可以实时跟进一次运行,也可以回放已记录的 session,看清每一步做了什么、花了多少。
+- **Session Dock**:Changes、Files、Terminal 和内嵌 Browser 共享对话旁的同一个侧边栏。
+- **你的 Pi 环境原样可用**:Pace 共享 `~/.pi/agent` 下的 session、认证与扩展;Packages 页面让你无需离开应用即可管理 Pi 扩展包。
+- **Pi 仍是唯一引擎**:Pace 不是 Pi 的分支,也不是另一套运行时。session 数据以 Pi 的本地日志为准;卸载 Pace 不会删除任何 Pi session。
+
+## 什么时候不需要 Pace
+
+- 你只在终端里用 Pi,不需要图形界面来查看费用、思维链或工具调用。
+- 你使用 Windows 或 Intel Mac。安装包仅提供 Apple Silicon Mac 与 64 位 Linux 版本。
+- 你想要一个不依赖 Pi 的 agent 客户端。Pace 自己没有 agent 执行循环,推理与上下文管理均由 Pi 负责。
## 快速开始
### 安装
-**预编译安装包(推荐)。** 每个 [GitHub Release](https://github.com/BubblePtr/pace/releases) 都包含已签名并公证的 Apple Silicon DMG,以及 Linux x64 的 AppImage 和 deb。
+每个 [GitHub Release](https://github.com/BubblePtr/pace/releases) 都附带为 Apple Silicon Mac 签名并公证的 DMG,以及 Linux x64 的 AppImage 和 deb。
-- **macOS。** 打开 DMG,将 Pace 拖入“应用程序”。之后可在应用内更新(ADR-0033)。
-- **Linux AppImage。** `chmod +x` 后直接运行。应用内更新只覆盖 AppImage。若因缺少 FUSE 无法启动,加上 `--appimage-extract-and-run`。
-- **Linux deb。** 用 `apt` 安装。deb 不会自动更新,升级时重新安装新包。
+| 平台 | 安装 | 更新 |
+| --- | --- | --- |
+| macOS 12+(Apple Silicon) | 打开 DMG,把 Pace 拖入“应用程序”。 | 应用内更新 |
+| Linux AppImage(x64) | `chmod +x` 后直接运行。缺少 FUSE 时加上 `--appimage-extract-and-run`。 | 应用内更新 |
+| Linux deb(x64) | 用 `apt` 安装。 | 手动安装新包 |
-说明见 [`docs/release/linux.md`](docs/release/linux.md)。
+Pi 运行时已随应用内置,无需单独安装 `pi`。更多 Linux 说明见 [`docs/release/linux.md`](docs/release/linux.md)。如需从源码运行,参见 [CONTRIBUTING.md 的 Setup](CONTRIBUTING.md#setup)。
-**从源码运行。** 需要 Bun 1.3.x 与 Node 24:
+### 开始第一个 session
-```bash
-git clone https://github.com/BubblePtr/pace.git pace
-cd pace
-bun install
-bun run dev
-```
+1. 首次启动时,Pace 会检查内置 Pi 运行时、数据目录和模型 provider 的登录状态,并显示数据的保存位置。如果尚未登录 provider,可在终端中运行 `pi` 完成登录;Pace 无需重启即可识别新的登录状态。
+2. 选择一个项目目录,新建 session。
+3. 发送第一条消息,比如:*解释一下这个仓库的架构*。
+4. 在 Live Chat 中阅读对话,在 Trajectory 中查看思维链和工具调用,在状态栏中查看本轮的 token 用量与费用。
-**运行要求。** 搭载 Apple Silicon 芯片、运行 macOS 12 或更高版本的 Mac,或 64 位 Linux。Pi 运行时已随应用内置(ADR-0031),无需单独安装 `pi`;若本机已装 Pi,Pace 会共享 `~/.pi/agent` 下的会话、认证与扩展。暂不支持 Windows 与 Intel Mac。
+## 设计原则
-### 开始第一次会话
+- **上下文归 Pi 所有。** `~/.pi` 下的 Pi session 日志是唯一事实来源。Pace 从不组装提示词,也从不写入该日志;它持久化的只是 Pi 事件流的投影,存放在自己的目录里。
+- **界面由事件日志驱动。** 每个 Pi 事件都会被标准化、编号并追加进 journal。实时时间线、历史回放与费用统计全部由此推导。
+- **GUI 永不阻塞 agent。** 后端运行在独立的 Electron `utilityProcess` 中,每个根 session 都在自己的进程里运行 Pi,繁重的日志解析或 session 崩溃都无法冻结窗口。
+- **为扩展而生。** 事件路由、Session Dock 和 gateway 能力模型的设计目标,就是让 Pi 扩展能贡献自己的面板与控件;对应的协议是下面路线图的第一项。
-1. 首次启动时,Pace 会检查内置 Pi 运行时、数据目录和模型服务商的登录状态,并显示数据的保存位置(ADR-0025)。如果尚未登录模型服务商,可在终端中通过 `pi` 完成登录。Pace 会自动识别新的登录状态,无需重启。
-2. 预检通过后,选择一个项目目录,新建会话。
-3. 在输入框中发送第一条消息,比如让它解释这个仓库的结构。
-4. 在 Live Chat 中查看对话,在 Trajectory 中查看思维链和工具调用,在状态栏中查看本轮的 Token 用量与费用。
+这些原则如何落地为代码,见 [`docs/architecture.md`](docs/architecture.md)。
-## 什么时候不需要 Pace
+## 扩展机制
-- 你只在终端里用 Pi,不需要通过图形界面查看费用、思维链或工具调用。
-- 你使用 Windows 电脑或 Intel Mac。安装包目前提供给 Apple Silicon Mac 与 64 位 Linux。
-- 你想要一个不依赖 Pi 的独立智能体客户端。Pace 不实现智能体的执行循环,推理执行与上下文管理均由 Pi 负责。
+Pace 原样复用 Pi 的 `Package → Extension / Skill / Prompt / Theme` 模型。侧边栏的 **Packages** 页可以安装、卸载和更新扩展包,启用或停用其中的单个资源,也可以把本地资源加入 Pi 的约定目录。扩展包行会标记可用更新,资源详情会展示最近活跃 session 中的扩展错误。所有变更在下一个新建 session 时生效。
-## 设计原则
+扩展暂时还无法贡献 GUI 面板。按优先级排列的路线图:
-- **Pace 只是会话事件的投影,不侵入核心上下文。** Pi 的本地会话日志(`~/.pi`)是唯一事实来源,会话恢复时由 Pi 自己从中重建大模型上下文。Pace 不组装提示词,也不修改该日志;Pace 持久化的所有数据都是 Pi 事件流的投影,存放在自己的目录里。
-- **界面完全由事件日志驱动。** Pi 的每个原始事件都被标准化为 `AgentRuntimeEvent`,分配单调递增的序号和按确定性规则生成的 run / turn / message ID,然后写入事件日志。实时时间线、历史回放、Token 用量与费用统计均由事件日志推导,不依赖前端渲染状态。
-- **面板和行为均与客户端解耦,都可以由扩展提供。** Pace 自身只内置少量核心面板(Surface)。事件路由、Session Dock 注册表和 Runtime Gateway 能力模型均采用插件化设计,Pi 扩展无需等待 Pace 发布新版本,就能注册自定义面板、控件或工作流视图。这与 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 的“一切皆插件”思路一致;随着其插件模型逐步成熟,Pace 计划借鉴其中的设计。
-- **监控与交互不阻塞执行引擎。** 后端运行在 Electron 的独立进程 `utilityProcess` 中,繁重的日志解析和驱动崩溃都不会让窗口卡顿。后端协议与具体传输方式解耦,将来可将后端部署为通过 socket 连接的远程服务。
-
-## 架构
-
-整个系统由一条单向事件流水线和两套职责明确、互不替代的持久化机制组成([ADR-0021](docs/adr/0021-session-fork-resume-persistence-layering.md)):
-
-```mermaid
-flowchart TB
- subgraph R["渲染层 — apps/desktop · React 19 · FSD(pages → entities → shared)"]
- direction LR
- pages["Pages + entities
消费事件包络,按 surface 戳路由:
chat · trace · status · composer · hidden"]
- dock["Session Dock
Changes · Files · Terminal · Browser
+ 扩展面板(provider 字段已预留)"]
- pages --- dock
- end
-
- subgraph S["Electron 主进程 — apps/desktop/electron"]
- relay["preload.ts contextBridge + IPC 中继
invoke ⇄ backend-event"]
- host["窗口 · 自动更新 · 内嵌浏览器宿主 · 应用菜单"]
- relay --- host
- end
-
- subgraph B["后端 — packages/backend · utilityProcess(Node)"]
- svc["service.ts — 组合根
RPC 分发 + 事件扇出"]
- subgraph PL["唯一的单向事件流水线"]
- direction LR
- pi["Pi 运行时 — 内嵌
AgentSession · 工具 · 扩展
(agent loop 在这里)"]
- drv["Driver
pi-sdk(唯一驱动)"]
- nz["Normalizer
原始事件 → AgentRuntimeEvent"]
- gw["Runtime Gateway
seq + 确定性 run/turn/message id
+ 能力声明"]
- pi --> drv --> nz --> gw
- end
- ws["workspace
会话 · 执行检出 · 资源管理
环境预检 · 供应商认证 · 终端 pty"]
- svc --- gw
- svc --- ws
- gw -. "命令: prompt · queue · steer · stop · model" .-> drv
- end
-
- R <-->|"contextBridge"| S
- S <-->|"MessageChannel port"| B
-
- gw ==>|"仅追加边界事件"| jrnl[("Session Event Journal
~/.pace — 呈现层真相")]
- gw -->|"更新"| proj[("Session Projection
~/.pace — 查询模型")]
- pi -->|"Pi 拥有"| pilog[("Pi 会话 jsonl
~/.pi — 上下文真相")]
-```
-
-- **Driver(驱动层)**:封装 Pi 运行时。SDK Driver 是唯一的 Pi 驱动,运行在每个根 Session 的独立进程中([ADR-0040](docs/adr/0040-root-session-process-isolation.md));早期的 RPC Driver 已删除([ADR-0041](docs/adr/0041-remove-pi-rpc-driver.md))。
-- **Normalizer(标准化层)**:把 Pi 的原始事件转换为统一的 `AgentRuntimeEvent`,附加阶段(Phase)、目标展示区(Surface)和按确定性规则生成的消息 ID([ADR-0020](docs/adr/0020-agent-runtime-event-model.md))。基于录制数据的契约测试构成了该协议的可执行规范。
-- **Runtime Gateway(运行时网关)**:渲染层与后端通信的唯一协议接口。接收渲染层发来的控制命令,并向渲染层推送带单调递增序号的事件封装(envelope)。网关声明当前运行时支持的能力,包括模型切换、思考设置、消息排队与执行引导,界面据此提供相应的操作([ADR-0024](docs/adr/0024-model-thinking-controls-follow-runtime-capabilities.md))。
-- **Persistence(持久化层)**:维护仅追加、可按时间线回放的 Session Event Journal,以及供列表和统计查询的 Session Projection。
-- **Renderer(渲染层)**:根据 `surface` 标签,将事件分发到实时对话(Live Chat)、执行轨迹(Trajectory)、状态栏或不直接显示的后台状态;同时承载 Session Dock 侧边栏,挂载内置面板和扩展提供的面板([ADR-0032](docs/adr/0032-session-dock-and-trajectory-vocabulary.md))。
-
-
-一条消息的处理流程
-
-1. 渲染层通过 Runtime Gateway Client 发送 `send_prompt` 请求(`apps/desktop/src/entities/runtime/runtime-gateway-client.ts`)。
-2. 命令经 MessagePort 跨进程通道转发至后端 `utilityProcess`(`apps/desktop/electron/preload.ts`、`backend.ts`)。
-3. `createBackendService()` 将命令分发至 Runtime Gateway 实例(`packages/backend/src/service.ts`)。
-4. Gateway 按确定性规则生成用户消息 ID,并将命令转发给当前启用的 Driver(`packages/backend/src/gateway/runtime-gateway.ts`)。
-5. SDK Driver 调用 Pi 的 `AgentSession`,驱动智能体的执行循环(`packages/backend/src/drivers/pi-sdk-driver.ts`)。
-6. Pi 的原始事件经 Normalizer 转换为标准格式(`packages/backend/src/gateway/agent-runtime-event-normalizer.ts`)。
-7. Gateway 为每个事件赋予单调递增序号,记录生命周期边界,同步更新投影(`packages/backend/src/persistence/`)。
-8. 事件经同一传输通道返回渲染层,按 `surface` 标签路由到对应界面组件(`apps/desktop/src/entities/runtime/`)。
-
-
-
-
-代码在哪里
-
-| 修改内容 | 对应位置 |
-| --- | --- |
-| 界面、页面、交互 | [`apps/desktop/src/`](apps/desktop/src/),FSD 分层 `pages` → `entities` → `shared`([ADR-0016](docs/adr/0016-fsd-layers-in-apps-desktop.md)) |
-| 事件语义(什么算 message / run / turn) | [`packages/backend/src/gateway/agent-runtime-event-normalizer.ts`](packages/backend/src/gateway/) 及其基于录制数据的测试 |
-| Gateway 协议(命令、事件契约、身份) | [`packages/core/src/`](packages/core/src/):`runtime-gateway.ts`、`agent-runtime-event.ts` |
-| 怎么驱动 Pi | [`packages/backend/src/drivers/`](packages/backend/src/drivers/) |
-| 持久化与回放 | [`packages/backend/src/persistence/`](packages/backend/src/persistence/) |
-| 磁盘上的会话、Git 工作树和配置清单 | [`packages/backend/src/workspace/`](packages/backend/src/workspace/) |
-| Electron 外壳与传输 | [`apps/desktop/electron/`](apps/desktop/electron/):`main.ts`、`preload.ts`、`backend.ts` |
-| Dock Surface(Changes、Files、Terminal、Browser) | [`apps/desktop/src/shared/ui/session-dock/surface-registry.ts`](apps/desktop/src/shared/ui/session-dock/surface-registry.ts) |
-| 资源管理(侧边栏的 Packages 页):扩展包、资源、更新检查与事件日志诊断 | [`apps/desktop/src/pages/setup.tsx`](apps/desktop/src/pages/setup.tsx)、[`packages/backend/src/workspace/resource-management.ts`](packages/backend/src/workspace/resource-management.ts)、[`resource-diagnostics.ts`](packages/backend/src/workspace/resource-diagnostics.ts)([ADR-0037](docs/adr/0037-resource-management.md)) |
-| 设计系统规则 | [`docs/design/`](docs/design/),自建组件清单见 [`docs/self-built-ui.md`](docs/self-built-ui.md) |
-| 为什么这样设计 | [`docs/adr/`](docs/adr/),术语在 [`CONTEXT.md`](CONTEXT.md) |
-
-
-
-## 扩展机制:将 Pi 扩展接入桌面界面
-
-Pi 的扩展生态基于 `Package → Extension / Skill / Prompt / Theme` 体系。Pace 直接复用这一模型,并定义扩展可以为桌面界面提供哪些展示与交互能力。
-
-主侧边栏 Packages 页的资源管理(Resource Management)支持安装、卸载和更新用户级扩展包(Package),启用或禁用其中的资源(Resource),以及将本地资源复制到 Pi 的约定目录。扩展包列表显示可用更新,资源详情显示最近活跃会话中的扩展错误。设置变更将在下一次新建会话时生效([ADR-0037](docs/adr/0037-resource-management.md))。
-
-目前已实现的扩展点:
-
-- **事件级别的 `surface` 路由标签**:事件携带的 `chat | trace | status | composer | hidden` 标签决定它在界面上如何呈现。目前可选值固定,未来将作为扩展面板的标准接入点。
-- **Session Dock 面板注册表**:侧边栏里的每块面板都是一个 Surface,有唯一 ID、标题、图标与提示,集中声明在 `surface-registry.ts`。当前有四个内置面板(Changes、Files、Terminal、Browser)。按 [ADR-0032](docs/adr/0032-session-dock-and-trajectory-vocabulary.md) 的设计,注册表预留了 `provider` 字段(`builtin` 或具体的 Pi 扩展 ID),外部扩展提供的面板将通过同一机制接入侧边栏。
-- **Runtime Gateway 能力模型**:界面根据当前运行时声明的能力调整可用操作。针对 Pi SDK 的扩展界面交互请求(Extension UI request),网关已在协议层预留接口([ADR-0018](docs/adr/0018-runtime-gateway-api-and-pi-drivers.md)),后续逐步补齐。
-
-后续计划按优先级排列如下:
-
-1. **自定义面板协议(Extension Surface)**:制定统一协议,让 Pi 扩展注册自定义面板,并直接使用同一条事件流。
-2. **多智能体动态工作流可视化**:将 Pi 的多步骤任务和多智能体协作过程绘制成执行链路拓扑图,便于查看各步骤之间的关系。
-3. **插件化运行时调优**:把 Pace 中影响智能体行为的控制项(提示词注入、权限管控、执行中断策略等)开放为扩展点,安装扩展包即可定制智能体行为,无需修改客户端源码。
-
-另一个方向是终端难以实现的图形界面功能,例如支持对 DOM 元素进行批注和交互的内嵌浏览器([ADR-0029](docs/adr/0029-embedded-browser-surface.md))。这也是 Pace 选择 Electron 的核心原因。
-
-## 仓库布局
-
-```plaintext
-apps/desktop/ Electron 应用:electron/(main、preload、后端宿主)+ src/(React,FSD)
-apps/server/ 预留:通过 WebSocket 提供服务的无界面后端(ADR-0015)
-apps/web/ 预留:apps/server 的浏览器客户端
-packages/core/ 共享内核:gateway 协议、事件模型、会话类型(ADR-0014)
-packages/backend/ drivers、gateway、persistence、workspace;service.ts 是组合根
-e2e/ 针对真实 Electron 应用的 Playwright 冒烟测试
-build/ 图标、entitlements、Icon Composer 源工程
-scripts/ 发布、打包与运行时捆绑脚本
-docs/ ADR、设计系统规则、发布与使用 Pace 开发 Pace 的指南
-CONTEXT.md 领域术语表;每个界面区域和概念在这里都有词条
-```
-
-技术栈:Electron + electron-vite、React 19、TypeScript、TanStack(Query / Router / Virtual)、Astryx 设计系统(组件样式由 StyleX 预编译)与 Tailwind v4、Bun workspaces、Vitest、Playwright。
+1. **Extension Surface 协议**:让 Pi 扩展注册自己的面板,由与内置视图相同的事件流驱动。
+2. **多 agent 工作流可视化**:把多步骤、多 agent 的运行渲染成执行拓扑图,而不是交织在一起的日志。
+3. **可插拔的运行时调优**:把提示词注入、权限管控和中断策略开放为扩展点,行为改动以扩展包的形式发布,无需修改客户端代码。
## 本地数据与恢复
| 数据 | 安装版 | `bun run dev` | 归属 |
| --- | --- | --- | --- |
-| Pi 会话、认证、扩展 | `~/.pi/agent` | 共享 | Pi 管理会话原始数据;Pace 通过 SDK 管理用户级资源配置并导入本地资源。 |
-| 会话事件日志、查询投影、预检状态 | `~/.pace` | `~/.pace-dev` | Pace。可通过 `PACE_DATA_DIR` 指定数据目录(`PIGUI_DATA_DIR` 为已弃用别名)。 |
+| Pi session、认证、扩展 | `~/.pi/agent` | 共享 | session 真相归 Pi 所有;Pace 通过 SDK 管理用户资源配置并导入本地资源。 |
+| session journal、projection、预检状态 | `~/.pace` | `~/.pace-dev` | Pace。可用 `PACE_DATA_DIR` 覆盖(`PIGUI_DATA_DIR` 为已弃用别名)。 |
| 渲染层偏好(项目注册表、草稿、模型选择)、Chromium 用户配置 | Electron userData | userData `-dev` | Pace。 |
-删除 Pace 的本地数据目录只会丢失界面历史与费用统计,不会损坏 Pi 的会话数据,Pi 随时可从自己的会话日志重建状态。调整事件日志或查询投影的存储格式时,必须兼容旧格式或附带迁移脚本(见 [`docs/dogfooding.md`](docs/dogfooding.md))。
-
-## 开发与验证
-
-工具链:Bun 1.3.x(工作区与脚本)、Node 24(Electron 运行时与 Vitest)、Electron 42。`bun run dev` 启动带热更新的 electron-vite。开发实例将数据写入 `~/.pace-dev` 和带 `-dev` 后缀的 userData 目录,不会影响已安装版本的数据;用 Pace 开发 Pace 的隔离规则见 [`docs/dogfooding.md`](docs/dogfooding.md)。
-
-```bash
-bun run typecheck # 整个 workspace 的 tsc --noEmit
-bun run test # vitest:单元 + 契约测试(normalizer fixture、gateway、persistence)
-bun run test:e2e # 针对 dev Electron 构建的 Playwright 冒烟测试
-bun run test:release # 发布脚本与发布行为测试
-bun run build # typecheck + electron-vite build
-```
-
-提交 PR 前,`typecheck`、`test`、`build` 必须全部通过。需要验证安装包时,可手动运行 `Validate macOS ARM64` 工作流,完成打包和安装包的端到端测试。
-
-打包:
-
-```bash
-bun run package:mac:unsigned # 未签名 .app + zip,本地测试用
-bun run dist:mac # 签名 + 公证的 DMG(需要 Apple 凭据)
-bun run dist:linux # AppImage + deb(x64)
-```
-
-签名、公证与发布流水线见 [`docs/release/macos.md`](docs/release/macos.md)。Linux 的 AppImage 与 deb 随同一个 tag 发布:[`docs/release/linux.md`](docs/release/linux.md)。
-
-界面开发提供两个仅在开发环境中可用的工具:
-
-- 路由 `/design`:设计系统的组件展示页,`shared/ui/` 下每个组件的全部变体与状态都在这里。
-- **UI Intent Picker**:按 `Cmd/Ctrl+Shift+X` 激活准星,点击任意元素即可复制它对应的 CONTEXT.md 术语、源码组件调用栈(含文件与行号)和最近的 `data-testid`(见 [`docs/ui-intent-picker.md`](docs/ui-intent-picker.md))。
-
-> [!WARNING]
-> 不要在 Bun 下直接调试终端 PTY 驱动。生产环境后端跑在 Node 上,Bun 当前的 Node-API 兼容层会让 `node-pty` 崩溃。
-
-## 文档
-
-- [`CONTEXT.md`](CONTEXT.md):领域术语表。统一代码、测试和 Issue 中使用的名称。
-- [`docs/adr/`](docs/adr/):架构决策记录,记录了控制平面方向的调整([ADR-0001](docs/adr/0001-agent-workspace-control-plane.md))及各个界面面板的设计决策。
-- [`docs/design/`](docs/design/):用哪些 token、哪些 Astryx 变体、哪些自建组件。
-- [`docs/release/macos.md`](docs/release/macos.md)、[`docs/release/linux.md`](docs/release/linux.md)、[`docs/dogfooding.md`](docs/dogfooding.md):发版与日常使用 Pace。
-- [`docs/agents/`](docs/agents/):面向开发者与智能体贡献者的协作指南,涵盖 Issue 管理、分诊标签和领域文档。
-- [`.scratch//PRD.md`](.scratch/):某个时间点的产品需求记录。
+删除 Pace 的数据目录只会丢失界面历史与费用统计,绝不会触及 Pi session 数据;Pi 随时可以从自己的日志完整重建状态。
## 支持与安全
- **Bug 与功能请求**:提交到 [GitHub Issues](https://github.com/BubblePtr/pace/issues)。
-- **安全漏洞**:请勿提交公开 Issue。请按照 [SECURITY.md](SECURITY.md) 的指引,通过 GitHub 私密报告安全漏洞。仅支持最新版本。
-- **版本变化**:每个版本的更新说明在 [GitHub Releases](https://github.com/BubblePtr/pace/releases)。
+- **安全漏洞**:请勿提交公开 Issue。请按照 [SECURITY.md](SECURITY.md) 的说明通过 GitHub 私密报告。仅支持最新版本。
+- **版本说明**:每个版本的更新说明见 [GitHub Releases](https://github.com/BubblePtr/pace/releases)。
## 参与贡献
-- **Issue 协作**:任务与缺陷统一在 GitHub Issues 中跟进。使用五种标签标记问题的分诊与处理状态(`needs-triage`、`needs-info`、`ready-for-agent`、`ready-for-human`、`wontfix`);标为 `ready-for-human` 的任务都可以认领。
-- **分支与提交**:在 `feat/`、`fix/`、`chore/` 分支开发;`main` 是唯一长期维护的分支,发布版本通过 Git 标签标记。有依赖关系的 PR 用 `gh stack`。提交信息遵循 Conventional Commits。
-- **架构决策记录**:改动架构边界或关键业务术语的变更要附 ADR;涉及概念定义的,在同一 PR 里同步更新 `CONTEXT.md`。
-- **界面组件**:可复用组件放 `apps/desktop/src/shared/ui/`,并在同一 PR 中添加到 `/design` 展示页。样式通过语义化桥接层使用设计变量(token),不直接写死样式值。
-- **首次贡献建议**:为事件标准化层(Normalizer)补充一条基于录制数据的测试。录制一段 Pi 原生会话日志,新增测试用例,验证转换后的标准事件。不涉及前端,能快速熟悉核心协议。
-
-详见 [CONTRIBUTING.md](CONTRIBUTING.md)、[CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) 和 [SECURITY.md](SECURITY.md)。[`AGENTS.md`](AGENTS.md) 是完整的贡献规则,开发者与编程智能体均需遵守。
+从 [CONTRIBUTING.md](CONTRIBUTING.md) 开始:环境搭建、验证命令、分支规范和第一个练手 PR。[`docs/architecture.md`](docs/architecture.md) 描绘了事件流水线以及各职责对应的代码位置;[`AGENTS.md`](AGENTS.md) 是完整规则集,人类贡献者与 coding agent 同样适用。参与本项目即表示你同意遵守[行为准则](CODE_OF_CONDUCT.md)。
## 许可证
diff --git a/docs/architecture.md b/docs/architecture.md
new file mode 100644
index 00000000..459d60a1
--- /dev/null
+++ b/docs/architecture.md
@@ -0,0 +1,126 @@
+# Pace 架构
+
+本文是 Pace 代码的权威地图:单向事件流水线、各职责对应的文件位置,以及一条消息从输入到渲染的完整链路。改代码前先读这里。
+
+## 设计原则
+
+- **Pace 只是会话事件的投影,不侵入核心上下文。** Pi 的本地会话日志(`~/.pi`)是唯一事实来源,会话恢复时由 Pi 自己从中重建大模型上下文。Pace 不组装提示词,也不修改该日志;Pace 持久化的所有数据都是 Pi 事件流的投影,存放在自己的目录里。
+- **界面完全由事件日志驱动。** Pi 的每个原始事件都被标准化为 `AgentRuntimeEvent`,分配单调递增的序号和按确定性规则生成的 run / turn / message ID,然后写入事件日志。实时时间线、历史回放、Token 用量与费用统计均由事件日志推导,不依赖前端渲染状态。
+- **面板和行为均与客户端解耦,都可以由扩展提供。** Pace 自身只内置少量核心面板(Surface)。事件路由、Session Dock 注册表和 Runtime Gateway 能力模型均按插件化思路设计,目标是让 Pi 扩展无需等待 Pace 发布新版本,就能注册自定义面板、控件或工作流视图;这套协议尚未实现,现状见下文[界面扩展点](#界面扩展点)。这与 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 的“一切皆插件”思路一致;随着其插件模型逐步成熟,Pace 计划借鉴其中的设计。
+- **监控与交互不阻塞执行引擎。** 后端运行在 Electron 的独立进程 `utilityProcess` 中,繁重的日志解析和驱动崩溃都不会让窗口卡顿。后端协议与具体传输方式解耦,将来可将后端部署为通过 socket 连接的远程服务。
+
+## 总体架构
+
+整个系统由一条单向事件流水线和两套职责明确、互不替代的持久化机制组成([ADR-0021](adr/0021-session-fork-resume-persistence-layering.md)):
+
+```mermaid
+flowchart TB
+ subgraph R["渲染层 — apps/desktop · React 19 · FSD (pages → entities → shared)"]
+ direction LR
+ pages["Pages + entities
消费事件包络,按 surface 戳路由:
chat · trace · status · composer · hidden"]
+ dock["Session Dock
Changes · Files · Terminal · Browser
(扩展面板尚未接入,见 ADR-0032)"]
+ pages --- dock
+ end
+
+ subgraph S["Electron 主进程 — apps/desktop/electron"]
+ relay["preload.ts contextBridge + IPC 中继
invoke ⇄ backend-event"]
+ host["窗口 · 自动更新 · 内嵌浏览器宿主 · 应用菜单"]
+ relay --- host
+ end
+
+ subgraph B["后端 — packages/backend · utilityProcess (Node)"]
+ svc["service.ts — 组合根
RPC 分发 + 事件扇出"]
+ subgraph PL["唯一的单向事件流水线"]
+ direction LR
+ drv["SessionProcessDriver
每个根 Session 一个进程"]
+ gw["Runtime Gateway
seq + 确定性 run/turn/message id
+ 能力声明"]
+ drv --> gw
+ end
+ ws["workspace
会话 · 执行检出 · 资源管理
环境预检 · 供应商认证 · 终端 pty"]
+ svc --- gw
+ svc --- ws
+ gw -. "命令: prompt · queue · steer · stop · model" .-> drv
+ end
+
+ subgraph W["根 Session 进程 — 内置 Node"]
+ pi["Pi SDK · 工具 · 扩展
子 Session 由插件自行管理"]
+ nz["Normalizer
原始事件 → AgentRuntimeEvent"]
+ pi --> nz
+ end
+ drv -. "SDK 驱动命令" .-> pi
+ nz -->|"IPC 事件"| drv
+
+ R <-->|"contextBridge"| S
+ S <-->|"MessageChannel port"| B
+
+ gw ==>|"仅追加边界事件"| jrnl[("Session Event Journal
~/.pace — 呈现层真相")]
+ gw -->|"更新"| proj[("Session Projection
~/.pace — 查询模型")]
+ pi -->|"Pi 拥有"| pilog[("Pi 会话 jsonl
~/.pi — 上下文真相")]
+```
+
+- **Driver(驱动层)**:`SessionProcessDriver` 为每个根 Session 提供独立的进程和工作目录,进程内运行 Pi SDK 驱动;子 Session 由插件自行管理([ADR-0040](adr/0040-root-session-process-isolation.md))。SDK 驱动是唯一的 Pi 驱动,早期的 CLI RPC 驱动已删除([ADR-0041](adr/0041-remove-pi-rpc-driver.md))。
+- **Normalizer(标准化层)**:把 Pi 发出的原始事件转换为统一的 `AgentRuntimeEvent`,附加阶段(Phase)、目标展示区(Surface)和按全局确定性规则生成的消息 ID([ADR-0020](adr/0020-agent-runtime-event-model.md))。基于录制数据的契约测试构成了该协议的可执行规范。
+- **Runtime Gateway(运行时网关)**:渲染层唯一需要对话的协议接口。控制命令上行,带单调递增序号的事件包络(envelope)下行。网关动态声明当前运行时支持的能力(模型切换、思考设置、消息排队与执行引导),界面跟随运行时实际支持的能力而非静态假设([ADR-0024](adr/0024-model-thinking-controls-follow-runtime-capabilities.md))。
+- **Persistence(持久化层)**:维护仅追加、可按时间线回放的 Session Event Journal,以及供列表渲染和状态统计快速查询的 Session Projection。
+- **Renderer(渲染层)**:根据 `surface` 戳把每个事件路由到 Live Chat、Trajectory(思维链与工具调用)、状态栏或不直接显示的后台状态;同时承载 Session Dock 侧边栏。目前只挂载四个内置面板,扩展贡献的面板由 [ADR-0032](adr/0032-session-dock-and-trajectory-vocabulary.md) 规划、尚未接入。
+
+### 一条消息的处理流程
+
+1. 渲染层通过 Runtime Gateway Client 发起 `send_prompt` 请求(`apps/desktop/src/entities/runtime/runtime-gateway-client.ts`)。
+2. 命令经 MessagePort 跨进程通道进入后端 `utilityProcess`(`apps/desktop/electron/preload.ts`、`backend.ts`)。
+3. `createBackendService()` 将命令分发至 Runtime Gateway 实例(`packages/backend/src/service.ts`)。
+4. Gateway 按全局确定性规则生成用户消息 ID,并将命令转发给当前启用的 Driver(`packages/backend/src/gateway/runtime-gateway.ts`)。
+5. 进程驱动把命令转发到该 Session 的 worker 进程,由其中的 SDK 驱动调用 Pi 的 `AgentSession`(`packages/backend/src/drivers/session-process-driver.ts`、`pi-sdk-driver.ts`)。
+6. worker 中的 Normalizer 把 Pi 事件转换为标准格式,并通过 IPC 送回(`packages/backend/src/gateway/agent-runtime-event-normalizer.ts`)。
+7. Gateway 为每个事件盖上单调递增的序号,记录生命周期边界,同步更新投影(`packages/backend/src/persistence/`)。
+8. 事件沿同一传输通道返回渲染层,按 `surface` 戳路由到对应的界面组件(`apps/desktop/src/entities/runtime/`)。
+
+### 代码在哪里
+
+| 修改内容 | 对应位置 |
+| --- | --- |
+| 界面、页面、交互 | [`apps/desktop/src/`](../apps/desktop/src/),FSD 分层 `pages` → `widgets` → `features` → `entities` → `shared`([ADR-0016](adr/0016-fsd-layers-in-apps-desktop.md)、[ADR-0045](adr/0045-slice-agent-workspace-into-fsd.md));`bun run lint` 强制约束依赖方向 |
+| Live Session View / Session Draft / Session Dock | [`apps/desktop/src/widgets/live-chat/`](../apps/desktop/src/widgets/live-chat/)、[`features/session-draft/`](../apps/desktop/src/features/session-draft/)、[`widgets/session-dock/`](../apps/desktop/src/widgets/session-dock/) |
+| 事件语义(什么算 message / run / turn) | [`packages/backend/src/gateway/agent-runtime-event-normalizer.ts`](../packages/backend/src/gateway/) 及其基于录制数据的测试 |
+| Gateway 协议(命令、事件契约、身份) | [`packages/core/src/`](../packages/core/src/):`runtime-gateway.ts`、`agent-runtime-event.ts` |
+| 怎么驱动 Pi | [`packages/backend/src/drivers/`](../packages/backend/src/drivers/) |
+| 持久化与回放 | [`packages/backend/src/persistence/`](../packages/backend/src/persistence/) |
+| Packages 页(侧边栏):扩展包、资源、更新检查与事件日志诊断 | [`apps/desktop/src/pages/setup.tsx`](../apps/desktop/src/pages/setup.tsx)、[`packages/backend/src/workspace/resource-management.ts`](../packages/backend/src/workspace/resource-management.ts)、[`resource-diagnostics.ts`](../packages/backend/src/workspace/resource-diagnostics.ts)([ADR-0037](adr/0037-resource-management.md)) |
+| 模型可用性(模型目录、能力映射、凭据驱动的刷新) | [`packages/backend/src/workspace/model-catalog.ts`](../packages/backend/src/workspace/model-catalog.ts),映射见 [`packages/core/src/model-capabilities.ts`](../packages/core/src/model-capabilities.ts)([ADR-0043](adr/0043-model-catalog-owns-model-availability.md)) |
+| MCP 服务器管理(全局 `mcp.json`、探测、OAuth 登录) | [`packages/backend/src/workspace/mcp-servers.ts`](../packages/backend/src/workspace/mcp-servers.ts),契约见 [`packages/core/src/mcp-servers.ts`](../packages/core/src/mcp-servers.ts) |
+| 磁盘上的会话、Git 工作树和配置清单 | [`packages/backend/src/workspace/`](../packages/backend/src/workspace/) |
+| Electron 外壳与传输 | [`apps/desktop/electron/`](../apps/desktop/electron/):`main.ts`、`preload.ts`、`backend.ts` |
+| Dock Surface(Changes、Files、Terminal、Browser) | [`apps/desktop/src/shared/ui/session-dock/surface-registry.ts`](../apps/desktop/src/shared/ui/session-dock/surface-registry.ts) |
+| 设计系统规则 | [`docs/design/`](design/),自建组件清单见 [`docs/self-built-ui.md`](self-built-ui.md) |
+| 为什么这样设计 | [`docs/adr/`](adr/),术语在 [`CONTEXT.md`](../CONTEXT.md) |
+
+## 界面扩展点
+
+Pi 的扩展生态基于 `Package → Extension / Skill / Prompt / Theme` 体系,Pace 原样复用这一模型。目前代码中已存在的扩展点:
+
+- **事件级别的 `surface` 路由标签**:事件携带的 `chat | trace | status | composer | hidden` 标签决定它在界面上如何呈现。目前可选值固定,未来将作为扩展面板的标准接入点。
+- **Session Dock 面板注册表**:侧边栏里的每块可交互面板都是一个 Surface,有唯一 ID、标题、图标与提示,集中声明在 `surface-registry.ts`。`SessionSurfaceId` 目前是四个内置面板(Changes、Files、Terminal、内嵌 Browser)组成的封闭联合类型。[ADR-0032](adr/0032-session-dock-and-trajectory-vocabulary.md) 计划为注册表引入 `provider` 字段(`builtin` 或具体的 Pi 扩展 ID),让外部扩展提供的面板通过同一机制接入侧边栏;该字段尚未实现。
+- **Runtime Gateway 能力模型**:界面根据当前运行时声明的能力调整可用操作。针对 Pi SDK 的 Extension UI request,目前只在 SDK spike 驱动(`packages/backend/src/drivers/pi-sdk-spike.ts`)的事件覆盖盘点中出现,尚未接入 Runtime Gateway 协议([ADR-0018](adr/0018-runtime-gateway-api-and-pi-drivers.md))。
+
+另一个方向是终端难以实现的图形界面功能,例如支持对 DOM 元素进行批注和交互的内嵌浏览器([ADR-0029](adr/0029-embedded-browser-surface.md))。这也是 Pace 选择 Electron 的核心原因。
+
+## 仓库布局
+
+```plaintext
+apps/desktop/ Electron 应用:electron/(main、preload、后端宿主)+ src/(React,FSD)
+apps/server/ 预留:通过 WebSocket 提供服务的无界面后端(ADR-0015)
+apps/web/ 预留:apps/server 的浏览器客户端
+packages/core/ 共享内核:gateway 协议、事件模型、会话类型(ADR-0014)
+packages/backend/ drivers、gateway、persistence、workspace;service.ts 是组合根
+e2e/ 针对真实 Electron 应用的 Playwright 冒烟测试
+build/ 图标、entitlements、Icon Composer 源工程
+scripts/ 发布、打包与运行时捆绑脚本
+docs/ ADR、设计系统规则、发布与 dogfooding 指南
+CONTEXT.md 领域术语表;每个界面区域和概念在这里都有词条
+```
+
+技术栈:Electron + electron-vite、React 19、TypeScript、TanStack(Query / Router / Virtual)、Astryx 设计系统(组件样式由 StyleX 预编译)与 Tailwind v4、Bun workspaces、Vitest、Playwright。
+
+## 存储格式兼容性
+
+调整事件日志(journal)或查询投影(projection)的存储格式时,必须向后兼容旧格式或附带迁移脚本(见 [`docs/dogfooding.md`](dogfooding.md))。