@opencoven/coven-code 0.0.1 → 0.0.2

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 (46) hide show
  1. package/README.md +2 -1
  2. package/docs/CLI.md +65 -1
  3. package/docs/DEMO.md +450 -0
  4. package/docs/DEVELOPMENT.md +1 -1
  5. package/docs/README.md +1 -0
  6. package/package.json +7 -6
  7. package/src/agent/{local.mjs → fixture.mjs} +1 -1
  8. package/src/cli/execute.mjs +6 -4
  9. package/src/cli/interactive-core.mjs +5 -279
  10. package/src/cli/interactive-io.mjs +101 -0
  11. package/src/cli/interactive-slash.mjs +184 -0
  12. package/src/cli/repl.mjs +1 -2
  13. package/src/cli/tui-actions.mjs +72 -0
  14. package/src/cli/tui-blessed.mjs +198 -0
  15. package/src/cli/tui-keys.mjs +80 -0
  16. package/src/cli/tui-lane.mjs +73 -0
  17. package/src/cli/tui-render.mjs +169 -0
  18. package/src/cli/tui-submit.mjs +82 -0
  19. package/src/cli/tui.mjs +30 -613
  20. package/src/commands/permissions-eval.mjs +122 -0
  21. package/src/commands/permissions-rules.mjs +53 -0
  22. package/src/commands/permissions-text.mjs +112 -0
  23. package/src/commands/permissions.mjs +15 -281
  24. package/src/commands/usage.mjs +1 -1
  25. package/src/constants.mjs +7 -1
  26. package/src/mcp/local.mjs +55 -0
  27. package/src/mcp/parsers.mjs +46 -0
  28. package/src/mcp/probe.mjs +12 -351
  29. package/src/mcp/remote-oauth.mjs +55 -0
  30. package/src/mcp/remote-session.mjs +54 -0
  31. package/src/mcp/remote-sse.mjs +82 -0
  32. package/src/mcp/remote.mjs +74 -0
  33. package/src/plugins/api.mjs +187 -0
  34. package/src/plugins/configuration.mjs +124 -0
  35. package/src/plugins/discover.mjs +8 -804
  36. package/src/plugins/helpers.mjs +187 -0
  37. package/src/plugins/subsystems.mjs +198 -0
  38. package/src/plugins/validators.mjs +142 -0
  39. package/src/sdk-execute.mjs +82 -0
  40. package/src/sdk-settings.mjs +88 -0
  41. package/src/sdk.mjs +13 -164
  42. package/src/tools/builtin/oracle.mjs +2 -2
  43. package/src/tools/builtin/runtime-content.mjs +31 -0
  44. package/src/tools/builtin/runtime-decisions.mjs +115 -0
  45. package/src/tools/builtin/runtime.mjs +18 -148
  46. package/src/tools/builtin/task.mjs +2 -2
package/README.md CHANGED
@@ -24,6 +24,7 @@ The package exposes `coven-code` and `coven-code-sdk` bins.
24
24
  - [SDK](docs/SDK.md) - package exports, install helper, execution API, permissions, and thread helpers
25
25
  - [Development](docs/DEVELOPMENT.md) - repository layout, local checks, release notes, and safety expectations
26
26
  - [Coven Dogfood Protocol](docs/DOGFOOD-PROTOCOL.md) - daily task packets, harness assignment, handoff, verification, retrospectives, and issue capture
27
+ - [Demo](docs/DEMO.md) - 15-20 minute end-to-end walkthrough of every shipped surface (`npm run demo`)
27
28
 
28
29
  ## Interactive Mode
29
30
 
@@ -33,7 +34,7 @@ filtering and a details panel for commands, skills, and plugin actions.
33
34
 
34
35
  ```text
35
36
  $ coven-code
36
- Coven Code 0.0.0-recreate
37
+ Coven Code 0.0.2
37
38
  /Users/example/project
38
39
  [chat] lane tools threads config help mode: smart effort: high
39
40
  --------------------------------------------------------------------------------
package/docs/CLI.md CHANGED
@@ -22,6 +22,70 @@ The direct local entrypoint is:
22
22
  node ./bin/coven-code.mjs
23
23
  ```
24
24
 
25
+ ## Help
26
+
27
+ `coven-code --help` prints the full option and command reference. The excerpt
28
+ below is verified against actual `--help` output by the test suite; regenerate
29
+ it with `node ./bin/coven-code.mjs --help` between the markers if it drifts.
30
+
31
+ <!-- BEGIN: coven-code --help -->
32
+ ```text
33
+ Coven Code
34
+
35
+ Usage: coven-code [options] [command]
36
+
37
+ Run with no arguments in a terminal to enter the panel TUI. Set
38
+ COVEN_CODE_REPL=1 to use the classic readline REPL. Piped stdin becomes the
39
+ first interactive message when stdout is a TTY. Pass --execute or redirect
40
+ stdout to run a single turn and exit.
41
+
42
+ Options:
43
+ --execute, -x [prompt] Run one agent turn, print the final answer, and exit
44
+ --stream-json Emit structured JSONL in execute mode
45
+ --stream-json-thinking Include thinking blocks in stream JSON output
46
+ --stream-json-input Read one or more user messages as JSONL from stdin
47
+ --dangerously-allow-all Allow tool calls that would otherwise require approval
48
+ --mcp-config <json> Add an inline MCP server config for this run
49
+ --settings-file <path> Read user settings from a specific file
50
+ --mode <name> Agent mode: smart, deep, rush, or large
51
+ --reasoning-effort <level>
52
+ Set reasoning effort for the active mode
53
+ --label <name> Add a label to the created or continued thread
54
+ --visibility <level> Thread visibility: private, public, workspace, group, or unlisted
55
+ --archive Archive the thread after the execute turn
56
+ --continue [thread-id] Continue the latest active thread or the specified thread
57
+ --toolbox <path> Use a PATH-like toolbox root for this run
58
+ --skills <path> Use a PATH-like skill root for this run
59
+ --jetbrains Connect to a JetBrains IDE
60
+ -h, --help Show help
61
+ -v, --version Show version
62
+
63
+ Commands:
64
+ login Print local login instructions
65
+ update Check for updates
66
+ usage Show local usage estimates
67
+ review Run configured local review checks
68
+ tools list|make|show|use Manage built-in and toolbox tools
69
+ permissions list Show permission policy rules
70
+ config edit [--workspace] Open settings in $EDITOR
71
+ ide connect Connect or inspect local IDE integration
72
+ mcp add|list|doctor|approve|oauth
73
+ Manage MCP server settings
74
+ skill list|show Inspect discovered Coven Code agent skills
75
+ plugins list|reload Show and reload project and user plugin files
76
+ threads list|show|search|archive|visibility|continue|map|report
77
+ Manage local thread records
78
+ agents-md list Show AGENTS.md guidance files used for this cwd
79
+ agents list Alias for agents-md list
80
+
81
+ TUI lane commands:
82
+ /lane refresh Refresh worktree, branch, changed files, and diff summary
83
+ /lane harness <name|next> Select smart, deep, rush, or large for the lane
84
+ /lane verify Run the detected verification command for the lane
85
+ /lane status|diff Show lane status or diff summary
86
+ ```
87
+ <!-- END: coven-code --help -->
88
+
25
89
  ## Interactive Mode
26
90
 
27
91
  Run with no arguments in a TTY:
@@ -35,7 +99,7 @@ transcript, tabs, compact status line, command palette, slash-command menu, and
35
99
  composer. It keeps a current local thread and accepts slash commands:
36
100
 
37
101
  ```text
38
- Coven Code 0.0.0-recreate
102
+ Coven Code 0.0.2
39
103
  [chat] lane tools threads config help mode: smart effort: high
40
104
  --------------------------------------------------------------------------------
41
105
  Ready. Type a prompt or /help.
package/docs/DEMO.md ADDED
@@ -0,0 +1,450 @@
1
+ # Coven Code Demo
2
+
3
+ A 15-20 minute end-to-end walkthrough of every shipped surface in this
4
+ repository. Designed to be driven by a coding agent on the user's behalf,
5
+ or run live by a human presenter.
6
+
7
+ The companion script `scripts/demo.sh` is the executable source of truth.
8
+ Every shell block in this document also appears there in the same order
9
+ with the same expected outputs. The script is presentation-only and is
10
+ not wired into `npm test`.
11
+
12
+ ---
13
+
14
+ ## Agent Instructions (read this first if you are an LLM)
15
+
16
+ You are driving this demo for the user. Follow these rules:
17
+
18
+ 1. **Prefer the script over ad-hoc commands.** If the user says "run the
19
+ demo" with no qualifier, run `npm run demo` once end-to-end and
20
+ report results. Do not improvise commands that drift from what is
21
+ documented here. The script opens a menu by default but
22
+ auto-advances through every section when stdin is not a TTY, so
23
+ invoking it from an agent subprocess will not hang — it runs
24
+ straight through. To request only one section non-interactively,
25
+ the user can run `npm run demo` with input like `5\nq\n` piped in,
26
+ but the easier path is just `npm run demo -- --auto` for the full
27
+ walk.
28
+
29
+ 2. **Walk the sections in order if asked to narrate.** When the user
30
+ asks for a guided walkthrough, run each section's commands in the
31
+ listed order. Before each command, state in one sentence what it
32
+ demonstrates. After each command, confirm the expected output shape
33
+ matches (do not paste full output back unless asked).
34
+
35
+ 3. **Stop and ask before any of these.** The demo is offline and writes
36
+ only to a temporary `HOME`, so it is otherwise safe. But you must
37
+ confirm before:
38
+ - Running the demo against the user's real `HOME` instead of a
39
+ `mktemp` directory (do not do this unless explicitly asked).
40
+ - Installing the package globally (`coven-code-sdk install`) on
41
+ the user's machine.
42
+ - Modifying any committed file in this repo as part of the demo
43
+ (the demo should write only to `$DEMO_HOME` and `$DEMO_HOME`
44
+ subdirectories).
45
+
46
+ 4. **The interactive panel TUI is the only surface you cannot drive.**
47
+ It requires a real terminal and keyboard input. When you reach the
48
+ TUI Appendix below, hand off to the user with the documented key
49
+ sequences they should try. Do not attempt to spawn the TUI yourself
50
+ in execute mode or stream-json mode — it will not work and you
51
+ will hang the session.
52
+
53
+ 5. **All other state is disposable.** The demo writes to a fresh
54
+ `$DEMO_HOME = $(mktemp -d)`. To re-run cleanly, just re-invoke the
55
+ script — it creates a new temp dir each time. To clean up an old
56
+ run, the final section of the script prints the exact `rm -rf`
57
+ command to use.
58
+
59
+ 6. **What this demo proves.** That every advertised feature in the
60
+ `README.md` "Implemented Surface" section actually works against
61
+ the local deterministic fixture agent (`src/agent/fixture.mjs`),
62
+ without needing an API key, network access, or a hosted Coven Code
63
+ service.
64
+
65
+ 7. **What this demo does NOT prove.** It does not prove behavior
66
+ against a real hosted model, real remote MCP servers, real OAuth,
67
+ or the panel TUI's rendering. Those paths exist in the code but
68
+ are out of scope for an offline demo. If the user asks about them,
69
+ point them at `docs/MCP-SKILLS-PLUGINS.md`, the `mcp oauth login`
70
+ subcommand, and the TUI appendix below.
71
+
72
+ ---
73
+
74
+ ## How to Run the Demo
75
+
76
+ End-to-end (recommended):
77
+
78
+ ```sh
79
+ npm run demo
80
+ ```
81
+
82
+ This invokes `bash ./scripts/demo.sh`. The script opens with a
83
+ welcome banner listing the 12 sections and the sandboxed HOME it will
84
+ use, then drops into an interactive menu so the operator picks what
85
+ to see — no cognitive overload from a 12-section wall of output.
86
+
87
+ The menu accepts:
88
+
89
+ | Input | Action |
90
+ | -------- | -------------------------------------------------------- |
91
+ | `1`-`12` | run one section by number |
92
+ | `a` | run all sections in sequence, then print the scoreboard |
93
+ | `t` | type your own prompt and run one execute turn |
94
+ | `s` | list the files the demo wrote into the sandbox HOME |
95
+ | `l` | re-print the section table of contents (with `✓` marks) |
96
+ | `?` | show the menu help |
97
+ | `q` | quit (sandbox path printed so you can clean up or poke around) |
98
+
99
+ Each section starts with a short narration explaining what it proves,
100
+ runs its commands (the literal `coven-code …` shell line is printed in
101
+ magenta before each output), and closes with a green `✓ proved: …`
102
+ payoff and a `↳ see also:` pointer to the relevant doc. After every
103
+ section the menu re-displays the running counter (`3 / 12 sections
104
+ seen`) so the audience always knows where they are.
105
+
106
+ The menu reads input via `read -e` so backspace, arrow keys, and line
107
+ history work in any terminal that supports readline — including agent
108
+ shells. Direct invocation (`bash scripts/demo.sh`) works identically
109
+ if `npm` is unavailable.
110
+
111
+ To skip the menu and run every section straight through (for example
112
+ when capturing a transcript or showing the demo to yourself):
113
+
114
+ ```sh
115
+ npm run demo -- --auto # explicit flag
116
+ COVEN_DEMO_AUTO=1 npm run demo # env var
117
+ npm run demo > /tmp/demo.log 2>&1 # non-TTY stdout auto-advances too
118
+ ```
119
+
120
+ When stdin is not a TTY (CI, an agent subprocess, a piped run), the
121
+ script automatically runs in `--auto` mode so it never hangs.
122
+
123
+ Colors are emitted only when stdout is a TTY. Set `NO_COLOR=1` to
124
+ disable color in a terminal that supports it but where you would
125
+ rather have plain output (e.g., capturing for a markdown paste).
126
+
127
+ To inspect or modify the demo HOME after the run, set it explicitly:
128
+
129
+ ```sh
130
+ COVEN_DEMO_HOME=/tmp/my-coven-demo npm run demo
131
+ ```
132
+
133
+ To clean up:
134
+
135
+ ```sh
136
+ rm -rf "$DEMO_HOME" # the script prints the exact path at the end
137
+ ```
138
+
139
+ ---
140
+
141
+ ## Section 0 — Sanity
142
+
143
+ **What this shows.** The CLI is installed and the local login path
144
+ works without any account or API key.
145
+
146
+ ```sh
147
+ node ./bin/coven-code.mjs --version # prints 0.0.2
148
+ node ./bin/coven-code.mjs --help # full option and command reference
149
+ node ./bin/coven-code.mjs login # printable instructions (no token yet)
150
+ node ./bin/coven-code.mjs login status # auth_status: logged_out
151
+ ```
152
+
153
+ The repo intentionally has no live-model API integration. `login` and
154
+ `login status` operate against a local `~/.config/coven-code/auth.json`
155
+ file; the demo never sets a real token. If the user wants to also see
156
+ the credential-storage path, run `COVEN_CODE_API_KEY=demo-token coven-code login`
157
+ out of band — that is not part of the offline demo because it muddies
158
+ the "no credentials" story.
159
+
160
+ ## Section 1 — Execute Mode
161
+
162
+ **What this shows.** Single-turn answers, mode and reasoning-effort
163
+ selection, `@file` context references, and stdin combination.
164
+
165
+ ```sh
166
+ coven-code -x "what is 2+2?"
167
+ coven-code --mode deep --reasoning-effort high -x "summarize this request"
168
+ coven-code -x "summarize @sample.md"
169
+ printf 'extra context from stdin\n' | coven-code -x "answer using the piped context"
170
+ ```
171
+
172
+ The fixture agent echoes a deterministic envelope around the prompt so
173
+ you can see exactly how mode, reasoning, file refs, and stdin flow into
174
+ the agent's input message.
175
+
176
+ ## Section 2 — Threads
177
+
178
+ **What this shows.** Threads are local records. They persist across
179
+ execute turns, carry labels and visibility, support continue/search,
180
+ and can emit diagnostic reports and reference maps.
181
+
182
+ ```sh
183
+ coven-code --label demo --visibility workspace -x "kick off a labelled demo thread"
184
+ coven-code threads list
185
+ coven-code --continue T-<id> -x "follow up on the previous turn"
186
+ coven-code threads show T-<id>
187
+ coven-code threads visibility T-<id> private
188
+ coven-code threads map T-<id>
189
+ coven-code threads report T-<id>
190
+ coven-code threads search "demo"
191
+ coven-code threads archive T-<id>
192
+ ```
193
+
194
+ The script captures the first listed thread id into `$THREAD_ID` and
195
+ substitutes it into the subsequent commands.
196
+
197
+ ## Section 3 — Stream JSON
198
+
199
+ **What this shows.** Structured JSONL output suitable for SDKs and
200
+ frontends, including thinking blocks and multi-turn JSONL input.
201
+
202
+ ```sh
203
+ coven-code -x "what is 2+2?" --stream-json
204
+ coven-code -x "demonstrate reasoning" --stream-json --stream-json-thinking
205
+ coven-code -x 'kickoff' --stream-json --stream-json-input < messages.jsonl
206
+ ```
207
+
208
+ `messages.jsonl` contains two `user` messages; the agent processes them
209
+ in order after the kickoff prompt.
210
+
211
+ ## Section 4 — Permissions
212
+
213
+ **What this shows.** The default policy ships sensible allow/ask rules
214
+ for common shell commands, and operators can add and test their own.
215
+
216
+ ```sh
217
+ coven-code permissions list
218
+ coven-code permissions add allow Bash command.name git
219
+ coven-code permissions test Bash command.name git
220
+ coven-code permissions list
221
+ ```
222
+
223
+ Each rule is keyed by tool name plus a nested field path. `test`
224
+ prints the matched rule and source (user vs builtin) so you can see
225
+ exactly which rule wins.
226
+
227
+ ## Section 5 — Tools and Toolbox
228
+
229
+ **What this shows.** Built-in tools, scaffolding a new toolbox tool,
230
+ running it directly, and pointing the CLI at a workspace-local
231
+ toolbox root with `--toolbox`.
232
+
233
+ ```sh
234
+ coven-code tools list # built-ins
235
+ coven-code tools make --bash demo_tool # writes ~/.config/coven-code/tools/demo_tool
236
+ coven-code tools list # now includes tb__demo_tool
237
+ coven-code tools show tb__demo_tool
238
+ coven-code tools use tb__demo_tool --only output
239
+ coven-code --toolbox ./workspace-toolbox tools list # workspace-local toolbox
240
+ coven-code --toolbox ./workspace-toolbox tools show tb__local_tool
241
+ ```
242
+
243
+ The `--only output` flag is two args (`--only output`), not
244
+ `--only-output`. The script uses the correct form.
245
+
246
+ ## Section 6 — Skills
247
+
248
+ **What this shows.** Skill discovery from built-ins and a workspace
249
+ skill root via `--skills`.
250
+
251
+ ```sh
252
+ coven-code skill list
253
+ coven-code skill show building-skills
254
+ coven-code --skills ./workspace-skills skill list
255
+ coven-code --skills ./workspace-skills skill show release-checklist
256
+ ```
257
+
258
+ A skill is just a directory with a `SKILL.md` whose YAML frontmatter
259
+ declares `name` and `description`. The script writes a minimal
260
+ `release-checklist` skill so the workspace-root case has something to
261
+ show.
262
+
263
+ ## Section 7 — MCP
264
+
265
+ **What this shows.** Adding a stdio MCP server, approving it, and
266
+ running the health doctor — all without contacting a real remote
267
+ server.
268
+
269
+ ```sh
270
+ coven-code mcp list # (none)
271
+ coven-code mcp add demo-server -- node -e "process.stdout.write('hi')" # harmless stdio command
272
+ coven-code mcp list # demo-server listed, approved at user scope
273
+ coven-code mcp approve demo-server # workspace approval
274
+ coven-code mcp doctor # probes the server
275
+ ```
276
+
277
+ The `--` separator is required so the spec parser knows where the
278
+ server name ends and the command begins. `mcp doctor` actually spawns
279
+ the configured command and waits for the MCP handshake; the harmless
280
+ command we use exits immediately, which the doctor reports as
281
+ "ok 0 tools."
282
+
283
+ For live remote MCP servers, see `docs/MCP-SKILLS-PLUGINS.md` and the
284
+ `coven-code mcp oauth login --server-url ... --client-id ... --client-secret ...`
285
+ flow. That path is intentionally out of scope for this offline demo.
286
+
287
+ ## Section 8 — Plugins
288
+
289
+ **What this shows.** A project plugin in `.coven-code/plugins/*.ts`
290
+ registers a tool and a command. After reload, the new tool appears in
291
+ `tools list` and in the stream-json initialization message, proving it
292
+ is wired into the agent's runtime catalog.
293
+
294
+ ```sh
295
+ # Plugin file (.coven-code/plugins/demo.ts):
296
+ export default function (covenCode) {
297
+ covenCode.registerTool({
298
+ name: 'demo_status',
299
+ description: 'Returns a deterministic status string for the demo plugin',
300
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
301
+ async execute() {
302
+ return { content: [{ type: 'text', text: 'demo-plugin: ok' }] };
303
+ },
304
+ });
305
+ covenCode.registerCommand(
306
+ 'demo-hello',
307
+ { title: 'Demo Hello', description: 'Greets the operator from the demo plugin' },
308
+ async () => 'hello from the demo plugin',
309
+ );
310
+ }
311
+ ```
312
+
313
+ ```sh
314
+ coven-code plugins list
315
+ coven-code plugins reload
316
+ coven-code tools list # demo_status now appears as 'plugin'
317
+ coven-code -x "list available tools" --stream-json | head -1
318
+ ```
319
+
320
+ The `head -1` line is the most important one: the init message's
321
+ `tools` array contains `demo_status`, confirming the plugin tool is
322
+ visible to the agent loop, not just to `tools list`.
323
+
324
+ ## Section 9 — SDK
325
+
326
+ **What this shows.** Both the `coven-code-sdk` install helper and the
327
+ package's module exports (`execute`, `threads`, etc.).
328
+
329
+ ```sh
330
+ node ./bin/coven-code-sdk.mjs # prints usage for the install helper
331
+ ```
332
+
333
+ A tiny consumer (`sdk-demo.mjs`) imports from `src/sdk.mjs` and
334
+ streams an execute turn:
335
+
336
+ ```js
337
+ import { execute, threads } from '<repo>/src/sdk.mjs';
338
+
339
+ const threadId = await threads.new({ cwd: process.cwd() });
340
+ for await (const message of execute({ prompt: 'demonstrate the SDK path' })) {
341
+ if (message.type === 'assistant') {
342
+ console.log('assistant:', message.message?.content?.[0]?.text);
343
+ }
344
+ if (message.type === 'result') {
345
+ console.log('result:', message.result);
346
+ }
347
+ }
348
+ ```
349
+
350
+ ```sh
351
+ node sdk-demo.mjs
352
+ ```
353
+
354
+ This proves the SDK shells out to `coven-code --stream-json` under the
355
+ hood and reshapes the JSONL into the documented event stream.
356
+
357
+ ## Section 10 — Diagnostics
358
+
359
+ **What this shows.** Local-only diagnostic commands that are useful in
360
+ day-to-day operation but do not require model access.
361
+
362
+ ```sh
363
+ coven-code usage # thread/turn counts and token estimates
364
+ coven-code review # configured local review checks (none by default)
365
+ coven-code ide connect # IDE integration status
366
+ coven-code agents-md list # AGENTS.md guidance files discovered from cwd
367
+ coven-code update # update check (skipped because of COVEN_CODE_SKIP_UPDATE_CHECK=1)
368
+ ```
369
+
370
+ The script writes a minimal `AGENTS.md` into the demo workspace so the
371
+ `agents-md list` output is non-empty.
372
+
373
+ ## Section 11 — Cleanup
374
+
375
+ The script prints the absolute path of the temp `HOME` it used, along
376
+ with the exact `rm -rf` command to remove it. The demo never writes
377
+ outside `$DEMO_HOME`.
378
+
379
+ ---
380
+
381
+ ## Appendix A — Panel TUI (human only)
382
+
383
+ The interactive panel TUI is the project's headline UI but cannot be
384
+ scripted (it owns the terminal, processes raw keys, and has no
385
+ non-interactive contract beyond the deterministic test hook
386
+ `COVEN_CODE_TUI_SCRIPTED=1`, which is reserved for tests, not demos).
387
+
388
+ For a live audience, run this section by hand in a normal terminal:
389
+
390
+ ```sh
391
+ node ./bin/coven-code.mjs # no arguments, in a TTY -> panel TUI
392
+ ```
393
+
394
+ Things worth showing:
395
+
396
+ 1. **Tabs.** The status bar shows `chat | lane | tools | threads | config | help`.
397
+ Cycle through them.
398
+ 2. **Slash menu.** Type `/` in the composer to open the slash command
399
+ palette with live filtering. Tab completes the selection.
400
+ 3. **`/help`.** Lists built-in slash commands.
401
+ 4. **`/mode`.** Shows the active agent mode (`smart`, `deep`, `rush`,
402
+ `large`) and lets you change it.
403
+ 5. **`/reasoning`.** Inspects or changes reasoning effort.
404
+ 6. **`/lane refresh`, `/lane status`, `/lane diff`.** Loads the current
405
+ worktree, branch, changed files, and a diff summary into the lane
406
+ panel.
407
+ 7. **`/lane harness <smart|deep|rush|large|next>`.** Switches the active
408
+ lane harness.
409
+ 8. **`/lane verify`.** Runs the detected verification command for the
410
+ lane and keeps its output in the panel.
411
+ 9. **`/new` and `/continue`.** Start a fresh thread or resume one.
412
+ 10. **`/queue`.** Queues a follow-up prompt while the current turn is
413
+ still running.
414
+
415
+ To exit cleanly, the standard kill key for `neo-blessed` apps works
416
+ (`Ctrl-C`).
417
+
418
+ If a demo cannot use a real TTY (e.g., recorded over an SSH pipeline
419
+ without a pty), fall back to the classic readline REPL instead — it
420
+ composes with shell pipelines and is fully scriptable:
421
+
422
+ ```sh
423
+ COVEN_CODE_REPL=1 COVEN_CODE_REPL_HISTORY=0 coven-code
424
+ ```
425
+
426
+ ---
427
+
428
+ ## Appendix B — What to do if the demo fails
429
+
430
+ The script uses `set -euo pipefail`, so any non-zero exit immediately
431
+ stops the run and the failing command is visible in the last printed
432
+ `$ ...` banner.
433
+
434
+ Common failure modes:
435
+
436
+ - **`node: command not found`** — `package.json` requires Node 24+.
437
+ Check `node --version`.
438
+ - **`Unknown tool: tb__demo_tool`** — a previous failed run left state
439
+ in `$DEMO_HOME`. The script always creates a fresh temp HOME, so
440
+ just re-run.
441
+ - **`Unknown mcp command: ...`** — you're on an older CLI than this
442
+ doc was written against. Pull the repo to head and re-run.
443
+ - **`Plugin tool execute handler is required`** — the plugin file was
444
+ edited away from the documented shape. Restore it from this doc or
445
+ `scripts/demo.sh`.
446
+
447
+ If any other command fails, capture the full output and the path of
448
+ the temp HOME (printed in section 11) and share both. The temp HOME
449
+ contains all settings, threads, plugins, and skills that the demo
450
+ generated, which is enough to reproduce the failure offline.
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Requirements
4
4
 
5
- - Node.js 20 or newer
5
+ - Node.js 24 or newer (plugins are loaded as `.ts` modules, which Node added native unflagged support for in 23.6)
6
6
  - npm for this package's current lockfile and scripts
7
7
 
8
8
  The runtime intentionally has a small dependency surface. `neo-blessed` owns the
package/docs/README.md CHANGED
@@ -13,6 +13,7 @@ as a harness for OpenCoven integration work, local demos, and regression tests.
13
13
  - [SDK](SDK.md)
14
14
  - [Development](DEVELOPMENT.md)
15
15
  - [Coven Dogfood Protocol](DOGFOOD-PROTOCOL.md)
16
+ - [Demo](DEMO.md)
16
17
 
17
18
  ## Core Ideas
18
19
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencoven/coven-code",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -10,8 +10,8 @@
10
10
  ".": "./src/sdk.mjs"
11
11
  },
12
12
  "bin": {
13
- "coven-code": "./bin/coven-code.mjs",
14
- "coven-code-sdk": "./bin/coven-code-sdk.mjs"
13
+ "coven-code": "bin/coven-code.mjs",
14
+ "coven-code-sdk": "bin/coven-code-sdk.mjs"
15
15
  },
16
16
  "files": [
17
17
  "bin/",
@@ -23,12 +23,13 @@
23
23
  "access": "public"
24
24
  },
25
25
  "scripts": {
26
- "test": "node --test 'test/*.test.mjs'",
26
+ "test": "node --test test/cli.test.mjs test/commands.test.mjs test/config.test.mjs test/execute.test.mjs test/mcp.test.mjs test/permissions.test.mjs test/plugins-agent-events.test.mjs test/plugins-commands.test.mjs test/plugins-discovery.test.mjs test/plugins-tool-events.test.mjs test/sdk.test.mjs test/skills.test.mjs test/stream-json.test.mjs test/threads.test.mjs test/tools.test.mjs test/tui.test.mjs",
27
27
  "start": "node ./bin/coven-code.mjs",
28
- "coven-code": "node ./bin/coven-code.mjs"
28
+ "coven-code": "node ./bin/coven-code.mjs",
29
+ "demo": "bash ./scripts/demo.sh"
29
30
  },
30
31
  "engines": {
31
- "node": ">=20"
32
+ "node": ">=24"
32
33
  },
33
34
  "dependencies": {
34
35
  "neo-blessed": "0.2.0"
@@ -1,7 +1,7 @@
1
1
  import { existsSync, readdirSync } from 'node:fs';
2
2
  import path from 'node:path';
3
3
 
4
- export function localAgentResponse(prompt, stdin) {
4
+ export function fixtureAgentResponse(prompt, stdin) {
5
5
  const text = prompt.trim();
6
6
  const lower = text.toLowerCase();
7
7
 
@@ -2,7 +2,7 @@ import { randomUUID } from 'node:crypto';
2
2
  import { readFileSync } from 'node:fs';
3
3
  import path from 'node:path';
4
4
  import { BUILTIN_TOOLS } from '../constants.mjs';
5
- import { estimateUsage, localAgentResponse } from '../agent/local.mjs';
5
+ import { estimateUsage, fixtureAgentResponse } from '../agent/fixture.mjs';
6
6
  import {
7
7
  listActiveMcpServerEntries,
8
8
  } from '../mcp/discover.mjs';
@@ -154,7 +154,9 @@ export async function runExecute(parsed, stdin, options = {}) {
154
154
  return thread;
155
155
  }
156
156
 
157
- process.stdout.write(result.endsWith('\n') ? result : `${result}\n`);
157
+ if (!options.silent) {
158
+ process.stdout.write(result.endsWith('\n') ? result : `${result}\n`);
159
+ }
158
160
  const thread = await persistThreadMessages(sessionId, turnMessages(turns), parsed.mode, options.thread, parsed);
159
161
  notifyAgentComplete(parsed);
160
162
  return thread;
@@ -198,7 +200,7 @@ async function runExecuteTurn(prompt, stdin, sessionId, parsed, plugins, thread,
198
200
  ? threadContinuationPrompt(contextThread, turnPrompt)
199
201
  : expandThreadReferences(turnPrompt);
200
202
  const toolRun = await executePromptToolRequest(prompt, stdin, sessionId, parsed, plugins);
201
- const result = toolRun?.output ?? localAgentResponse(applySystemPrompt(modelPrompt, parsed), stdin);
203
+ const result = toolRun?.output ?? fixtureAgentResponse(applySystemPrompt(modelPrompt, parsed), stdin);
202
204
  const endDecision = await runPluginEventHandlers(plugins.handlers['agent.end'], {
203
205
  message: prompt,
204
206
  id: messageId,
@@ -349,7 +351,7 @@ async function runStreamJsonInputExecute(parsed, stdin, options = {}, started =
349
351
  const turnPrompt = guidancePrompt ? `${guidancePrompt}\n${expandedPrompt}` : expandedPrompt;
350
352
  const modelPrompt = modelPromptWithTranscript(turnPrompt, transcript, options.thread, parsed);
351
353
  const toolRun = await executePromptToolRequest(input.text, '', sessionId, parsed, plugins);
352
- result = toolRun?.output ?? localAgentResponse(modelPrompt, '');
354
+ result = toolRun?.output ?? fixtureAgentResponse(modelPrompt, '');
353
355
  numTurns += streamJsonTurnCount([{ toolRun }]);
354
356
  if (toolRun?.permissionDenials) permissionDenials.push(...toolRun.permissionDenials);
355
357
  if ((toolRun?.exitCode ?? 0) !== 0) isError = true;