@crouton-kit/crouter 0.3.78 → 0.3.79
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/dist/build-root.d.ts +12 -4
- package/dist/build-root.js +25 -6
- package/dist/builtin-memory/crouter-development/plugins.md +82 -5
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/provider-rotation.test.ts +1228 -12
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +3 -3
- package/dist/builtin-pi-packages/pi-crtr-extensions/lib/subscription-state.ts +2 -787
- package/dist/clients/attach/__tests__/attach-chrome-remote.test.js +8 -3
- package/dist/clients/attach/__tests__/attach-keybindings.test.d.ts +1 -0
- package/dist/clients/attach/__tests__/attach-keybindings.test.js +113 -0
- package/dist/clients/attach/__tests__/mermaid-render.test.js +9 -1
- package/dist/clients/attach/attach-cmd.d.ts +9 -1
- package/dist/clients/attach/attach-cmd.js +849 -803
- package/dist/clients/attach/auth-pickers.d.ts +0 -12
- package/dist/clients/attach/auth-pickers.js +64 -15
- package/dist/clients/attach/graph-overlay.d.ts +12 -2
- package/dist/clients/attach/graph-overlay.js +83 -33
- package/dist/commands/human/queue.js +3 -4
- package/dist/commands/pkg/plugin-inspect.js +22 -1
- package/dist/commands/pkg/plugin-manage.js +31 -9
- package/dist/commands/sys/__tests__/setup-core.test.js +158 -1
- package/dist/commands/sys/doctor.js +42 -4
- package/dist/commands/sys/setup-core.d.ts +37 -0
- package/dist/commands/sys/setup-core.js +138 -1
- package/dist/commands/sys/setup.d.ts +88 -0
- package/dist/commands/sys/setup.js +915 -171
- package/dist/commands/view-pick.d.ts +4 -0
- package/dist/commands/view-pick.js +17 -7
- package/dist/core/__tests__/canvas-inbox-watcher.test.js +34 -9
- package/dist/core/__tests__/command-plugins-surfaces.test.d.ts +1 -0
- package/dist/core/__tests__/command-plugins-surfaces.test.js +298 -0
- package/dist/core/__tests__/command-plugins.test.d.ts +1 -0
- package/dist/core/__tests__/command-plugins.test.js +444 -0
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +6 -0
- package/dist/core/__tests__/fixtures/fake-engine.js +9 -1
- package/dist/core/__tests__/preview-registry-sync.test.js +30 -1
- package/dist/core/__tests__/scope-crouter-home-fence.test.d.ts +1 -0
- package/dist/core/__tests__/scope-crouter-home-fence.test.js +55 -0
- package/dist/core/canvas/browse/app.d.ts +6 -0
- package/dist/core/canvas/browse/app.js +71 -41
- package/dist/core/command-plugins/adapter.d.ts +15 -0
- package/dist/core/command-plugins/adapter.js +145 -0
- package/dist/core/command-plugins/compose.d.ts +5 -0
- package/dist/core/command-plugins/compose.js +56 -0
- package/dist/core/command-plugins/discovery.d.ts +104 -0
- package/dist/core/command-plugins/discovery.js +565 -0
- package/dist/core/config.d.ts +2 -5
- package/dist/core/keybindings/__tests__/bespoke-consumers.test.d.ts +1 -0
- package/dist/core/keybindings/__tests__/bespoke-consumers.test.js +40 -0
- package/dist/core/keybindings/__tests__/resolve.test.js +2 -2
- package/dist/core/keybindings/catalog.d.ts +3 -3
- package/dist/core/keybindings/catalog.js +2 -1
- package/dist/core/profiles/select.d.ts +6 -0
- package/dist/core/profiles/select.js +86 -52
- package/dist/core/provider-management.d.ts +12 -0
- package/dist/core/provider-management.js +24 -0
- package/dist/core/runtime/broker.js +7 -6
- package/dist/core/runtime/pi-vendored.d.ts +8 -0
- package/dist/core/runtime/pi-vendored.js +14 -0
- package/dist/core/runtime/recap.d.ts +1 -1
- package/dist/core/runtime/recap.js +50 -25
- package/dist/core/runtime/session-list-cache.d.ts +10 -0
- package/dist/core/runtime/session-list-cache.js +94 -26
- package/dist/core/runtime/spawn.js +1 -13
- package/dist/core/runtime/tmux.js +2 -1
- package/dist/core/scope.js +27 -4
- package/dist/core/subscription-state.d.ts +90 -0
- package/dist/core/subscription-state.js +762 -0
- package/dist/daemon/crtrd.js +253 -12
- package/dist/pi-extensions/canvas-recap.js +43 -17
- package/dist/types.d.ts +6 -13
- package/dist/types.js +0 -3
- package/package.json +7 -3
package/dist/build-root.d.ts
CHANGED
|
@@ -9,8 +9,16 @@ export declare const SUBTREE_NAMES: string[];
|
|
|
9
9
|
* every valid child). This keeps every help/error surface byte-identical while
|
|
10
10
|
* the common leaf-dispatch path loads exactly one subtree. */
|
|
11
11
|
export declare function resolveRoot(first: string | undefined): Promise<RootDef>;
|
|
12
|
-
/** Assemble the full crtr command tree
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
/** Assemble the full crtr command tree: every core subtree plus any top-level
|
|
13
|
+
* branches contributed by enabled command plugins. Used for root -h, the
|
|
14
|
+
* unknown-path error, bare-root boot, front-door recognition, and the
|
|
15
|
+
* listing-completeness test — i.e. only the FALLTHROUGH path, never the core
|
|
16
|
+
* fast path (`resolveRoot` short-circuits a recognized core first token with
|
|
17
|
+
* zero plugin I/O). Root owns only the tagline; every subtree (core or
|
|
18
|
+
* external) declares its own root representation via its rootEntry.
|
|
19
|
+
*
|
|
20
|
+
* Order is deterministic: core subtrees in declared order first, then accepted
|
|
21
|
+
* external branches sorted by name (from discovery). Discovery is
|
|
22
|
+
* invocation-local — no cache, no persistence — so plugin enable/update/remove
|
|
23
|
+
* takes effect on the next invocation automatically. */
|
|
16
24
|
export declare function buildRoot(): Promise<RootDef>;
|
package/dist/build-root.js
CHANGED
|
@@ -36,11 +36,30 @@ export async function resolveRoot(first) {
|
|
|
36
36
|
}
|
|
37
37
|
return buildRoot();
|
|
38
38
|
}
|
|
39
|
-
/** Assemble the full crtr command tree
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
39
|
+
/** Assemble the full crtr command tree: every core subtree plus any top-level
|
|
40
|
+
* branches contributed by enabled command plugins. Used for root -h, the
|
|
41
|
+
* unknown-path error, bare-root boot, front-door recognition, and the
|
|
42
|
+
* listing-completeness test — i.e. only the FALLTHROUGH path, never the core
|
|
43
|
+
* fast path (`resolveRoot` short-circuits a recognized core first token with
|
|
44
|
+
* zero plugin I/O). Root owns only the tagline; every subtree (core or
|
|
45
|
+
* external) declares its own root representation via its rootEntry.
|
|
46
|
+
*
|
|
47
|
+
* Order is deterministic: core subtrees in declared order first, then accepted
|
|
48
|
+
* external branches sorted by name (from discovery). Discovery is
|
|
49
|
+
* invocation-local — no cache, no persistence — so plugin enable/update/remove
|
|
50
|
+
* takes effect on the next invocation automatically. */
|
|
43
51
|
export async function buildRoot() {
|
|
44
|
-
const
|
|
45
|
-
|
|
52
|
+
const core = await Promise.all(SUBTREE_NAMES.map((n) => SUBTREE_LOADERS[n]()));
|
|
53
|
+
// Dynamic import keeps command-plugin discovery/compose (and their
|
|
54
|
+
// resolver/manifest deps) OFF the hot leaf path's module graph — they load
|
|
55
|
+
// only here, on the fallthrough, matching this file's lazy-subtree rationale.
|
|
56
|
+
const [{ discoverCommandContributions }, { composeExternalSubtrees }] = await Promise.all([
|
|
57
|
+
import('./core/command-plugins/discovery.js'),
|
|
58
|
+
import('./core/command-plugins/compose.js'),
|
|
59
|
+
]);
|
|
60
|
+
// Core always wins: a plugin claiming a core top-level name is skipped +
|
|
61
|
+
// recorded as an issue (surfaced via pkg plugin show / sys doctor).
|
|
62
|
+
const snapshot = discoverCommandContributions(new Set(SUBTREE_NAMES));
|
|
63
|
+
const external = composeExternalSubtrees(snapshot);
|
|
64
|
+
return defineRoot({ tagline: TAGLINE, globals: [], subtrees: [...core, ...external] });
|
|
46
65
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
kind: knowledge
|
|
3
3
|
when-and-why-to-read: When creating a crtr plugin, packaging memory docs for
|
|
4
|
-
distribution,
|
|
4
|
+
distribution, adding top-level CLI commands via a command manifest, or
|
|
5
|
+
debugging install/resolution, this knowledge should be read.
|
|
5
6
|
short-form: How to author a crtr plugin — plugin.json manifest, directory
|
|
6
|
-
layout, scopes, install mechanics, versioning
|
|
7
|
-
|
|
7
|
+
layout, scopes, install mechanics, versioning, and command plugins (top-level
|
|
8
|
+
CLI commands via commands.json + one executable). Use when creating a plugin,
|
|
9
|
+
packaging memory docs, contributing commands, or debugging install/resolution.
|
|
8
10
|
system-prompt-visibility: name
|
|
9
11
|
file-read-visibility: none
|
|
10
12
|
---
|
|
@@ -39,7 +41,7 @@ If it's a one-off note for yourself, scope-owned memory docs are simpler. Promot
|
|
|
39
41
|
└── <name>.md
|
|
40
42
|
```
|
|
41
43
|
|
|
42
|
-
The `<plugin-name>` directory IS the plugin. The manifest's `name` field must match the directory name (install renames if needed). Sibling dirs (`rules/`, `agents/`, and future `
|
|
44
|
+
The `<plugin-name>` directory IS the plugin. The manifest's `name` field must match the directory name (install renames if needed). Sibling dirs (`rules/`, `agents/`, and future `hooks/`) hold the other artifact types. A plugin that contributes CLI commands adds a `commands.json` manifest plus its executable — see [Command plugins](#command-plugins).
|
|
43
45
|
|
|
44
46
|
## The manifest
|
|
45
47
|
|
|
@@ -65,6 +67,7 @@ The `<plugin-name>` directory IS the plugin. The manifest's `name` field must ma
|
|
|
65
67
|
| `description` | yes | One sentence. |
|
|
66
68
|
| `source` | recommended | Git URL where the plugin lives. Used by `crtr pkg plugin update --name <name>`. |
|
|
67
69
|
| `owner` | optional | Author info. |
|
|
70
|
+
| `commands` | optional | Plugin-root-relative path to a `commands.json` command manifest. Present ⇒ the plugin contributes top-level `crtr` commands — see [Command plugins](#command-plugins). |
|
|
68
71
|
|
|
69
72
|
## Scopes
|
|
70
73
|
|
|
@@ -150,13 +153,87 @@ Bad plugin scope:
|
|
|
150
153
|
|
|
151
154
|
If your memory doc conceptually depends on another plugin's doc, link via `## Related` with `` `<plugin>/<doc>` ``. Don't fork content; link it.
|
|
152
155
|
|
|
156
|
+
## Command plugins
|
|
157
|
+
|
|
158
|
+
Beyond docs, a plugin may contribute **top-level `crtr` commands** — new noun branches with their own leaves. You declare one pointer in the manifest and ship one executable; crtr owns parsing, help, rendering, and errors, and direct-spawns your executable once per leaf invocation.
|
|
159
|
+
|
|
160
|
+
### The manifest pointer
|
|
161
|
+
|
|
162
|
+
Add `commands` to `plugin.json` — a plugin-root-relative path to one static manifest:
|
|
163
|
+
|
|
164
|
+
```json
|
|
165
|
+
{ "name": "crouter-infra", "version": "0.1.0", "description": "...", "commands": "commands.json" }
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Only an installed, **enabled** plugin's `commands` manifest contributes. Discovery is per-invocation: enable/disable/update/remove takes effect on the very next `crtr` call — no daemon restart, no cache to clear.
|
|
169
|
+
|
|
170
|
+
### commands.json shape
|
|
171
|
+
|
|
172
|
+
```json
|
|
173
|
+
{
|
|
174
|
+
"schemaVersion": 1,
|
|
175
|
+
"executable": "bin/cmd.js",
|
|
176
|
+
"mounts": [
|
|
177
|
+
{ "parent": [], "node": { "kind": "branch", "name": "app", "...": "..." } }
|
|
178
|
+
]
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
- `schemaVersion` — exactly the integer `1`. Anything else rejects the whole manifest.
|
|
183
|
+
- `executable` — plugin-root-relative path to the one command binary. Must resolve inside the plugin root, be a regular file, and carry the POSIX exec bit.
|
|
184
|
+
- `mounts[]` — each `{ parent: [], node }`. v1 supports **top-level mounts only**: `parent` must be `[]`.
|
|
185
|
+
|
|
186
|
+
Every top-level `node` is a **branch** (`kind: "branch"`) carrying a `rootEntry { concept, description, whenToUse }` — the representation crtr renders at root help. Branch children are nested branches (no rootEntry) or leaves. A leaf declares `params`, `output` (array of `{ name, type, required, constraint }`), `outputKind: "object"`, and a non-empty `effects` array. Params use crtr's public vocabulary — one positional max, long-form `flag`s (types `string|int|bool|path|enum`, `choices` for enum), `stdin`, `context-file`; kebab-case names, no aliases. The declaration mirrors crtr's stable help descriptors, not its internal TypeScript defs — no closures, no dynamic state, no renderers.
|
|
187
|
+
|
|
188
|
+
### Execution: the trust boundary
|
|
189
|
+
|
|
190
|
+
On explicit leaf invocation — **never on install, help, or discovery** — crtr direct-spawns your executable (no shell) with `--crtr-command-protocol 1`, the caller's cwd, and the full environment. Installed command plugins are **trusted local code running with the caller's authority**: crtr does not sandbox them, filter the environment, mint a credential, or interpret your backend's auth. Your executable owns authentication to its own backend. This is an execution trust boundary, not a sandbox — installed code can already read the caller's files, so env filtering would only imply a security guarantee that does not exist.
|
|
191
|
+
|
|
192
|
+
### The protocol
|
|
193
|
+
|
|
194
|
+
crtr writes exactly one JSON request to your executable's stdin:
|
|
195
|
+
|
|
196
|
+
```json
|
|
197
|
+
{
|
|
198
|
+
"protocolVersion": 1,
|
|
199
|
+
"command": ["app", "show"],
|
|
200
|
+
"input": { "appId": "app_123" },
|
|
201
|
+
"context": { "cwd": "/caller/cwd", "plugin": { "name": "crouter-infra", "version": "0.1.0", "scope": "project", "root": "/plugin/root" } }
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
`input` keys are the parser's camelCase form; a declared `stdin` param arrives as an `input` string, not a second stream. Your executable writes exactly one JSON envelope to stdout and nothing else — diagnostics go to stderr:
|
|
206
|
+
|
|
207
|
+
```json
|
|
208
|
+
{ "protocolVersion": 1, "ok": true, "result": { "app_id": "app_123" } }
|
|
209
|
+
{ "protocolVersion": 1, "ok": false, "error": { "code": "authentication_required", "message": "...", "field": "session", "next": "..." } }
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
`ok` is the source of truth (a valid envelope is honored regardless of exit code). crtr validates `result` against your declared `output` (top-level field presence + type) and renders it; `--json` mirrors the same object. An error envelope becomes a normal crtr error with your `code` — lowercase snake_case, never crtr-reserved `internal`, `unknown_path`, `command_collision`, or `plugin_protocol_error`. No envelope at all (invalid JSON, empty, extra stdout, output over 10 MiB, signal kill) becomes `plugin_protocol_error`.
|
|
213
|
+
|
|
214
|
+
### Two rules that prevent silent breakage
|
|
215
|
+
|
|
216
|
+
- **Generate `commands.json` from your command definitions — never hand-write it.** The manifest must stay in lockstep with the executable's actual command surface; a hand-maintained copy drifts, and a drifted param or output field surfaces as a validation issue or a `plugin_protocol_error` at invocation. Emit it from the same source your executable dispatches on.
|
|
217
|
+
- **A required output field must be non-null.** The adapter treats an explicit `null` for a declared-required field as *absent* → `plugin_protocol_error`. If a value is genuinely optional, declare it `required: false`; if it's required, always return a real value.
|
|
218
|
+
|
|
219
|
+
### Validating your command manifest
|
|
220
|
+
|
|
221
|
+
crtr validates command manifests **statically — it never executes your binary** to check them:
|
|
222
|
+
|
|
223
|
+
- `crtr pkg plugin show <name>` — inventories the manifest path, executable, accepted top-level command names, and every current validation issue (each with received/expected/next).
|
|
224
|
+
- `crtr sys doctor` — validates the manifest + executable path for every effective command plugin and reports structured remediation (disable/update/remove). `--fix` never chmods or rewrites plugin content.
|
|
225
|
+
- `crtr pkg plugin install` / `update` — report the accepted top-level commands and any issues in their result.
|
|
226
|
+
|
|
227
|
+
A fixed manifest goes live on the next invocation; there is nothing to restart.
|
|
228
|
+
|
|
153
229
|
## Validation
|
|
154
230
|
|
|
155
231
|
`crtr sys doctor` checks each plugin's manifest:
|
|
156
232
|
- Manifest exists and is valid JSON.
|
|
157
233
|
- Manifest `name` matches the directory name.
|
|
234
|
+
- When the plugin declares `commands`, its command manifest + executable path are validated statically (never executed) — see [Command plugins](#command-plugins).
|
|
158
235
|
|
|
159
|
-
`crtr memory lint` checks the docs under `memory/`: frontmatter parses, valid `kind`, both visibility rungs set. Run `crtr memory write -h` for the authoring + routing guide.
|
|
236
|
+
`crtr memory lint` checks the docs under `memory/`: frontmatter parses, valid `kind`, both visibility rungs set. Run `crtr memory write -h` for the authoring + routing guide. Other sibling artifact dirs (`rules/`, `agents/`, `hooks/`) are validated by their respective specs as those land.
|
|
160
237
|
|
|
161
238
|
## Cross-publishing with Claude Code
|
|
162
239
|
|