@davidorex/pi-context-cli 0.30.0 → 0.31.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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,43 @@ All notable changes to this package are documented here. Format follows [Keep a
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.31.0] - 2026-06-13
8
+
9
+ ### Changed
10
+ - The CLI auto-supplied params (`writer`, `arrayKey` — filled after parse so a caller need not pass them) are now described by one internal source that drives all of: their exemption from the missing-required check, their bracketed-optional rendering in the per-op synopsis, and their `autoSupplied` annotation in the `--help` Flags block. Observable behavior is unchanged — these params remain optional to pass and auto-filled.
11
+
12
+ ### Added
13
+ - `pi-context context-install [--update]` reflects the new `context-install` op, listed under the top-level help's Substrate lifecycle group (after `context-accept-all`). It materializes the schemas + starter blocks declared in `config.json`'s `installed_schemas` / `installed_blocks` from the package samples catalog and records the install baseline (`config.installed_from`). Default skip-if-exists; `--update` re-syncs existing installed schemas (migration-aware) and replaces empty blocks with the catalog starter, while populated block data is preserved. `authGated` (confirm or `--yes`/`--force`). The install ceremony was previously reachable only as the `/context install` slash command.
14
+ - `pi-context read-catalog-schema --kind <canonical_id>` reflects the new read-only op, listed under the top-level help's Read & query group. It fetches and prints the verbatim bundled catalog `*.schema.json` body for a named block kind (the raw JSON Schema — `properties` / `definitions` / `$id`, not the `read-samples-catalog` projection), so the body is diffable locally against the installed `<substrate>/schemas/<name>.schema.json` without hunting through `node_modules`. Under `--json` the raw schema text rides the op-result envelope as a string; on the default text surface it prints the bytes as-is. Package-intrinsic (reads the extension's bundled catalog, independent of any substrate); an unknown kind is a non-zero exit.
15
+ - `pi-context context-check-status` reflects the new read-only drift-report op, listed under the top-level help's Read & query group. It reports each installed schema's installed-vs-catalog drift state and, for each schema behind the catalog (`catalog-ahead` / `both-diverged`), which schema is behind and by what version gap — the baseline → catalog version pair under `version_delta` (a declared version bump) or a content-only basis when the catalog body moved with the version string unchanged. Under `--json` the structured `CheckStatusReport` (`perAsset` + `summary`) rides in the op-result envelope; writes nothing.
16
+ - `pi-context update`'s text surface now reports, on a schema blocked by items failing the catalog schema, that git-style failure markers were written INTO the block file(s) — the blocked report header and trailing guidance tell the operator to open each block file, fix the items between the `<<<<<<< BLOCKED …` / `>>>>>>> target: …` markers, then run `pi-context resolve-blocked --schemaName <name> --yes`. `pi-context resolve-blocked` strips the markers before re-validating the corrected block against the pinned target.
17
+ - `pi-context resolve-blocked --schemaName <name>` — the CLI now reflects the new `resolve-blocked` op, the commit step that resolves a schema `update` blocked. After `update` blocks a catalog-ahead resync (and persists a pending-blocked record), the calling agent fixes the block's failing items (or widens the local schema) and runs `resolve-blocked` to re-validate the corrected block against the pinned target and, on pass, write the target schema + advance the merge base so a subsequent `update` converges (in-sync) instead of re-blocking; on fail it reports the remaining per-item failures and writes nothing. Listed under the top-level help's Schema & config group; `authGated` (confirm or `--yes`/`--force`). The blocked-resync report `update` prints on the text surface now ends with the matching guidance line (fix the named items → `resolve-blocked --schemaName <name> --yes`).
18
+ - `pi-context update` now surfaces the per-schema blocked-resync diagnostic on its default text surface: when a catalog-ahead resync is refused, the CLI renders a readable report below the op's own output — a `blocked: <name> (<from> -> <to>)` header per blocked schema, then either a `no migration chain reaches <to> from <from>` line or, for a validation failure, one line per failing item naming the item id (or its `instancePath` when no id resolved), the field, and the constraint. Under `--json` the structured `blockedDetail` already rides in the op-result envelope — the report is not double-emitted there. An `update` with no blocked schemas, or any other op, is unaffected.
19
+ - `pi-context validate-block-items --block <name>` reflects the new read-only diagnostic op: it validates a block's items against the catalog schema version (forward-migrating in memory when the block lags the catalog version) and returns `{ block, from?, to?, valid, failures[] }` — each failure naming the item id, field, and constraint — without writing. An unknown block or a missing installed block file is a non-zero exit. Listed under the top-level help's Read & query group.
20
+ - `pi-context context-lens-view --lensId <id>` projects a config-declared lens (`config.lenses[]`) as a binned item-view. Without `--bin` it returns a bin→count summary (the count of items in each declared bin plus `uncategorized` and `total`, always under the read cap); with `--bin <name>` it returns that bin's items paged by `--offset`/`--limit` (`{ items, total, hasMore }`). Serves target, composition, and hand-curated lenses. An unknown lens id or an undeclared bin is a non-zero exit.
21
+ - Per-op `pi-context <op> --help` now renders a structured page: a one-line summary, a `SYNOPSIS` line (`pi-context <op>` with required flags first and optional flags bracketed — auto-injected `writer`/`arrayKey` shown bracketed-optional), the per-field `Flags` block (type tag, enum choices, required/optional, description; JSON-valued flags shown as `<json | @file>`), an `EXAMPLES` section of copy-pasteable invocations for that op, a `RELATED` section listing the sibling commands in the same help group, and a footer pointing to `pi-context --help` and the machine-readable form. **`pi-context <op> --help --format json`** (or `--help --json`) emits that same help as a machine-readable JSON model (`{ name, synopsis, summary, flags[], examples[], related[] }`).
22
+ - The top-level `pi-context --help` (and bare `pi-context`) is now grouped and scannable: the surfaced ops are partitioned into seven command classes — Read & query, Block writes, Relations, Schema & config, Substrate lifecycle, Workflow, and a Process modes section (`pi-bound`) — rendered read-before-mutate, alphabetically within each class, each row showing the op's short reflection summary truncated to a uniform width. The classification is derived from the reflected op set, so a newly surfaced op appears under its class automatically. A new **`pi-context --version`** (alias `-v`) prints the package version and exits.
23
+ - An ergonomic-affordance layer adds three CLI-side conveniences, leaving every in-pi op byte-unchanged: (1) **`--show-schema`** previews a block-mutation op's contract — array key, required-field set, every field with its type (and enum values when declared), and the id pattern — and exits before any write (read through the installed schema; exits `3` when the block's schema is absent). (2) **`append-block-item --dry-run`** (alias `--dryRun`) validates the prospective whole file (`{...existing, <arrayKey>: [...items, newItem]}` against the block schema — exactly what a real append validates) and writes nothing, replicating the op's `--autoId` allocation and reporting the id that would be allocated (`[dry-run] PASS — would append <id>`); it never invokes the append op, so the op stays frozen. The flag is a global flag (matched on both kebab and camel forms) only for an op that declares no `dryRun` param; ops with their own `dryRun` param keep their existing semantics. (3) **Granular exit codes** distinguish error classes: `0` success, `1` runtime error / declined authorization, `2` usage error, `3` schema-absent, `4` id-allocation failure, `5` schema validation. A validation failure that previously exited `1` now exits `5`.
24
+ - An output + error-shaping layer adds three CLI-side affordances at the emit/catch boundary, leaving every in-pi op byte-unchanged: (1) **`--format text|json|table`** selects the render — `text` (default) reproduces each op's prior human output, `json` is the existing `{ ok, op, output }` envelope (`--json` is now its exact alias), and `table` projects a renderable row array (a read whose body is a collection, or a data op returning an array) as a compact markdown table (`id`-first, ≤4 columns, cells one-lined + 80-char-capped); a result that is not a complete tabular collection (prose, a non-array value, or an over-cap read) falls back to `text` so a degenerate table never replaces the real output; an unknown `--format` value is a usage error (exit 2). (2) **Field-named validation guidance** — a schema-validation failure now surfaces which field and what constraint (e.g. `` `/gaps/0`: missing required field `description` ``, `expected string`, `must be one of …`, `unexpected property …`) on both the text and `--json` surfaces, instead of the raw validator phrasing. (3) **Whole-subtree addressed reads** — `read-schema --schemaName <name> --path <dotted.path>` and `read-config --registry <name> [--id <id>]` return the complete node at that address (all children included), 50KB-capped, instead of a paged slice of one of the node's arrays. The whole-subtree behavior is now sourced from the in-pi op itself (the op passes `whole: true` on the addressed read); the earlier CLI-side recompute that produced the same envelope is retired.
25
+ - A pre-call input layer adds four additive flag affordances over the schema-derived surface (the in-pi op schemas + handlers are unchanged — the ops still receive + require their declared params; the CLI normalizes/supplies them, and every schema-exact form keeps working): (1) **kebab-case flags** resolve to their camelCase op-schema keys (`--dry-run` → `--dryRun`); (2) **`--id`** aliases an op's single id-shaped param (`itemId`/`parentId`/`taskId`/`unitId`/…), rejecting as ambiguous when an op declares two (e.g. `complete-task`, `rename-canonical-id`); (3) **`--arrayKey` is derived** from `config.block_kinds[].array_key` for the seven block-mutation ops, so a caller passes only `--block <name>` (an explicit `--arrayKey` overrides); (4) three shorthands — **`--writer kind:id`** (`human:you@example.com` → `{"kind":"human","user":"you@example.com"}`, `agent:`→`agent_id`, `monitor:`→`monitor_name`, `workflow:`→`workflow_step_id`), **`--where field:op:value`** for the filter predicate (split on the first two colons; the value may contain colons), and **CSV `--op in`** (a comma-separated `--value a,b,c` becomes `["a","b","c"]`, argv-order-independent).
26
+ - `pi-context resolve-conflict --schemaName <name> [--schema <reconciled>]` — the CLI now reflects the new `resolve-conflict` op, the commit step that completes the caller-as-reconciler conflict path. After `update` surfaces a conflict and the calling agent reconciles it, `resolve-conflict` writes the reconciled body AND advances the merge base for that schema to the catalog, so a subsequent `update` converges (the schema reads as `locally-modified` and its merge takes the reconciled body) instead of re-reporting the same conflict — which a bare `write-schema` (not advancing the base) would do. Omit `--schema` to treat the current on-disk body as already reconciled and only advance the base. `authGated` (confirm or `--yes`/`--force`).
27
+ - `pi-context update` surfaces the irreconcilable 3-way-merge conflicts it produces (`UpdateResult.conflicts`) to the **calling agent** rather than spawning a subordinate session. Under `--json` the structured conflict set (per schema, each `{ path, base, ours, theirs }`) rides in the op-result envelope; on the default text surface the CLI additionally renders a readable per-schema conflict report ending with a reconcile-guidance line (reconcile the conflicting paths into a schema → `resolve-conflict --schemaName <name> --schema <reconciled>`). Because the CLI is an agent-invoked surface, the caller — already an interactive, credentialed agent holding the conflict set and the operator's authority — reconciles and commits via `resolve-conflict`; the CLI spawns nothing. The `update` op's own output is unchanged and still printed first; an `update` with no conflicts, or any other op, is unaffected.
28
+ - `pi-context pi-bound [--grant <id>]... [...pi flags]` — a CLI process mode that launches an interactive `pi` coding-agent session whose tool surface is constrained to the canonical bounded set: the static tools derived from the installed packages' generated `SKILL.md` files, plus pi's built-in read-only tools (`read`/`ls`/`grep`/`find`), plus the active substrate's declared bounded composites (`config.tool_operations[]`). Repeated `--grant <canonical_id>` scopes the composite surface to a subset (default: all declared); every other token passes through to `pi`. Runs from the target dir; re-derives the full allowlist and runs `pi install -l` on every launch, including `--continue`/`-c` resumes. Replaces the `scripts/launch-constrained-pi.sh` entrypoint.
29
+ - `pi-context update [--dryRun]` — a reflected op that brings the installed substrate model toward the current catalog: it consults the per-schema drift classification, resyncs `in-sync`/`catalog-ahead` schemas, and **refuses to overwrite** a `locally-modified`/`both-diverged` schema, reporting it instead (a user's schema edits are never silently clobbered). `--dryRun` previews the per-schema action plan and writes nothing.
30
+
31
+ ### Removed
32
+ - The CLI-side addressed-read override (the post-`op.run` block that re-addressed the node off a fresh source load and re-wrapped it with `whole: true` for `read-schema --path` / `read-config --registry [--id]`) is retired. The in-pi op now returns the whole addressed subtree itself, so both surfaces — the op and the CLI — produce the whole-subtree envelope from the single op source; the CLI no longer recomputes it. The now-unused `addressInto` / `structureForRead` imports were dropped.
33
+ - `resolveConflicts` and the `resolve-conflicts` module (the subordinate-spawn conflict mergetool) are removed; `pi-context update` surfaces the conflict set to the calling agent instead.
34
+
35
+ ### Fixed
36
+ - The `read-catalog-schema` `verbatimText` text-surface test and the two trailing-newline comments (the test's doc-comment and the `cli.ts` emit-branch comment) are corrected to the verified fact that the bundled catalog `*.schema.json` files end with their own trailing newline (last bytes `}\n`). The prior text encoded a false premise — that the files end with `}` and carry no trailing newline. The verbatimText emit reproduces the file's own bytes byte-exact (its single trailing newline included) and does not append a second one; the defect it addresses was the CLI appending an extra newline (doubling `}\n` to `}\n\n`), which a `read-catalog-schema --kind <k> | diff <installed> -` surfaced as a phantom trailing-empty-line. The byte-exact behavior of `read-catalog-schema` is unchanged.
37
+ - Per-op `--help` now reconciles its `Flags` block with its `SYNOPSIS` for CLI-auto-supplied params (`writer`, `arrayKey`). The `Flags` block keeps the schema-truth `(required)` tag but appends the param's provenance — `--arrayKey <string> (required; auto-derived from --block)` and `--writer <json | @file> (required; auto-injected)` — so a reader no longer sees a bare `(required)` for a param the synopsis brackets as optional and the CLI fills automatically. The `--help --format json` model carries the same provenance on each such flag (`autoSupplied`). A genuinely-required param the caller must pass keeps a plain `(required)` with no provenance marker.
38
+ - `--dryRun`/`--dry-run` on an op that does not support a dry run now errors as an unknown flag (exit 2) instead of being silently swallowed and the real operation running. The global `--dry-run` capture is now scoped to `append-block-item` — the only op whose dry run the CLI performs client-side; for every other op that declares no `dryRun` param (`update-block-item`, `remove-block-item`, and the other no-`dryRun` mutation ops) the flag is rejected rather than dropped, so a caller's dry-run intent can no longer turn into a real write. Ops that declare their own `dryRun` param (`upsert-block-item`, `update`, the relation ops, …) are unaffected — the flag still reaches their own preview semantics.
39
+ - A schema-absent failure surfaced through id allocation now classifies to exit `3` (schema-absent) instead of `4` (id-allocation failure). When an `--autoId` append targets a block whose schema file is missing, the id allocator's "schema not found" throw was matching the id-allocation exit-code pattern first; the catch classifier now tests schema-not-found ahead of id-allocation, so the exit code names the true cause. Genuine id-allocation failures (no id pattern, or an unparseable pattern) still exit `4`.
40
+ - The `--id` alias no longer binds to a boolean flag whose name happens to end in `Id`. The alias identifies an op's id-param(s) by name (`id` or `…Id`); it now additionally requires the matched param to be string-typed, so `append-block-item`'s `autoId` (a boolean auto-allocation flag, not an identity selector) is excluded. Previously `autoId` was that op's sole `…Id` match, so `--id` silently resolved to it — `append-block-item --id SOME-123` swallowed the value into `autoId` and `--id true` silently enabled auto-allocation on a write. With the guard, `append-block-item` declares zero id-params, so `--id` correctly falls through to the unknown-flag error; `--autoId` as the boolean presence flag is unaffected.
41
+ - `pi-context update` no longer leaves an irreconcilable schema conflict unresolvable from the CLI. The prior route dispatched a subordinate `pi-bound` mergetool via `pi -p`, which runs headless (`hasUI=false`) so the spawned agent's `write-schema` was auth-gate-refused and its reconciliation was never applied — the spawned agent could only print a proposal. The conflict set is now returned to the calling agent — the interactive, credentialed actor that invoked the CLI — which reconciles it and commits via `resolve-conflict` (which writes the reconciled body AND advances the merge base to the catalog, so a subsequent `update` converges instead of re-reporting the conflict).
42
+ - `pi-bound` pre-launch setup-step failures now abort before the `pi` launch with an attributed `pi-context pi-bound: …` stderr line and a deterministic exit code, restoring the `set -e` parity of the `scripts/launch-constrained-pi.sh` entrypoint it ports: a non-resolvable package returns 1 (was a raw `Cannot find module` throw surfaced as a generic error); a non-zero `pi install -l` exit propagates the install's own code and aborts (was discarded, proceeding to a broken launch); a `pi install`/launch spawn failure (pi un-runnable) returns 1 (was a bare reject). The success path still returns the launch's exit code unchanged.
43
+
7
44
  ## [0.30.0] - 2026-06-04
8
45
 
9
46
  ### Added
package/README.md CHANGED
@@ -15,8 +15,10 @@ This provides a `pi-context` binary.
15
15
  ## Usage
16
16
 
17
17
  ```bash
18
- pi-context --help # list every surfaced op + global flags
19
- pi-context <op> --help # per-op help: declared flags with TYPE tags
18
+ pi-context --help # grouped op index (by command class) + global flags
19
+ pi-context --version # print the package version (alias -v)
20
+ pi-context <op> --help # per-op help: synopsis + flags + examples + related commands
21
+ pi-context <op> --help --format json # the same help as a machine-readable JSON model
20
22
  pi-context <op> [flags] # run an op
21
23
  ```
22
24
 
@@ -31,15 +33,128 @@ Example:
31
33
  pi-context read-block --block tasks
32
34
  pi-context append-block-item --block issues --arrayKey issues --item @new-issue.json --autoId
33
35
  pi-context read-block-page --block framework-gaps --offset 0 --limit 50
36
+ pi-context update --dryRun
37
+ ```
38
+
39
+ ## Input affordances
40
+
41
+ On top of the schema-derived flags, the CLI accepts a set of input conveniences. Each is additive — the schema-exact form (camelCase flags, explicit `--arrayKey`, a JSON `--writer`, separate `--field`/`--op`/`--value`) keeps working unchanged.
42
+
43
+ - **kebab-case flags** are accepted alongside the camelCase op-schema keys. `--dry-run` resolves to `--dryRun`; any conventional kebab form resolves when its camelCase key exists. An unrecognized flag (kebab or otherwise) is still rejected.
44
+ - **`--id` aliases the op's single id-param.** When an op declares exactly one id-shaped parameter (`itemId` / `parentId` / `taskId` / `unitId` / …), `--id <value>` resolves to it. An op that already declares a literal `id` parameter takes `--id` directly. An op with two id-params (e.g. `complete-task`, `rename-canonical-id`) rejects `--id` as ambiguous — name the explicit flag.
45
+ - **`--arrayKey` is derived from config** for the block-mutation ops (`append-block-item`, `update-block-item`, `upsert-block-item`, `remove-block-item`, and the nested variants). Pass only `--block <name>`; the array key is read from that block's `config.block_kinds[].array_key`. An explicit `--arrayKey` overrides the derivation.
46
+ - **`--writer kind:id` shorthand.** `--writer human:you@example.com` expands to `{"kind":"human","user":"you@example.com"}`; `--writer agent:claude` to `{"kind":"agent","agent_id":"claude"}` (`monitor:`→`monitor_name`, `workflow:`→`workflow_step_id`). The first colon delimits the kind; the identifier may itself contain colons.
47
+ - **`--where field:op:value` shorthand** for the filter predicate: `--where status:eq:done` sets `--field status --op eq --value done`. Split on the first two colons only, so the value may contain colons.
48
+ - **CSV `--op in`.** When the comparison operator is `in`, a comma-separated `--value a,b,c` is split into the array `["a","b","c"]`. Order-independent — `--op in --value a,b,c` and `--value a,b,c --op in` are equivalent.
49
+
50
+ ```bash
51
+ pi-context append-block-item --block framework-gaps --item @gap.json # arrayKey derived from config
52
+ pi-context find-references --id TASK-1 # --id → itemId
53
+ pi-context append-block-item --block tasks --item @t.json --writer human:you@example.com
54
+ pi-context filter-block-items --block tasks --where status:eq:done # field/op/value from one token
55
+ pi-context filter-block-items --block tasks --field tag --op in --value a,b,c
56
+ ```
57
+
58
+ ## Contract preview + dry-run
59
+
60
+ For the block-mutation ops the CLI offers two pre-write affordances:
61
+
62
+ - **`--show-schema`** previews a block op's contract and exits before any write — the array key, the required-field set, every field with its type (and enum values when declared), and the id pattern. Pass it with the op and `--block <name>`; no `--item` is needed.
63
+ - **`append-block-item --dry-run`** (or `--dryRun`) validates the prospective whole file — `{...existing, <arrayKey>: [...items, newItem]}` against the block schema, exactly what a real append validates — and writes nothing. With `--autoId` it reports the id that would be allocated. The output is `[dry-run] PASS` (or `[dry-run] PASS — would append <id>`); a schema-invalid item surfaces the field-named validation error.
64
+
65
+ ```bash
66
+ pi-context append-block-item --block framework-gaps --show-schema # contract preview, no write
67
+ pi-context append-block-item --block tasks --item @t.json --dry-run # validate the prospective file, no write
68
+ pi-context append-block-item --block tasks --item @t.json --dry-run --autoId # also reports the allocated id
69
+ ```
70
+
71
+ ## Output rendering
72
+
73
+ `--format text|json|table` selects how an op's result is rendered. `--json` is the exact alias of `--format json`.
74
+
75
+ - **`text`** (default) — each op's human render: prose, a JSON.stringify'd value, or a read body with its paging footer.
76
+ - **`json`** — the `{ ok, op, output }` envelope (`{ ok: false, op, error }` on failure). `output` is the un-stringified value (single-parse), read-capped at 50KB.
77
+ - **`table`** — a compact markdown table of a renderable row array (a read whose body is a collection, or a data op that returns an array). The projection is best-effort terse: `id` first when present, then up to three more fields (≤4 columns), cells one-lined and capped at 80 chars. A result that is not a complete tabular collection (prose, a non-array value, or an over-cap read) renders as `text` instead — a degenerate table is never substituted for the real output.
78
+
79
+ ```bash
80
+ pi-context read-block --block tasks --format table # markdown table of the tasks
81
+ pi-context filter-block-items --block tasks --where status:eq:open --format table
82
+ pi-context read-block --block tasks --json # ≡ --format json
83
+ ```
84
+
85
+ Schema-validation failures surface **field-named guidance** — which field and what constraint (e.g. `` `/gaps/0`: missing required field `description` ``) — rather than the raw validator phrasing, on both the text and `--json` surfaces.
86
+
87
+ Addressed reads return the **whole addressed subtree** (50KB-capped): `read-schema --schemaName <name> --path <dotted.path>` and `read-config --registry <name> [--id <id>]` return the complete node at that address — including all of its children — not a paged slice of one of its arrays.
88
+
89
+ ## `pi-context pi-bound` — constrained pi session
90
+
91
+ ```bash
92
+ pi-context pi-bound [--grant <id>]... [...pi-args]
93
+ ```
94
+
95
+ `pi-bound` is a CLI **process mode** (not a substrate op): it launches a `pi` coding-agent session restricted to the composed pi-extension tool surface. On every launch it:
96
+
97
+ 1. runs `pi install -l <@davidorex/pi-project-workflows root>` to register the extensions into the target dir's `.pi/`
98
+ 2. derives the static tool allowlist from the installed packages' generated `skills/*/SKILL.md` (`@davidorex/pi-context` + `@davidorex/pi-project-workflows`)
99
+ 3. always adds the built-in read-only tools `read`, `ls`, `grep`, `find`
100
+ 4. appends the bounded composites declared in the active substrate's `config.tool_operations[]`
101
+ 5. launches `pi --tools <union> ...pi-args`
102
+
103
+ It runs from the process cwd and reads that dir's `.pi-context.json` for composites (warns, non-fatally, if absent).
104
+
105
+ **Flags:**
106
+
107
+ - `--grant <id>` (repeatable) — scope the bounded composites to only the named ids. Default: all declared composites.
108
+ - any other token — passed through verbatim to `pi` (e.g. `--continue` / `-c` to resume a session).
109
+
110
+ ```bash
111
+ pi-context pi-bound # launch with the full composed tool surface
112
+ pi-context pi-bound --grant grep-paths # restrict composites to a single named op
113
+ pi-context pi-bound -c # pass -c through to pi to resume
114
+ ```
115
+
116
+ This process mode replaces the former `scripts/launch-constrained-pi.sh` launch script.
117
+
118
+ ## `pi-context update` — drift-aware model update + conflict surfacing
119
+
120
+ ```bash
121
+ pi-context update [--dryRun]
122
+ ```
123
+
124
+ `update` brings the installed schema model current with the packaged catalog. Per installed schema it consults the drift classification and routes by state: an `in-sync` schema is a no-op; a `catalog-ahead` schema re-syncs through the migration-aware path; a `locally-modified` / `both-diverged` schema is reconciled by a deterministic 3-way merge of base (the as-installed schema body in the object store, keyed by the recorded baseline `content_hash`) × ours (the installed schema) × theirs (the catalog schema). Disjoint edits auto-merge so both the user's and the catalog's changes survive (`required` / `enum` / array-valued `type` nodes merge as sets).
125
+
126
+ A schema whose per-path edits cannot be reconciled is left unmodified, and the conflict is SURFACED to the calling agent — `update` does not spawn a subordinate resolver. The conflict set is returned in the op output (the `conflicts` array, printed under `--json`) alongside a readable per-schema report on the default text surface. The report ends with a guidance line; the calling agent reconciles each conflicting schema and commits the reconciliation with `pi-context resolve-conflict`:
127
+
128
+ ```bash
129
+ pi-context read-schema --schemaName <name> # inspect the current installed body
130
+ # resolve the conflicting paths into a reconciled draft-07 schema, then commit it:
131
+ pi-context resolve-conflict --schemaName <name> --schema '<reconciled-json>'
132
+ ```
133
+
134
+ `resolve-conflict` writes the reconciled body AND advances the merge base for that schema to the catalog, so the next `update` sees the schema as `locally-modified` and its deterministic merge takes the reconciled body (base === theirs → ours) — converging with zero conflicts and preserving the resolution. A bare `write-schema` does not advance the base, so `update` would re-report the same conflict on every run. Omit `--schema` to treat the current on-disk body as already reconciled and only advance the base.
135
+
136
+ `update` also additively propagates catalog-new config-registry entries (`relation_types` / `invariants` / `block_kinds` / `lenses`) absent from the substrate config, preserving every user-authored entry and any locally-diverged body of an existing entry (additive-only — present entries are never overwritten; the added ids are reported under `registryAdditions`).
137
+
138
+ A `catalog-ahead` schema whose resync is refused (`blocked`) carries its diagnostic under `blockedDetail` (one entry per blocked schema): the refusal reason — `no-migration-chain` (no shipped chain reaches the catalog version) vs `validation-failed` (the forward-migrated items fail the catalog schema) — the installed→catalog version pair, and for a validation failure the per-item failures naming the failing item id, field, and constraint. Under `--json` the `blockedDetail` array rides in the op-result envelope; on the default text surface the CLI renders a readable per-schema report below the op output (`blocked: <name> (<from> -> <to>)` then the no-chain line or the per-item failure lines), ending with a guidance line. A live blocked `update` also persists a pending-blocked record pinning the target catalog schema, and — for a `validation-failed` block — writes git-style failure markers INTO the block file at the offending items (full-line `<<<<<<< BLOCKED …` / `>>>>>>> target: …` sentinels), pinning the pre-marker bytes (the schema and `migrations.json` stay byte-unchanged). The resolution loop is: open the block file, fix the items between the markers (or widen the local schema) → `pi-context resolve-blocked --schemaName <name>`, which strips the markers, re-validates the corrected block against the pinned target and, on pass, writes the target schema + advances the merge base so a subsequent `update` converges (in-sync) instead of re-blocking. The standalone `pi-context validate-block-items --block <name>` runs the same per-item check on demand (read-only, returns `{ block, from?, to?, valid, failures[] }`).
139
+
140
+ `--dryRun` predicts the precise per-schema outcome (resync / migrate / block / merge / conflict) by running the forward-migration and re-validation in memory, alongside the per-blocked-schema diagnostic detail and the config-registry entries that would be added, and writes nothing.
141
+
142
+ ```bash
143
+ pi-context update --dryRun # predict the precise per-schema outcome (in-memory migrate + re-validate) + config-registry additions
144
+ pi-context update # apply: resync + auto-merge; conflicts → surfaced (op output + report) for the caller to reconcile + commit via resolve-conflict
34
145
  ```
35
146
 
36
147
  ## Global flags
37
148
 
38
149
  - `--cwd <dir>` — substrate root (default: current working directory; relative paths resolve against it)
39
- - `--json` — emit a `{ ok, op, output }` envelope on success (`{ ok: false, op, error }` on failure) instead of raw output
150
+ - `--json` — emit a `{ ok, op, output }` envelope on success (`{ ok: false, op, error }` on failure) instead of raw output (≡ `--format json`)
151
+ - `--format <text|json|table>` — select the output render (default `text`, or `json` with `--json`); see [Output rendering](#output-rendering)
40
152
  - `--yes`, `--force` — pre-authorize an auth-gated op in a non-interactive context
41
153
  - `--writer <json>` — override the auto-resolved writer identity
42
- - `--help`, `-h` — top-level help, or per-op help after an op name
154
+ - `--show-schema` — preview a block op's contract (array key / required fields / field types / id pattern) and exit; see [Contract preview + dry-run](#contract-preview--dry-run)
155
+ - `--dry-run`, `--dryRun` — for `append-block-item`, validate the prospective file and write nothing; see [Contract preview + dry-run](#contract-preview--dry-run)
156
+ - `--version`, `-v` — print the package version and exit
157
+ - `--help`, `-h` — grouped top-level help (ops by command class + a Process modes section), or per-op help after an op name
43
158
 
44
159
  ## Writer identity
45
160
 
@@ -59,6 +174,11 @@ Ops marked `authGated` (writes that mutate config / schemas / migrations) requir
59
174
 
60
175
  ## Exit codes
61
176
 
62
- - `0` success
63
- - `1` op/runtime error, or declined authorization
64
- - `2` usage error (unknown op, unknown flag, missing required field)
177
+ | Code | Meaning |
178
+ | --- | --- |
179
+ | `0` | success |
180
+ | `1` | op/runtime error, or declined authorization |
181
+ | `2` | usage error (unknown op, unknown flag, missing required field) |
182
+ | `3` | schema absent (the block's schema is not installed) |
183
+ | `4` | id-allocation failure (`--autoId` could not allocate the next id) |
184
+ | `5` | schema validation failure |
package/dist/bin.js CHANGED
File without changes
package/dist/cli.d.ts CHANGED
@@ -6,6 +6,16 @@ import { type OpDefinition } from "@davidorex/pi-context/ops";
6
6
  * is excluded here by the partition, never by name.
7
7
  */
8
8
  export declare const useOps: OpDefinition[];
9
+ /**
10
+ * The pi-context-cli package version, read ONCE at module load from the shipped
11
+ * package.json. Resolved RELATIVE to this module's URL (mirrors pi-bound.ts's
12
+ * createRequire(import.meta.url) pattern) so it works from the BUILT bin: from
13
+ * `dist/cli.js`, `../package.json` is the package root (npm always ships
14
+ * package.json in a published tarball). A plain `import pkg from "../package.json"`
15
+ * is deliberately avoided — tsconfig.build's rootDir:"./src" / include:["src/**"]
16
+ * would make that compile path a hazard. `--version`/`-v` prints this value.
17
+ */
18
+ export declare const PKG_VERSION: string;
9
19
  /** Field-type tag rendered in help and used to pick a coercion strategy. */
10
20
  export type FieldType = "string" | "number" | "boolean" | "json";
11
21
  interface FieldSchema {
@@ -59,6 +69,17 @@ export interface ParsedArgs {
59
69
  json: boolean;
60
70
  yes: boolean;
61
71
  help: boolean;
72
+ /** --show-schema (FGAP-022): print the block contract and exit before any write. */
73
+ showSchema?: boolean;
74
+ /**
75
+ * --dryRun / --dry-run (FGAP-024): for append-block-item, validate the prospective
76
+ * whole file and write nothing. Parsed as a global flag — never injected into
77
+ * `params` — because the frozen append op declares no `dryRun` param and would
78
+ * reject it as an unknown flag.
79
+ */
80
+ dryRun?: boolean;
81
+ /** Selected output render (FGAP-021). Unset → resolved from `json` at emit time. */
82
+ format?: "text" | "json" | "table";
62
83
  explicitWriter?: unknown;
63
84
  params: Record<string, unknown>;
64
85
  }
@@ -77,6 +98,18 @@ export declare function parseOpArgs(op: OpDefinition, argv: string[], cwdBase?:
77
98
  * identity (falling back to "operator"). Mutates and returns `params`.
78
99
  */
79
100
  export declare function injectWriter(op: OpDefinition, params: Record<string, unknown>, identity: string | null): Record<string, unknown>;
101
+ /**
102
+ * Schema- + config-driven arrayKey injection (FGAP-019), mirroring injectWriter.
103
+ * The 7 block-mutation ops still DECLARE `arrayKey` required (their in-pi schema +
104
+ * handler are byte-unchanged and still receive + require it) — the CLI supplies it
105
+ * pre-call so a caller passes only `--block`. When the op declares `arrayKey`, none
106
+ * was passed, and a string `block` is present, derive the array_key from the
107
+ * config block_kinds entry whose canonical_id matches `block` (canonical_id ≠
108
+ * array_key in real data, e.g. framework-gaps → gaps, so the derivation is genuinely
109
+ * needed). Best-effort: no substrate, no config, or an unknown block leaves arrayKey
110
+ * unset — the op then throws its own missing-param error. Mutates and returns params.
111
+ */
112
+ export declare function injectArrayKey(op: OpDefinition, params: Record<string, unknown>, cwd: string): Record<string, unknown>;
80
113
  /**
81
114
  * Build the DispatchContext threaded into `op.run` as its 3rd arg so every CLI
82
115
  * write op stamps attestation (created_by / created_at) on schemas that declare
@@ -112,9 +145,92 @@ export declare function authDecision(op: OpDefinition, opts: {
112
145
  yes: boolean;
113
146
  interactive: boolean;
114
147
  }): AuthDecision;
115
- /** Per-op help text: description + one line per declared field. */
148
+ /**
149
+ * One flag descriptor in the machine-readable help model (CHANGE 3 / TASK-042).
150
+ * `type` is the enum-join (`eq|neq|in|matches`) for string-enum fields, else the
151
+ * coarse FieldType tag. `required` reflects the op's declared schema `required` set
152
+ * verbatim (writer/arrayKey ARE marked required here — schema-truth). `autoSupplied`
153
+ * carries the AUTO_SUPPLIED provenance phrase when the CLI fills the param after
154
+ * parse (writer / arrayKey), else omitted — the Flags block + json help render it as
155
+ * `(required; <autoSupplied>)` so a schema-required-but-CLI-supplied param is not
156
+ * mistaken for one the caller must pass.
157
+ */
158
+ export interface HelpFlag {
159
+ name: string;
160
+ type: string;
161
+ required: boolean;
162
+ description?: string;
163
+ autoSupplied?: string;
164
+ }
165
+ /**
166
+ * Structured per-op help model — the single source both the text template
167
+ * (deriveHelp) and the `--help --format json` machine help render from.
168
+ *
169
+ * `synopsis` treats `writer` and `arrayKey` as OPTIONAL even when the schema lists
170
+ * them required, because both are auto-injected after parse (writer from the
171
+ * resolved operator identity; arrayKey from config.block_kinds[].array_key) — the
172
+ * same exemption parseOpArgs applies to its required-field check. So a flag is
173
+ * synopsis-required iff it is schema-required AND not writer/arrayKey.
174
+ *
175
+ * `related` is the sibling use-ops sharing this op's top-level help group
176
+ * (groupForOp — the single grouping source the top-level help uses), name-sorted,
177
+ * self excluded. pi-bound modes are not useOps, so they never appear.
178
+ */
179
+ export interface HelpModel {
180
+ name: string;
181
+ synopsis: string;
182
+ summary: string;
183
+ flags: HelpFlag[];
184
+ examples: string[];
185
+ related: string[];
186
+ }
187
+ /**
188
+ * Single source for the CLI's auto-supplied params: a field declared `required`
189
+ * by the op schema that the CLI fills after parse, so the caller never passes it.
190
+ * Maps the param name to its provenance phrase. This map is the ONE source for
191
+ * both the synopsis exemption (bracketed-optional, `isSynopsisRequired`) and the
192
+ * per-flag `autoSupplied` annotation surfaced in the Flags block + json help —
193
+ * reconciling the Flags `(required)` schema-truth with the optional synopsis so
194
+ * neither surface contradicts the other (TASK-042 iterate-to-zero finding):
195
+ * - writer: injectWriter fills it from the resolved operator identity
196
+ * - arrayKey: injectArrayKey derives it from config.block_kinds[].array_key
197
+ */
198
+ export declare const AUTO_SUPPLIED: Record<string, string>;
199
+ /**
200
+ * Build the structured per-op help model from the op's typebox parameters +
201
+ * the registry `examples` + the help-group siblings. Pure — no I/O.
202
+ */
203
+ export declare function buildHelpModel(op: OpDefinition): HelpModel;
204
+ /**
205
+ * Best-of-breed per-op help text (TASK-042): `<name> — <description>` → SYNOPSIS →
206
+ * Flags (per-field, enum joins + required/optional + desc; json fields show
207
+ * `<json | @file>`) → EXAMPLES → RELATED (omitted when empty) → footer →
208
+ * the Global flags trailer. Plain text.
209
+ */
116
210
  export declare function deriveHelp(op: OpDefinition): string;
117
- /** Top-level help: one line per surfaced op + global flag notes. */
211
+ /**
212
+ * Classify a use-op into its top-level help group LABEL (first-match-wins over the
213
+ * ordered HELP_GROUPS). Throws when a use-op matches no group — a new op that slips
214
+ * past every rule fails loudly here rather than silently vanishing from the help.
215
+ * The drift-guard test asserts every `useOps` name maps to exactly one group.
216
+ */
217
+ export declare function groupForOp(name: string): string;
218
+ /**
219
+ * One-liner for an op row: prefer `promptSnippet` (the terse reflection summary),
220
+ * fall back to `description`. Collapse to a single line, then truncate uniformly to
221
+ * ~HELP_ONELINER_WIDTH at the last word boundary, appending an ellipsis when cut.
222
+ * Applied to EVERY row identically — no per-op special-casing, and the ops-registry
223
+ * text itself is never edited.
224
+ */
225
+ export declare function helpOneLiner(op: OpDefinition): string;
226
+ /**
227
+ * Grouped, scannable top-level help. Sections appear in HELP_GROUPS order (only
228
+ * groups with ≥1 op), ops sorted alphabetically within a group, each row a name
229
+ * padded to the group's own max-name width followed by the truncated one-liner.
230
+ * A static Process modes section surfaces `pi-bound` (a process mode, not a
231
+ * substrate op). The Global flags block is retained verbatim plus `--version`.
232
+ * Plain text only.
233
+ */
118
234
  export declare function deriveTopHelp(): string;
119
235
  export declare function main(argv: string[]): Promise<number>;
120
236
  export {};
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}