command-code 1.1.0 → 1.1.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.
package/CHANGELOG.md CHANGED
@@ -1,11 +1,35 @@
1
1
  # command-code
2
2
 
3
+ ## 1.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - fix: capture the real cause when a self-update fails (#3047)
8
+ - 11e7eb1: fix: mods calling `cmd.ui.setStatus` / `cmd.ui.widget` / `cmd.ui.refreshWidgets` no longer crash
9
+
10
+ These methods are documented in the mod-builder UI reference but were never present on the `ModUi` runtime, so any mod written against the docs threw `cmd.ui.setStatus is not a function` (surfaced as a `mod_error`). They are now safe, inert no-ops (rendering into the TUI is still pending) and the docs say so.
11
+
12
+ - cd3452a: fix: capture the real cause when a self-update fails
13
+
14
+ `executeUpdate` swallowed the underlying `exec` error and returned a bare
15
+ `false`, so every update failure was tracked as a generic `Update failed:
16
+ <from> -> <to>` with no way to tell a permission denial from a network drop
17
+ from a timeout. The install error (exit code, signal, and stderr tail) is now
18
+ threaded through `performAutoUpdate` → `UpdateFailureReport` into the failure
19
+ telemetry (`cmd.update.failure_reason` / `update.failure_reason` and the error
20
+ message) for the CLI, TUI, and `cmd update` paths.
21
+
3
22
  ## 1.1.0
4
23
 
5
24
  ### Minor Changes
6
25
 
26
+ - feat: improve mods and cmd knowledge internal docs
27
+
28
+ ## 1.0.1
29
+
30
+ ### Patch Changes
31
+
7
32
  - fix: /reload header
8
- feat: improve mods and cmd knowledge internal docs
9
33
 
10
34
  ## 1.0.0
11
35
 
@@ -30,6 +30,74 @@ This page is the whole mods surface end to end: the quick start and loading rule
30
30
 
31
31
  ---
32
32
 
33
+ ## Just ask Command Code to build it
34
+
35
+ You rarely need to hand-write a mod. Command Code already knows this entire API - describe the behavior you want and it writes the mod, loads it with `--mod`, and iterates until it works. The fastest way in is to ask what's possible, then ask for the one you want:
36
+
37
+ ```text copy filename="Prompt"
38
+ What kinds of mods can I build for Command Code? Show me a few examples.
39
+ ```
40
+
41
+ ```text copy filename="Prompt"
42
+ Build me a mod that roasts me every time I greet you with "hi".
43
+ ```
44
+
45
+ ```text copy filename="Prompt"
46
+ Add a /standup slash command that summarizes what changed in git today.
47
+ ```
48
+
49
+ ```text copy filename="Prompt"
50
+ Block any shell command containing "rm -rf" unless I confirm it first.
51
+ ```
52
+
53
+ Under the hood it reads the [bundled examples](#runnable-examples) and writes against the same `ModApi` this page documents. When it's done, `cmd --mod ./your-mod.ts` tries it instantly - no build step.
54
+
55
+ ### A real one, built by asking
56
+
57
+ [`cmd-mod-hi`](https://github.com/ahmadawais/cmd-mod-hi) started as exactly that prompt - "roast me when I say hi" - and shipped to npm. Install it and greet your agent:
58
+
59
+ ```bash
60
+ cmd mods add npm:cmd-mod-hi -g
61
+ ```
62
+
63
+ Then type `hi`, `yo`, `howdy`, or `hello` and watch it judge you; `/hi-stats` tallies the damage. The whole mod is one `transformInput` hook plus a renderer:
64
+
65
+ ```ts
66
+ import type {ModApi} from '@commandcode/harness';
67
+
68
+ const roasts = [
69
+ '"hi" — bold. groundbreaking. truly pushing the boundaries of human communication.',
70
+ 'you typed "hi" and pressed enter. your ancestors are weeping.',
71
+ // …a dozen more
72
+ ];
73
+
74
+ let greetingCount = 0;
75
+
76
+ export default function (cmd: ModApi): void {
77
+ cmd.addRenderer('hi-roast', (data: {text: string}) => ['[cmd-mod-hi]: ' + data.text]);
78
+
79
+ cmd.addCommand({
80
+ name: 'hi-stats',
81
+ description: 'See how many times you\'ve been roasted for saying "hi"',
82
+ handler: () => ({message: `[cmd-mod-hi]: You've been roasted ${greetingCount} times.`}),
83
+ });
84
+
85
+ cmd.hooks({
86
+ transformInput({text}) {
87
+ if (/^(hi|hello|hey|yo|sup|howdy)[.!?\s]*$/.test(text.trim().toLowerCase())) {
88
+ greetingCount += 1;
89
+ cmd.showEntry('hi-roast', {text: roasts[greetingCount % roasts.length]});
90
+ }
91
+ return undefined; // let the greeting through - the roast is a side show
92
+ },
93
+ });
94
+ }
95
+ ```
96
+
97
+ Want to understand what it's doing, or write one by hand? The rest of this page is the full reference.
98
+
99
+ ---
100
+
33
101
  ## Quick start
34
102
 
35
103
  Create `~/.commandcode/mods/review-guard.ts`:
@@ -133,7 +201,6 @@ Runnable, single-file example mods ship with Command Code inside the bundled `mo
133
201
  | `custom-entry-renderer.ts` | `addRenderer` + `showEntry` - styled feed rows |
134
202
  | `flags-and-options.ts` | `addFlag` / `getFlag` + `--mod-option` |
135
203
  | `lifecycle-hooks.ts` | `hooks.onStop` (Stop) + `onSessionStart`/`onSessionEnd` + `afterToolCall` `isError` + `on('subagent_start'/'subagent_stop')` |
136
- | `status-and-widgets.ts` | `ui.setStatus` footer segment + `ui.widget` above the editor + a timed confirm |
137
204
  | `kitchen-sink.ts` | every capability in one annotated file |
138
205
 
139
206
  ---
@@ -21,11 +21,11 @@ const proceed = await cmd.ui.confirm({
21
21
  });
22
22
  ```
23
23
 
24
- ## Footer status segments
24
+ ## Footer status segments and editor widgets
25
25
 
26
- `cmd.ui.setStatus(text | null)` - a persistent per-mod segment in the TUI footer (under the input panel). One segment per mod: a new call replaces the text, `null` clears it, the returned `Disposable` clears it too. Segments from multiple mods concatenate in load order. Headless: renders nowhere (no-op).
26
+ > **Not wired into the TUI yet.** `cmd.ui.setStatus`, `cmd.ui.widget`, and `cmd.ui.refreshWidgets` exist on the surface and are safe to call - they never throw and return the documented `Disposable` - but they currently render **nowhere** (no-op everywhere, interactive and headless alike). The contract below is the intended design; wire-up is pending. Build against it, but don't rely on anything appearing on screen today.
27
27
 
28
- ## Editor widgets
28
+ `cmd.ui.setStatus(text | null)` - a persistent per-mod segment in the TUI footer (under the input panel). One segment per mod: a new call replaces the text, `null` clears it, the returned `Disposable` clears it too. Segments from multiple mods concatenate in load order. Headless: renders nowhere (no-op).
29
29
 
30
30
  `cmd.ui.widget({placement: 'above-editor' | 'below-editor', render: () => lines})` - a line-based widget the TUI renders around the input panel. Same verbatim-lines contract as `addRenderer` (style with ansi); `render` re-runs on every repaint, and `cmd.ui.refreshWidgets()` requests a repaint after your data changes. A throwing render is skipped (reported as a `mod_error`) so siblings keep rendering. Headless: no-op.
31
31
 
@@ -56,8 +56,6 @@ Rendering is deliberately **line-based, not component-based**: mods return style
56
56
  | `confirm` | modal | resolves `false` |
57
57
  | `select` / `input` | modal | resolves `undefined` |
58
58
  | timed dialog | countdown, auto-resolve at deadline | resolves `timeoutValue` immediately |
59
- | `setStatus` | footer segment | no-op |
60
- | `widget` | rendered around the editor | no-op |
59
+ | `setStatus` | no-op (wire-up pending) | no-op |
60
+ | `widget` | no-op (wire-up pending) | no-op |
61
61
  | `showEntry` | rendered feed row | dropped |
62
-
63
- The `status-and-widgets.ts` bundled example exercises all of this in one file - see [Runnable examples](./overview.md#runnable-examples).