@sma1lboy/kobe 0.7.101 → 0.8.1

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 (50) hide show
  1. package/README.md +32 -305
  2. package/dist/cli/index.js +456 -470
  3. package/dist/web-ui/assets/{AppShell-BEJGNTTN.js → AppShell-D5qnwUMs.js} +2 -2
  4. package/dist/web-ui/assets/Board-rMFDmqPk.js +1 -0
  5. package/dist/web-ui/assets/{BoardPeek-BTehy4UX.js → BoardPeek-BCu0X7f6.js} +2 -2
  6. package/dist/web-ui/assets/ChatTerminal-BrP-ENHg.css +1 -0
  7. package/dist/web-ui/assets/ChatTerminal-o8jB1xhy.js +143 -0
  8. package/dist/web-ui/assets/{ChatTranscript-BKbzoH8U.js → ChatTranscript-CARRzyc3.js} +1 -1
  9. package/dist/web-ui/assets/{ConfirmDialog-s0vMlcAP.js → ConfirmDialog-CA4-jGup.js} +1 -1
  10. package/dist/web-ui/assets/{IssueIntakePanel-DzyNodnf.js → IssueIntakePanel-DMPEbckt.js} +1 -1
  11. package/dist/web-ui/assets/IssuePeek-ETnooKbW.js +1 -0
  12. package/dist/web-ui/assets/IssuesPage-DbadUcgK.js +1 -0
  13. package/dist/web-ui/assets/{RichEditor-B5dldvlg.js → RichEditor-CLKcirfq.js} +1 -1
  14. package/dist/web-ui/assets/{SettingsPage-DF_alouR.js → SettingsPage-CLiLO3DV.js} +1 -1
  15. package/dist/web-ui/assets/{SlideOver-Ds3g7tXz.js → SlideOver-BDk46jas.js} +1 -1
  16. package/dist/web-ui/assets/{ViewToggle-CfWPMzZq.js → ViewToggle-C5g-6hVX.js} +1 -1
  17. package/dist/web-ui/assets/{WorkspaceTabs-DR7NCXZH.js → WorkspaceTabs-BzC5r6yX.js} +3 -3
  18. package/dist/web-ui/assets/arrow-left-CTu620DY.js +1 -0
  19. package/dist/web-ui/assets/board-DPzxbbaO.js +1 -0
  20. package/dist/web-ui/assets/{chips-L2qle6td.js → chips-ER3SiHRg.js} +1 -1
  21. package/dist/web-ui/assets/{createLucideIcon-Dn8f0BBU.js → createLucideIcon-B3ImGkvG.js} +1 -1
  22. package/dist/web-ui/assets/{external-link-CGQEaSmM.js → external-link-D0CjtZaF.js} +1 -1
  23. package/dist/web-ui/assets/{external-store-DUMhHvtl.js → external-store-BMGmoHuF.js} +1 -1
  24. package/dist/web-ui/assets/harness-CK84StwB.js +1 -0
  25. package/dist/web-ui/assets/{index-CLHcUG-u.js → index-D6_gfBg1.js} +3 -3
  26. package/dist/web-ui/assets/issues-C28QnXY7.js +1 -0
  27. package/dist/web-ui/assets/issues-DVIXgRvr.js +4 -0
  28. package/dist/web-ui/assets/lazy-issue-panels-D9Cl4s2i.js +6 -0
  29. package/dist/web-ui/assets/{rotate-cw-zLlRat-M.js → rotate-cw-BxAflhQC.js} +1 -1
  30. package/dist/web-ui/assets/routes-Cmq1duQP.js +1 -0
  31. package/dist/web-ui/assets/{store-CbgoTSs1.js → store-BvkKuplZ.js} +2 -2
  32. package/dist/web-ui/assets/{tabs-B_hac99E.js → tabs-C6drmk5t.js} +1 -1
  33. package/dist/web-ui/assets/task._taskId-Dnrgrhvc.js +1 -0
  34. package/dist/web-ui/assets/{toast-D798wIYZ.js → toast-CvhQ8RqX.js} +1 -1
  35. package/dist/web-ui/assets/{worktrees-Sg0XZDuk.js → worktrees-vJFxdsyR.js} +1 -1
  36. package/dist/web-ui/index.html +6 -6
  37. package/package.json +5 -7
  38. package/dist/web-ui/assets/Board-IDFIzXrT.js +0 -1
  39. package/dist/web-ui/assets/ChatTerminal-kHJ-D0s7.css +0 -1
  40. package/dist/web-ui/assets/ChatTerminal-yge5k7Tv.js +0 -8
  41. package/dist/web-ui/assets/IssuePeek-j-sd5Pit.js +0 -1
  42. package/dist/web-ui/assets/IssuesPage-CizzkyG3.js +0 -1
  43. package/dist/web-ui/assets/arrow-left-BXrVItPe.js +0 -1
  44. package/dist/web-ui/assets/board-B6uuMuPK.js +0 -1
  45. package/dist/web-ui/assets/harness-BRyFen92.js +0 -1
  46. package/dist/web-ui/assets/issues-BNEYA0hF.js +0 -3
  47. package/dist/web-ui/assets/issues-BpIswsef.js +0 -1
  48. package/dist/web-ui/assets/lazy-issue-panels-BuVM5o5S.js +0 -6
  49. package/dist/web-ui/assets/routes-B-g-4AF8.js +0 -1
  50. package/dist/web-ui/assets/task._taskId-D9HssxYO.js +0 -1
package/README.md CHANGED
@@ -1,330 +1,57 @@
1
- <p align="center">
2
- <img src="docs/assets/brand/bracket-chip.gif" alt="kobe" width="720" />
3
- </p>
1
+ # @sma1lboy/kobe
4
2
 
5
- <p align="center">
6
- <strong>One terminal, many Claude Code sessions.</strong><br/>
7
- kobe is a TUI that runs N Claude Code agents in parallel — each in its own git worktree — so you can drive a small team of tasks from one screen.
8
- </p>
9
-
10
- <p align="center">
11
- <em>Codename — will be renamed before any non-beta release.</em>
12
- </p>
13
-
14
- ---
15
-
16
- ## What kobe is
17
-
18
- A terminal UI on top of the `claude` CLI. It gives you a Conductor-shaped layout
19
- (sidebar of tasks, workspace pane with chat + file tabs, file tree, embedded
20
- terminal, status bar) and runs each task in its own isolated git worktree, so
21
- multiple Claude Code sessions can edit the same repo at the same time without
22
- stepping on each other.
23
-
24
- If you've used a single `claude` session and wished you could fan out to five,
25
- that's the gap kobe fills.
26
-
27
- ## Install
28
-
29
- [![npm](https://img.shields.io/npm/v/%40sma1lboy%2Fkobe.svg)](https://www.npmjs.com/package/@sma1lboy/kobe)
30
-
31
- You need two things on `PATH`:
32
-
33
- - [**Bun**](https://bun.sh) ≥ 1.0 — kobe's renderer is opentui, which uses Bun-FFI.
34
- - [**`claude`** CLI](https://docs.anthropic.com/en/docs/claude-code) — the engine kobe drives. Run `claude --version` to confirm it's installed and signed in.
35
-
36
- Optional but recommended (preview pane shows graceful fallbacks otherwise):
37
-
38
- - **`chafa`** ≥ 1.8 + **`ffmpeg`** / **`ffprobe`** — image preview (sixel + character grid + animated GIF). Without these, image files show a metadata card with a "preview not supported" hint.
39
- - **`rsvg-convert`** (`librsvg2-bin`) — SVG → rasterized image preview. Without it, SVGs fall back to syntax-highlighted XML source.
40
-
41
- | Platform | Install command |
42
- |---|---|
43
- | Debian / Ubuntu | `sudo apt install chafa ffmpeg librsvg2-bin` |
44
- | Fedora | `sudo dnf install chafa ffmpeg librsvg2-tools` |
45
- | Arch | `sudo pacman -S chafa ffmpeg librsvg` |
46
- | macOS | `brew install chafa ffmpeg librsvg` |
47
- | Windows | `winget install hpjansson.chafa Gyan.FFmpeg` |
48
-
49
- `bun install` runs a postinstall check and prints any missing pieces with the install command. Set `KOBE_SKIP_DEP_CHECK=1` to silence it in CI.
50
-
51
- Then:
3
+ The published kobe CLI and PureTUI package.
52
4
 
53
5
  ```bash
54
6
  bun install -g @sma1lboy/kobe
7
+ kobe add /path/to/repo
55
8
  kobe
56
9
  ```
57
10
 
58
- Or run without installing:
59
-
60
- ```bash
61
- bunx @sma1lboy/kobe
62
- ```
63
-
64
- The first launch drops you into an empty sidebar — press `n` to create your
65
- first task. kobe will ask for a repo path and a base branch, then spin
66
- up a worktree at `<repo>/.claude/worktrees/<task-id>/` and a chat pane
67
- talking to a fresh `claude` session inside it.
68
-
69
- ## A glimpse
70
-
71
- <p align="center">
72
- <img src="docs/assets/brand/pane-grid.gif" alt="kobe pane layout" width="720" />
73
- </p>
74
-
75
- ## What you can do
76
-
77
- Once you're in, the keys you'll use most:
78
-
79
- | Key | What it does |
80
- | ------------------ | -------------------------------------------------------------- |
81
- | `ctrl+h` / `ctrl+j` / `ctrl+k` / `ctrl+l` | Move between tmux panes (Tasks, engine, Ops files, shell) |
82
- | `ctrl+q` | Detach back to your launching shell; the task tmux session keeps running |
83
- | `ctrl+t` | Open a same-engine ChatTab window on the current task/worktree |
84
- | `ctrl+shift+t` or tmux `prefix T` | Pick an engine, then open a new ChatTab window |
85
- | `ctrl+[` / `ctrl+]` | Switch to previous / next ChatTab window |
86
- | `ctrl+w` | Close the current ChatTab window; the final window is protected |
87
- | `F2` | Rename the current ChatTab window |
88
- | tmux `prefix f` | Open the Tasks pane's new-task dialog from anywhere in the session |
89
-
90
- Inside the Tasks pane, with a task highlighted: `n` creates a task, `j/k` moves, `enter` opens, `r` renames, `b` renames the branch, `v` cycles the engine, `o` opens the worktree in your editor, `a` archives/unarchives, `d` deletes, `s` opens Settings, and `[` / `]` switches between Working session and Archives. Archive/delete also kill the task's cached tmux session when one exists.
91
-
92
- Inside the Ops files pane: `[` / `]` switches All / Changes, `enter` opens the preview, `a` injects an `@file` mention into the engine pane, `p` injects the create-PR prompt, `r` refreshes, and `o` opens a file externally when that makes sense.
93
-
94
- A given task can host **multiple ChatTab tmux windows** on the same worktree — useful when you want a parallel sub-conversation without losing the main thread.
95
-
96
- ## Opening tasks in your editor
97
-
98
- The top bar shows an `[Open] <editor>` chip when kobe can find an editor for the
99
- active task. Click it, use `ctrl+o`, or run **Open task in editor** from the
100
- command palette to open the task's worktree.
101
-
102
- Detection order is:
103
-
104
- 1. `KOBE_OPEN_EDITOR`
105
- 2. `code` (VS Code)
106
- 3. `cursor`
107
- 4. `windsurf`
108
- 5. `zed`
109
- 6. platform fallback (`open` on macOS, `xdg-open` on Linux)
110
-
111
- Set `KOBE_OPEN_EDITOR` globally if you want to force a specific tool:
112
-
113
- ```bash
114
- export KOBE_OPEN_EDITOR=cursor
115
- export KOBE_OPEN_EDITOR=code
116
- export KOBE_OPEN_EDITOR=/Applications/Cursor.app/Contents/Resources/app/bin/cursor
117
- ```
118
-
119
- For the full feature manifest, see [`CHANGELOG.md`](./CHANGELOG.md).
120
-
121
- ## Browser dashboard
122
-
123
- The browser dashboard is experimental and ships with the default npm package.
124
- Installed packages can start it directly with `kobe web`; source checkouts can
125
- run the sandbox dev stack from `packages/kobe-web`:
126
-
127
- ```bash
128
- kobe web # http://localhost:5174
129
-
130
- cd packages/kobe-web
131
- bun run dev:sandbox # http://localhost:5173, isolated from production
132
- ```
133
-
134
- When present, `kobe web` connects to the same daemon as the TUI, so tasks
135
- created in either surface appear in both. The process model, routes, and
136
- security posture are documented in
137
- [`docs/design/web-dashboard.md`](../../docs/design/web-dashboard.md).
138
-
139
- ## Custom themes
140
-
141
- kobe ships a handful of bundled themes (`claude` is the default), and any JSON
142
- file you drop into `~/.kobe/themes/` is auto-loaded at boot and shows up in
143
- Settings → Theme alongside the built-ins. Themes are publishable as raw JSON
144
- on GitHub and installed with one command:
145
-
146
- ```bash
147
- kobe theme add https://raw.githubusercontent.com/<you>/<repo>/main/<your-theme>.json
148
- kobe theme list
149
- kobe theme remove <name>
150
- ```
151
-
152
- A JSON Schema at [`packages/kobe/src/tui/context/theme/theme.schema.json`](./src/tui/context/theme/theme.schema.json)
153
- gives editor autocomplete — reference it via `"$schema"` in your theme file.
154
-
155
- Full guide (shape, examples, GitHub publishing flow):
156
- [`docs/themes.md`](../../docs/themes.md).
157
-
158
- ## Where things live
159
-
160
- - Tasks: `~/.kobe/tasks.json`
161
- - User themes: `~/.kobe/themes/*.json`
162
- - Per-task worktrees: `<repo>/.claude/worktrees/<task-id>/`
163
- - UI state (theme, sidebar widths, last-active task): kobe's KV store, also under `~/.kobe/`
164
-
165
- ## Troubleshooting
166
-
167
- **`command not found: claude`** — kobe shells out to the `claude` CLI; install
168
- it from [the Claude Code docs](https://docs.anthropic.com/en/docs/claude-code)
169
- and confirm `claude --version` works in the same shell you launched kobe from.
170
-
171
- **`bun: command not found`** — install [Bun](https://bun.sh) (`curl -fsSL https://bun.sh/install | bash`).
172
- kobe's renderer requires Bun ≥ 1.0; it does not run under Node.
11
+ Plain `kobe` launches one React/opentui Workspace Host. Interactive engine and
12
+ shell processes are owned by the standalone PTY Host, so they survive TUI exits
13
+ and daemon restarts.
173
14
 
174
- **The terminal pane is blank** — kobe starts your `$SHELL` through Bun's native PTY. Confirm `$SHELL` points at an installed shell, your Bun version supports `Bun.spawn({ terminal })`, and the active task's worktree path still exists. `KOBE_TERMINAL_BACKEND=pipe` is available only as a fallback.
175
-
176
- **Some shortcuts do not work inside tmux** — kobe asks opentui to enable the
177
- kitty / CSI-u keyboard protocol, but tmux must pass those extended key
178
- sequences through. Add this to `~/.tmux.conf`, then restart tmux:
179
-
180
- ```tmux
181
- set -g extended-keys on
182
- set -as terminal-features ',xterm*:extkeys'
183
- set -as terminal-features ',tmux*:extkeys'
15
+ ```text
16
+ Task = git worktree + hosted engine sessions + branch
184
17
  ```
185
18
 
186
- Your outer terminal still has to send the sequences. For iTerm2, enable
187
- profile-level CSI-u key reporting. Terminal-app or macOS-level shortcuts can
188
- still intercept Option/Cmd chords before tmux sees them; no tmux setting can
189
- pass through a shortcut the terminal never forwards.
190
-
191
- **`posix_spawnp failed` when running `bun run test:behavior`** — on macOS arm64,
192
- Bun's installer occasionally ships `node-pty`'s prebuilt `spawn-helper` without
193
- an exec bit. The behavior-test driver fixes it lazily on first spawn (see
194
- `test/behavior/driver.ts`), so a re-run usually clears it. If not, run
195
- `chmod +x node_modules/node-pty/build/Release/spawn-helper`.
196
-
197
- **Worktree won't create** — kobe wants a clean git repo. The new-task dialog
198
- validates the repo path before creating; if it's complaining, check that
199
- `git status` runs cleanly inside the path you typed.
200
-
201
- ## Driving kobe from another agent
202
-
203
- Inside kobe, the `claude` (or `codex`, etc.) you are talking to can call back
204
- out and spawn more kobe tasks — useful when you ask it to "try three approaches
205
- in parallel" instead of doing them sequentially in one chat. The mechanism is a
206
- small CLI surface; design rationale lives in [`docs/design/cli-api.md`](../../docs/design/cli-api.md).
207
-
208
- ### Daemon lifecycle
209
-
210
- A `kobe daemon` process holds your tasks and chat sessions. The TUI auto-starts
211
- one on first launch; in scripts you may want to manage it explicitly.
19
+ ## Main commands
212
20
 
213
21
  ```bash
214
- kobe daemon start # spawn detached, listen on the unix socket
215
- kobe daemon status # JSON status (pid, uptime, attached clients, task count)
216
- kobe daemon restart # graceful stop + start
217
- kobe daemon stop # tell the daemon to drain and exit
22
+ kobe --help
23
+ kobe web
24
+ kobe daemon status
25
+ kobe daemon restart
26
+ kobe api --help
218
27
  ```
219
28
 
220
- > Pre-0.6 builds shipped a separate `kobed` binary for the same commands. It
221
- > was removed in favor of the single-bin surface (KOB-136); any script with
222
- > `kobed restart` needs a one-time rename to `kobe daemon restart`.
223
-
224
- ### `kobe api <verb>` — six shell verbs
225
-
226
- Each call is a short-lived process: connect to (or auto-start) the daemon, do
227
- the work, print JSON to stdout, exit. Any tool with a `Bash` capability (Claude
228
- Code, Codex, Cursor, a custom agent) can drive it.
229
-
230
- | verb | flags | what it does |
231
- |---|---|---|
232
- | `spawn-task` | `--repo PATH [--prompt TEXT] [--title T] [--base-branch B] [--vendor V]` | Create one task + worktree. With `--prompt`, also start the engine in tmux and deliver the prompt. |
233
- | `fan-out` | `--repo PATH --prompt TEXT [--count N \| --agents claude:2,codex:1] [--base-branch B]` | Spawn N tasks of the same prompt in one call (per-engine counts optional). Returns `{count, tasks[]}`. Capped at 10. |
234
- | `send` | `[--task-id ID] --prompt TEXT` | Paste a prompt into a task's engine pane (bracketed paste, then Enter — multi-line stays one turn). Defaults to the active task; prefer `--task-id` for unattended fan-out. |
235
- | `get-task` | `--task-id ID` | Read task metadata; `.running` is true when the tmux session is live. |
236
- | `collect` | `--task-ids a,b,c \| --repo PATH` | Read-only aggregation snapshot: per task, branch + `.running` + uncommitted `.changes` ({added, deleted}) for comparing attempts. |
237
- | `list` | — | List all tasks. |
238
-
239
- `spawn-task --prompt` and `send` also return `.engineReady` — `false` means a freshly-started engine didn't confirm it was ready before the prompt was pasted (delivered best-effort).
240
-
241
- Output is one JSON object on stdout, `\n` terminated, exit 0. Errors land on
242
- stderr as `{"error":{"message":"...","code":"..."}}` with a non-zero exit.
243
- Add `--pretty` for human inspection.
244
-
245
- v0.6 is tmux-native — a task's chat history lives in its tmux session, not in
246
- the daemon — so `send` types the prompt into the engine pane and there is no
247
- verb that reads the reply back. Results are reviewed in the TUI. (The v0.5
248
- `create-tab` / `get-tab` verbs are gone; extra chat tabs are tmux windows
249
- opened from inside the TUI.)
250
-
251
- Fan-out from a shell:
29
+ Prompted API calls can run headlessly. `send`, prompted `add`, and `fan-out`
30
+ ensure the task Worktree and canonical `<taskId>::tab-1` hosted engine session
31
+ without requiring an open TUI.
252
32
 
253
33
  ```bash
254
- T1=$(kobe api spawn-task --repo "$PWD" --prompt "Approach A: state machine" | jq -r .taskId)
255
- T2=$(kobe api spawn-task --repo "$PWD" --prompt "Approach B: event sourcing" | jq -r .taskId)
256
- T3=$(kobe api spawn-task --repo "$PWD" --prompt "Approach C: reducer pattern" | jq -r .taskId)
257
-
258
- # Tell the user three tasks are running — they'll appear in the sidebar.
259
- echo "Spawned $T1 $T2 $T3 — open the kobe TUI to watch them"
260
-
261
- # Confirm each session came up.
262
- for ID in $T1 $T2 $T3; do
263
- kobe api get-task --task-id "$ID" | jq -r '"\(.task.id) running=\(.running)"'
264
- done
34
+ kobe api add --repo . --prompt "implement the feature" --pretty
35
+ kobe api send --task-id <id> --prompt "run tests"
36
+ kobe api pty-list --pretty
265
37
  ```
266
38
 
267
- `kobe api ...` auto-starts the daemon, so there is nothing to launch first. If
268
- the daemon cannot be reached or started, it exits 2 with
269
- `{"error":{"code":"BAD_DAEMON",...}}` on stderr.
39
+ Press `F1` in the TUI for live help. Direct and prefix bindings are configured
40
+ in `~/.kobe/settings/keybindings.yaml`.
270
41
 
271
- ### Install the agent skill
42
+ ## Development
272
43
 
273
- `kobe api` gives the *capability*. The SKILL.md gives the model the
274
- *intent* — when to fan out, how to scope subtask prompts, how to read results
275
- back. Install it via the [Vercel Labs agent-skills CLI](https://github.com/vercel-labs/skills):
276
-
277
- ```bash
278
- npx skills add Sma1lboy/kobe --skill kobe --agent claude-code
279
- ```
280
-
281
- The skill source lives at `.agents/skills/kobe/SKILL.md` in this repo,
282
- which is one of the directories `npx skills` scans by default. The
283
- agent-skills CLI fetches it directly from GitHub and writes it to
284
- `~/.claude/skills/kobe/SKILL.md`.
285
-
286
- After install, Claude Code automatically picks up the skill on its next launch.
287
- For project-level overrides, copy the file to `<repo>/.claude/skills/kobe/SKILL.md`
288
- and customise — Claude Code's discovery order is project > user > none.
289
-
290
- Run `kobe doctor` to confirm — it reports whether the skill is installed and prints the install command if not. kobe also shows a one-time install hint on startup when the skill is missing.
291
-
292
- > The old built-in `kobe skill install` / `kobe diagnose` commands were
293
- > removed in v0.6 — use the `npx skills` command above to manage the skill.
294
-
295
- ## Coming later
296
-
297
- - Homebrew tap (mirroring [`sma1lboy/homebrew-codefox`](https://github.com/sma1lboy/homebrew-codefox)) so you can `brew install kobe` without touching Bun directly.
298
- - Conductor-as-backend mode (Phase 2 in [`docs/PLAN.md`](./docs/PLAN.md)).
299
-
300
- ---
301
-
302
- ## For contributors
303
-
304
- If you want to hack on kobe itself rather than just use it:
44
+ From the monorepo root:
305
45
 
306
46
  ```bash
307
47
  bun install
308
- bun run dev # boots the 5-pane TUI under KOBE_DEV=1 (no update chip, etc.)
309
- bun run test # normal suite: fast tests + serial socket tests
310
- bun run test:behavior # slow PTY suite; only run for user-visible TUI behavior
311
- bun run typecheck # strict tsc
312
- bun run build # produces ./dist/cli/index.js for npm
48
+ bun run dev:sandbox
49
+ bun run lint
50
+ bun run typecheck
51
+ bun run test
52
+ bun run build
53
+ bun run test:behavior
313
54
  ```
314
55
 
315
- Architecture, design philosophy, and the team-of-agents operating model live in:
316
-
317
- - [`docs/DESIGN.md`](../../docs/DESIGN.md) — design philosophy, tech stack lock-in.
318
- - [`docs/ARCHITECTURE.md`](../../docs/ARCHITECTURE.md) — module map and current state.
319
- - [`docs/HARNESS.md`](../../docs/HARNESS.md) — the agent self-test contract.
320
- - [`docs/PLAN.md`](../../docs/PLAN.md) — phase / wave plan.
321
- - [`HANDOFF.md`](../../HANDOFF.md) — latest session state and follow-ups.
322
-
323
- ### Releasing
324
-
325
- Bump `package.json`, move `## [Unreleased]` in `CHANGELOG.md` to the new
326
- version section, commit, then push the matching `vX.Y.Z` tag. The release
327
- workflow ([`.github/workflows/release.yml`](../../.github/workflows/release.yml))
328
- runs typecheck + unit tests + build, asserts the tag matches `package.json`,
329
- then `npm publish --provenance` and creates a GitHub release with the
330
- changelog section as the body.
56
+ See the root [README](../../README.md), [architecture](../../docs/ARCHITECTURE.md),
57
+ and [harness contract](../../docs/HARNESS.md).