@dotobokuri/fleet-console 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/AGENTS.md +101 -0
  2. package/README.md +69 -0
  3. package/dist/cli-bin.d.ts +2 -0
  4. package/dist/cli-bin.mjs +35423 -0
  5. package/dist/cli.d.ts +116 -0
  6. package/dist/cli.mjs +35429 -0
  7. package/dist/client/assets/_baseUniq-Bx4tjoo0.js +1 -0
  8. package/dist/client/assets/arc-D2VjIIjy.js +1 -0
  9. package/dist/client/assets/architectureDiagram-Q4EWVU46-BZwp8oQE.js +36 -0
  10. package/dist/client/assets/blockDiagram-DXYQGD6D-BFOEZdvM.js +132 -0
  11. package/dist/client/assets/c4Diagram-AHTNJAMY-CSR3Fk7i.js +10 -0
  12. package/dist/client/assets/cascadia-code-arabic-wght-normal-BxRhwSzF.woff2 +0 -0
  13. package/dist/client/assets/cascadia-code-braille-wght-normal-Cj7wfYns.woff2 +0 -0
  14. package/dist/client/assets/cascadia-code-cyrillic-ext-wght-normal-Bq2rGQtZ.woff2 +0 -0
  15. package/dist/client/assets/cascadia-code-cyrillic-wght-normal-DC72kP-V.woff2 +0 -0
  16. package/dist/client/assets/cascadia-code-greek-wght-normal-DmKacV-0.woff2 +0 -0
  17. package/dist/client/assets/cascadia-code-hebrew-wght-normal-CYieC9BD.woff2 +0 -0
  18. package/dist/client/assets/cascadia-code-latin-ext-wght-normal-CeKCfnVW.woff2 +0 -0
  19. package/dist/client/assets/cascadia-code-latin-wght-normal-CCwG33-X.woff2 +0 -0
  20. package/dist/client/assets/cascadia-code-symbols2-wght-normal-o0G5EPJ1.woff2 +0 -0
  21. package/dist/client/assets/cascadia-code-vietnamese-wght-normal-DXbdGs8p.woff2 +0 -0
  22. package/dist/client/assets/channel-DEE95baa.js +1 -0
  23. package/dist/client/assets/chunk-4BX2VUAB-CS98Xbj0.js +1 -0
  24. package/dist/client/assets/chunk-4TB4RGXK-CS16wI2h.js +206 -0
  25. package/dist/client/assets/chunk-55IACEB6-CIO8gXOu.js +1 -0
  26. package/dist/client/assets/chunk-EDXVE4YY-Dp62WKTv.js +1 -0
  27. package/dist/client/assets/chunk-FMBD7UC4-P-iX66To.js +15 -0
  28. package/dist/client/assets/chunk-OYMX7WX6-KYR0A13Y.js +231 -0
  29. package/dist/client/assets/chunk-QZHKN3VN-Bxf_1qP2.js +1 -0
  30. package/dist/client/assets/chunk-YZCP3GAM-fOywdyl7.js +1 -0
  31. package/dist/client/assets/classDiagram-6PBFFD2Q-C48o24xA.js +1 -0
  32. package/dist/client/assets/classDiagram-v2-HSJHXN6E-C48o24xA.js +1 -0
  33. package/dist/client/assets/clone-UUGnmCaX.js +1 -0
  34. package/dist/client/assets/cose-bilkent-S5V4N54A-CFVfzokO.js +1 -0
  35. package/dist/client/assets/cytoscape.esm-DH6-wILU.js +321 -0
  36. package/dist/client/assets/dagre-KV5264BT-CfFJpw9h.js +4 -0
  37. package/dist/client/assets/defaultLocale-DX6XiGOO.js +1 -0
  38. package/dist/client/assets/diagram-5BDNPKRD-ULNbraD0.js +10 -0
  39. package/dist/client/assets/diagram-G4DWMVQ6-BbMRdy0R.js +24 -0
  40. package/dist/client/assets/diagram-MMDJMWI5-xMtFUvhH.js +43 -0
  41. package/dist/client/assets/diagram-TYMM5635-zoxhe65u.js +24 -0
  42. package/dist/client/assets/erDiagram-SMLLAGMA-Bsi2YaEX.js +85 -0
  43. package/dist/client/assets/flowDiagram-DWJPFMVM-CJi0VEgQ.js +162 -0
  44. package/dist/client/assets/fraunces-latin-ext-wght-normal-Ca2vKHc0.woff2 +0 -0
  45. package/dist/client/assets/fraunces-latin-wght-normal-ukD16Tqj.woff2 +0 -0
  46. package/dist/client/assets/fraunces-vietnamese-wght-normal-CnvboYUG.woff2 +0 -0
  47. package/dist/client/assets/ganttDiagram-T4ZO3ILL-C6zhjR-p.js +292 -0
  48. package/dist/client/assets/gitGraphDiagram-UUTBAWPF-BWwF6PIg.js +106 -0
  49. package/dist/client/assets/graph-B_LOrVuH.js +1 -0
  50. package/dist/client/assets/index-CUwIAcWy.js +734 -0
  51. package/dist/client/assets/index-qy_LXUbN.css +1 -0
  52. package/dist/client/assets/infoDiagram-42DDH7IO-lGXnGt9J.js +2 -0
  53. package/dist/client/assets/init-Gi6I4Gst.js +1 -0
  54. package/dist/client/assets/ishikawaDiagram-UXIWVN3A-BOLdpalb.js +70 -0
  55. package/dist/client/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
  56. package/dist/client/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
  57. package/dist/client/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  58. package/dist/client/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  59. package/dist/client/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
  60. package/dist/client/assets/journeyDiagram-VCZTEJTY-BL3YNELi.js +139 -0
  61. package/dist/client/assets/kanban-definition-6JOO6SKY-hr-sYeeB.js +89 -0
  62. package/dist/client/assets/katex-DHMw6HUq.js +257 -0
  63. package/dist/client/assets/layout-BZ-MMmoc.js +1 -0
  64. package/dist/client/assets/linear-DC89C5fp.js +1 -0
  65. package/dist/client/assets/manrope-cyrillic-wght-normal-Dvxsihut.woff2 +0 -0
  66. package/dist/client/assets/manrope-greek-wght-normal-DL7QRZyv.woff2 +0 -0
  67. package/dist/client/assets/manrope-latin-ext-wght-normal-Ch3YOpNY.woff2 +0 -0
  68. package/dist/client/assets/manrope-latin-wght-normal-DHIcAJRg.woff2 +0 -0
  69. package/dist/client/assets/manrope-vietnamese-wght-normal-usUDDRr7.woff2 +0 -0
  70. package/dist/client/assets/mermaid.core-CwFfQIZ3.js +243 -0
  71. package/dist/client/assets/min-CQCIo8ng.js +1 -0
  72. package/dist/client/assets/mindmap-definition-QFDTVHPH-DST5EYZ1.js +96 -0
  73. package/dist/client/assets/ordinal-Cboi1Yqb.js +1 -0
  74. package/dist/client/assets/pieDiagram-DEJITSTG-B1cKU1RL.js +30 -0
  75. package/dist/client/assets/quadrantDiagram-34T5L4WZ-BAoS3KE9.js +7 -0
  76. package/dist/client/assets/requirementDiagram-MS252O5E-1Dy-goiy.js +84 -0
  77. package/dist/client/assets/sankeyDiagram-XADWPNL6-BiGdJMmS.js +10 -0
  78. package/dist/client/assets/sequenceDiagram-FGHM5R23-BF2eGtl0.js +157 -0
  79. package/dist/client/assets/stateDiagram-FHFEXIEX-Bbe8i846.js +1 -0
  80. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-C5NCIJbi.js +1 -0
  81. package/dist/client/assets/timeline-definition-GMOUNBTQ-C57TZcAM.js +120 -0
  82. package/dist/client/assets/vennDiagram-DHZGUBPP-CCLKJVMf.js +34 -0
  83. package/dist/client/assets/wardley-RL74JXVD-CkN25AoB.js +162 -0
  84. package/dist/client/assets/wardleyDiagram-NUSXRM2D-D7-EokFc.js +20 -0
  85. package/dist/client/assets/xychartDiagram-5P7HB3ND-Dr1PKcCW.js +7 -0
  86. package/dist/client/index.html +14 -0
  87. package/package.json +62 -0
  88. package/postinstall.mjs +37 -0
package/AGENTS.md ADDED
@@ -0,0 +1,101 @@
1
+ # Fleet Console Doctrine
2
+
3
+ `runtime/fleet-console` owns the Fleet Console — a standalone fullstack product: its own loopback HTTP backend plus the React web surface for observing carrier jobs, live output streams from registered fleet-cli workspaces, and the Codex/Fleet Wiki web surface, driven by the `fleet-console` CLI lifecycle. It is the unified Fleet GUI runtime.
4
+
5
+ ## Owns
6
+
7
+ - The console HTTP backend (loopback-only): its own server skeleton, CLI ingest bearer auth, security headers, static `/console/` serving of its own `dist/client/`, the CLI register-ingest API, the browser observer REST/SSE surface, and the terminal PTY WebSocket. The console no longer imports or launches the retired gateway package.
8
+ - The server lifecycle: lock file, runtime paths, health probe, and build-stale detection are console-owned. `fleet-console` is the daemon, not a launcher over someone else's daemon.
9
+ - The `fleet-console` CLI entry point (`./cli` export, `dist/cli.mjs`): `start` (the default when no subcommand is given) ensures the local console server and opens the console URL in a browser; if a healthy daemon already exists, it opens that daemon's URL without starting a new server or erroring. `stop` stops the console server; `restart` stops the console server then starts a fresh one and opens it; `status` prints server health, endpoint, console URL, and registered-workspace count. The server binds to an OS-assigned random loopback port and records the actual port in the lock file, so consumers discover the port from the lock endpoint. `--help`/`-h` prints the banner-style help. `fleet console <args>` in `fleet-cli` relays the full argument list to this CLI as a child process, so every subcommand works through both `fleet console …` and the standalone `fleet-console …` binary. The root `pnpm fleet-console` script runs it from source via `tsx`.
10
+ - The CLI register-ingest contract (server side): `POST /api/cli/register` (returns only `registrationId`, `ingestToken`, `heartbeatIntervalMs`, `leaseTtlMs`, `maxBatchEvents`), `POST /api/cli/events` (ordered `{cliRunId, seq, at, event}[]` batches authenticated by the ingest token; the console assigns its own `observedId`), `POST /api/cli/heartbeat`, and best-effort `POST /api/cli/deregister`. Registration and ingest are CLI-only; the shared register/ingest data-contract types are owned by `@dotobokuri/core-agent`.
11
+ - The React SPA served from the console backend at `/console/`: layout, components, styles, and visual identity. The global navigation bar owns **Theater** selection — a project root directory that groups console-owned terminal sessions and Codex wiki context. The Operations sidebar (under the Operation nav tab) lists terminal sessions filtered to the active Theater, each listing its carrier job history (active and finished) in registration order; selecting a job opens a centered streaming overlay over that session's terminal, scoped to the active session's jobs.
12
+ - The Codex/Fleet Wiki web surface under `/console/codex`: the console-owned Codex server gateway, workspace registry, wiki API routes, migrated vanilla TypeScript Maritime Codex client, `fleet wiki` compatibility helpers, and standalone `fleet-wiki` binary shim. The console-level **TheaterRegistry** is the source of truth for project roots and does not require a Fleet Wiki knowledge root; the Codex `WorkspaceRegistry` is the subset of Theaters whose directories contain a Fleet Wiki knowledge root. Codex must remain mounted under the Fleet Console GNB without an iframe or proxy daemon.
13
+ - The observer-side client contract: REST snapshot fetches and the SSE consumption loop with reconnect/resync.
14
+ - The streaming view model: the event reducer that folds `CarrierJobStreamEvent` timelines into per-job, per-track views with incremental text accumulation.
15
+
16
+ ## Codex / Fleet Wiki Surface
17
+
18
+ - Canonical Codex workspace routes live under `/console/codex/w/:ws/...`; MRU-compatible API routes live under `/console/codex/api/...`. Do not reintroduce global `/api/...` wiki routes because console owns `/api/cli/*`.
19
+ - The console-level **Theater** is the parent concept for project roots. Codex workspaces share the same id space (`workspaceHash(realpath(dir))`) but are a strict subset of the Theater registry (`hasWiki=true`). The Codex left workspace switcher is removed; Theater selection in the global navigation bar is the only workspace switch, and Theaters without a Fleet Wiki knowledge root render a "Codex 없음" state instead of mounting a wiki surface.
20
+ - The migrated Codex client stays Vanilla TypeScript under `client/src/codex/**`; do not rewrite it into React state or components beyond the React mount host.
21
+ - Preserve Maritime Codex UX: reading flow, raw viewer, Drydock queue, conflicts, index/log views, command palette, Manifest/ToC rails, copy-context actions, diagram lightbox, brass/aurora roles, and self-hosted fonts.
22
+ - Preserve wiki security invariants: Host allowlist, Origin guard, write-surface loopback gate, DOMPurify markdown sanitization, Mermaid `securityLevel: "strict"` with `htmlLabels: false` and no `bindFunctions`, path containment, and lockfile bearer auth for admin workspace registration.
23
+ - Browser payloads must not expose CLI ingest tokens, MCP/session tokens, terminal tickets, or Codex admin tokens.
24
+
25
+ ## Must Not Own
26
+
27
+ - Multi-tenant aggregation or tenant/session token issuance — the console observes a single workspace's registered fleet-cli sessions; it does not re-implement the retired gateway tenant model.
28
+ - MCP transport — the MCP HTTP/JSON-RPC server is owned by `fleet-cli` in-process (assembled from `@dotobokuri/core-agent` primitives). The console never proxies or owns MCP tool-call routing.
29
+ - Fleet tool builders, carrier persona policy, or provider-specific launch logic.
30
+
31
+ ## Token Boundary (hard rule)
32
+
33
+ - Browser observer routes are loopback-only and do not use browser bearer tokens.
34
+ - Terminal HTTP routes do not use browser bearer tokens, but must retain the terminal Origin check; the terminal WebSocket is reached through a one-use ticket.
35
+ - The CLI `ingestToken` and any MCP session token must never reach browser code, URL query strings, SSE payloads, terminal tickets, logs, or static assets.
36
+ - Theater routes likewise do not expose admin bearer tokens, ingest tokens, MCP/session tokens, terminal tickets, folder-grant identifiers, or raw working-directory paths to the browser.
37
+
38
+ ## Carrier Readiness Boundary
39
+
40
+ - `runtime/fleet-console/src/**` may import `@dotobokuri/fleet-carriers` public root exports to consume read-only Carrier Readiness read models for browser-safe observer payloads.
41
+ - `runtime/fleet-console/client/**` must not import `@dotobokuri/fleet-carriers`, carrier persona modules, deep carrier paths, or Node-only carrier runtime modules.
42
+ - Fleet Console may render display-safe carrier readiness data such as carrier id, display name, role/category, resolved model/effort, Task Force backend count, and subagent mode/tag.
43
+ - `fleet-carriers` remains the source of truth for carrier persona defaults, carrier-store interpretation, and carrier read-model construction. Console must not copy, reconstruct, mutate, or persist carrier persona policy or carrier runtime state.
44
+ - Console must not deep-import `@dotobokuri/fleet-carriers/src/**`, `packages/fleet-carriers/src/**`, `runtime/fleet-cli/**`, or `@dotobokuri/fleet-cli`.
45
+ - Carrier readiness browser payloads must not serialize prompt bodies, raw persona instructions, executor tool allowlists, tokens, credential values, auth env details, terminal/session/admin tickets, or raw filesystem paths.
46
+
47
+ ## Layout
48
+
49
+ - `src/` — Node-side backend and CLI lifecycle: the HTTP server (`server.ts`), bearer auth and security headers, static serving (`static-console.ts`), the register-ingest and observer routes (including `/observer/theaters*` Theater registry and session launch), the SSE helper, `codex/` (Fleet Wiki/Codex API gateway and workspace registration), `theaters.ts` (console-level in-memory TheaterRegistry), `theater.ts` (Theater id hash, realpath canonicalization, and label helpers), `terminal/` (PTY ticket/session/ws transport; console terminal sessions launch `fleet-cli --headless --native` so the child Agent CLI owns the PTY while registering with the console), the lifecycle modules (`lock.ts`, `paths.ts`, `health.ts`, `stale.ts`), and the CLI (`cli.ts`, `cli-bin.ts`, `browser.ts`, `help-style.ts`). Built by tsup to `dist/cli.mjs` and `dist/cli-bin.mjs`. Depends on `@dotobokuri/core-agent` for the shared register data contract; must **not** depend on the retired gateway package. `help-style.ts` is a CLI-help-only **self-hosted** style helper shared by the console and Codex compatibility CLIs; it must not import from `fleet-cli`, `packages/*` (beyond the core-agent contract), or `client/`, and changes to the shared banner/SGR vocabulary require manual sync across those copies.
50
+ - `client/` — the Vite React SPA (`client/src/`, `client/index.html`, `client/vite.config.ts`). Must not import Node-only modules or the console backend (`src/`).
51
+ - `tests/` — vitest suites for the reducer, SSE parser, store, register-ingest, terminal, and CLI lifecycle.
52
+
53
+ ## Tech Stack (deliberate)
54
+
55
+ - **React 19 + Vite + TypeScript.** Chosen because the console's core requirement is smooth incremental streaming UI and the package is slated to grow into the unified Fleet GUI. Do not replace with hand-rolled DOM rendering. A second surface has now landed (the Welcome dashboard), so `react-router-dom` (`BrowserRouter` with `basename="/console"`) is the sanctioned client router. Routes: `/` renders **Welcome** (the live dashboard); `/operations` renders the carrier observation surface (Sidebar + JobView); unknown paths redirect to `/`. The console backend already serves extensionless `/console/*` paths as `index.html` (SPA fallback in `static-console.ts`), so client-side routes require **no** backend change. Routing state belongs to react-router; observation data stays in the external `store.ts`. Do not add a state-management library until that store proves insufficient.
56
+ - State lives in a framework-agnostic external store (`client/src/store.ts`) bridged via `useSyncExternalStore`. Pure reduction logic stays in `client/src/reduce.ts` and must remain React-free and unit-tested.
57
+ - Web fonts are self-hosted via `@fontsource-variable/*`. External font CDNs are forbidden.
58
+ - Browser launch must use OS-level commands via `child_process.spawn`; do not add an `open` dependency.
59
+
60
+ ## Streaming Invariants
61
+
62
+ - `track:text` / `track:thought` events are **deltas**; the reducer appends them per track. Never treat them as snapshots.
63
+ - Event ids (the console-assigned `observedId`) are globally monotonic across all registered CLI sessions; the reducer must ignore non-advancing ids so snapshot resync and live frames can overlap safely.
64
+ - Snapshot rebuild (`/observer/jobs`) and live SSE application must go through the same reducer (`applyEvent`) — no second interpretation of event payloads.
65
+ - The output view keeps pin-to-bottom follow behavior: pinned within slack distance, released on upward scroll, restored via the follow button. Removing this is a UX regression.
66
+ - `sentTextLength` tracks emitted length from `textLength` metadata so retention clamping on the console-backend side stays visible to the operator.
67
+
68
+ ## Design Identity — "Maritime Console"
69
+
70
+ The console is the operations variant of Fleet Wiki's **Maritime Codex** language: same deep-water ink, brass instrumentation, aurora life signals, glass surfaces, and codex motion grammar, but tuned for live observation rather than reading. It is a command instrument over the same sea, not an editorial document view.
71
+
72
+ - **Relationship to Maritime Codex**: `client/src/codex/**` owns the migrated Maritime Codex reading surface. Console may translate the vocabulary for operations needs, but it must stay visibly related through the shared token system, glass atmosphere, brass/aurora pairing, Fraunces display type, and `codex-rise` motion.
73
+ - **Color semantics**:
74
+ - `brass` means "지금 보고 있는 곳" — selected job brass dot indicator, active navigation, structural decoration, and non-live active/focus-adjacent emphasis.
75
+ - `aurora` means "지금 살아있는 것" — streaming status, live dots, tenant beacons, stream caret, follow button, and `connection-chip--live`. Unlike Fleet Wiki, console does not reserve aurora only for document linkage because there is no document-link concept here.
76
+ - `coral` means error/bad; `--warn` (amber, near `oklch(80% 0.13 85)`) means warning/connecting; neutral ink means idle.
77
+ - **Typography**: `Fraunces Variable` is display type for the topbar brand, job titles, idle marks, and large headings. `Manrope Variable` is the default UI family. `JetBrains Mono Variable` is for stream output, job ids, timelines, and eyebrow labels with uppercase tracked styling. **Exception**: the Operations terminal (xterm) uses `Cascadia Code` — a terminal-tuned face for box-drawing/Powerline glyph alignment — rendered via the xterm WebGL addon with DOM fallback. This is the sole surface where the console mono identity deliberately diverges from JetBrains Mono; the terminal font lives in the `terminal.tsx` xterm options (xterm takes a JS font string, not a CSS token), so it is not a `theme.css` variable.
78
+ - **Surface and atmosphere**: `body::before` owns the multi-radial cold teal + brass afterglow field, and `body::after` owns the `feTurbulence` grain overlay. Sidebar, selected-job stage, timeline dock, and job summary are glass cards using `backdrop-filter: blur(18px) saturate(140%)`, `--surface-glass`, `--surface-rim`, `--shadow-soft`, and `--radius-xl`/large-radius surfaces.
79
+ - **Motion**: panes use one first-paint `codex-rise` reveal (720ms, `--ease-spring`, topbar/sidebar/stage staggered 40/120/200ms). Live dots use aurora pulse, the stream caret keeps its blink, and ambient infinite motion is forbidden. `prefers-reduced-motion` must continue to short-circuit animation.
80
+ - **Hard bans**: no font CDN; no `Inter`/`Roboto`/`Arial`/`system-ui` as the first font family; no solid `#fff` or `#000` backgrounds; no card/button/chip radius at or below 4px; no removal of `prefers-reduced-motion`; no mixing brass and aurora roles; no reintroduction of `--carbon-*` or `--signal-*` token families.
81
+ - CSS stays in three layers: `theme.css` (tokens/reset/keyframes only), `layout.css` (shell grid/breakpoints only), `components.css` (every concrete surface).
82
+
83
+ ## TypeScript File Structure
84
+
85
+ All `.ts`/`.tsx` files follow:
86
+
87
+ ```text
88
+ imports -> types/interfaces -> constants -> functions/components
89
+ ```
90
+
91
+ ## Build & Serve Contract
92
+
93
+ - `pnpm --filter @dotobokuri/fleet-console build` runs tsup (`src/cli.ts` → `dist/cli.mjs`) and Vite (`client/` → `dist/client/` with `base: "/console/"`). There is **no** embed step: the console backend serves its own `dist/client/` directly under `/console/` (loopback-only). Changing `base` or the output layout breaks the static-serving contract.
94
+ - This package **is** the HTTP server. The backend owns its own loopback server, lifecycle, and `/console/` serving; the CLI starts and stops that server rather than launching a separate daemon.
95
+ - **npm publish contract**: tsup bundles every `@dotobokuri/*` workspace dependency inline (`noExternal: [/^@dotobokuri\//]`) so the published package is self-contained; only `node-pty` (native binding) and `ws` (dynamic `require`) stay external. `scripts/publish-fleet-console.mjs` drops `private`, replaces `dependencies` with just those two externals, and injects the `node-pty` `postinstall`. Do **not** add a statically-imported workspace package without confirming it bundles, and re-verify the published manifest with `npm pack` after touching `noExternal` or runtime deps — leaving a `workspace:*` dependency in the manifest breaks `npm install`.
96
+
97
+ ## Tests
98
+
99
+ - `pnpm --filter @dotobokuri/fleet-console test`
100
+ - `pnpm --filter @dotobokuri/fleet-console typecheck`
101
+ - `pnpm --filter @dotobokuri/fleet-console build`
package/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # Fleet Console
2
+
3
+ Standalone loopback web console for observing registered Fleet CLI workspaces, carrier jobs, live output streams, and multi-session PTY terminal workspaces.
4
+
5
+ ## What It Does
6
+
7
+ Fleet Console owns its own local HTTP server. Fleet CLI processes register with the console when available, push ordered event batches through the CLI-only ingest API, and continue normally if the console is absent.
8
+
9
+ - Registered CLI workspaces and observed jobs in a navigable rail.
10
+ - Workspace hub sessions created from OS-native folder selection.
11
+ - Console-spawned `fleet-cli --native` PTYs with deterministic registration binding.
12
+ - Per-job carrier tracks with incremental output text, reasoning folds, and tool-call activity.
13
+ - Codex/Fleet Wiki browsing under the shared Console GNB at `/console/codex`.
14
+ - Browser observer snapshots and SSE streams backed by console-owned global observed ids.
15
+ - Browser terminal access through short-lived tickets over WebSocket.
16
+
17
+ ## Runtime Channels
18
+
19
+ | Channel | Purpose | Token Boundary |
20
+ |---|---|---|
21
+ | `POST /api/cli/register` | CLI registers a workspace session. | Uses the console bootstrap token from the lock file. |
22
+ | `POST /api/cli/events` | CLI pushes `{ cliRunId, seq, at, event }[]` batches. | Uses CLI-only `ingestToken`; never sent to browser code. |
23
+ | `/observer/*` | Browser snapshot and SSE observer surface. | Loopback-only; no browser bearer token. |
24
+ | `POST /terminal/folders/pick` | Opens a native folder picker and returns a one-use folder grant, or `{ cancelled: true }`. | Requires the terminal Origin boundary; selected paths are kept server-side. |
25
+ | `POST /terminal/sessions` | Consumes `{ folderGrantId }` to create a console-spawned `fleet-cli --native` PTY session. | Raw cwd values from browser requests are rejected. |
26
+ | `GET /terminal/sessions` | Lists non-secret terminal session metadata for hydration. | Requires the terminal Origin boundary. |
27
+ | `POST /terminal/ticket` + `/terminal/ws` | Browser terminal PTY transport; ticket requests may include `{ sessionId }` and default to `"default"` for compatibility. | Browser receives a one-use ticket. |
28
+ | `/console/` | Static React client served from this package's `dist/client`. | Served directly from the loopback console URL. |
29
+ | `/console/codex/*` | Console-owned Codex/Fleet Wiki web, workspace API, and migrated Maritime Codex client. | Admin workspace registration uses the lock bearer token; browser reads stay token-free on allowed local origins. |
30
+
31
+ `/observer/tenants` may include `terminalSessionId` when a registered CLI workspace is deterministically bound to a console-spawned terminal session. `/terminal/ws` keeps the same path and query shape.
32
+
33
+ ## Session Binding
34
+
35
+ When the console creates a terminal session, it generates a session id and launches `fleet-cli --native` with `FLEET_CONSOLE_SESSION_ID`, `INIT_CWD`, and `PWD` set to the selected absolute cwd. Fleet CLI uses that session id as `cliRunId` unless an explicit `cliRunId` was provided. The console binds registration metadata to a pending terminal session only when `cliRunId === sessionId` and the canonical cwd matches. It does not use pid matching or cwd/time proximity fallback.
36
+
37
+ Folder grants are one-use and in-memory. Folder picker cancellation is a normal response. Picker failures are reported with typed errors such as `unsupported_platform`, `dialog_unavailable`, `dialog_timeout`, and `invalid_folder`.
38
+
39
+ ## Security Notes
40
+
41
+ HTTP surfaces are loopback-only. CLI ingest remains protected by bearer tokens, while browser observer routes are directly available on loopback and terminal routes retain their Origin boundary. CLI `ingestToken`, MCP session tokens, bootstrap tokens, and selected absolute paths are not exposed through browser payloads, URL query strings, SSE frames, terminal tickets, logs, or static assets.
42
+
43
+ Codex/Fleet Wiki routes preserve the migrated wiki security boundary: Host allowlist, Origin checks for write routes, loopback write gates, path containment, DOMPurify markdown sanitization, strict Mermaid rendering, and lockfile bearer auth for workspace registration.
44
+
45
+ ## Usage
46
+
47
+ ```bash
48
+ fleet console # via fleet-cli
49
+ fleet-console # standalone binary
50
+ fleet-console status
51
+ fleet-console stop
52
+ fleet wiki # opens the console-owned Codex surface
53
+ fleet-wiki # standalone compatibility binary from this package
54
+ ```
55
+
56
+ The launcher ensures the local console server is running and opens `/console/` directly without browser token fragments.
57
+
58
+ ## Development
59
+
60
+ ```bash
61
+ pnpm --filter @dotobokuri/fleet-console dev
62
+ pnpm --filter @dotobokuri/fleet-console test
63
+ pnpm --filter @dotobokuri/fleet-console typecheck
64
+ pnpm --filter @dotobokuri/fleet-console build
65
+ ```
66
+
67
+ `build` emits `dist/cli.mjs` and `dist/client/`. There is no external embed step.
68
+
69
+ See `AGENTS.md` for ownership, token-boundary, and streaming invariants.
@@ -0,0 +1,2 @@
1
+
2
+ export { }