@davidorex/pi-context-cli 0.28.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 +13 -0
- package/README.md +60 -0
- package/dist/cli.d.ts +104 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +427 -0
- package/dist/cli.js.map +1 -0
- package/package.json +42 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this package are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/). This package has not yet been published to npm; the accumulated surface below sits under `[Unreleased]` and becomes its first published version's section at first publish.
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
## [0.28.0] - 2026-06-03
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- Runtime-reflecting CLI over pi-context's op-registry: the command surface is derived from the registered operations rather than hand-maintained (`b0a831e`)
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- String-enum union flags derive as strings rather than JSON (DEFECT-1) (`37f3f31`)
|
package/README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# @davidorex/pi-context-cli
|
|
2
|
+
|
|
3
|
+
A command-line interface over the [`@davidorex/pi-context`](https://github.com/davidorex/pi-project-workflows/tree/main/packages/pi-context) substrate operations.
|
|
4
|
+
|
|
5
|
+
The command set is **auto-tracking**: every operation in pi-context's op-registry whose `surface` is `"use"` surfaces as a CLI command by reflection. There is no hardcoded command list — adding an op to pi-context makes a new CLI command appear with zero changes to this package. Operations that depend on a pi runtime handle (e.g. `list-tools`) carry `surface: "process"` and are not surfaced here.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm i -g @davidorex/pi-context-cli
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This provides a `pi-context` binary.
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
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
|
|
20
|
+
pi-context <op> [flags] # run an op
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Each op's flags derive from its parameter schema:
|
|
24
|
+
|
|
25
|
+
- scalar fields take `--field value` (`string` / `number`); `boolean` fields are presence flags (`--flag`, or `--flag true|false`)
|
|
26
|
+
- object / array / typeless fields take a JSON argument: `--field '<inline json>'` or `--field @path/to.json`
|
|
27
|
+
|
|
28
|
+
Example:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pi-context read-block --block tasks
|
|
32
|
+
pi-context append-block-item --block issues --arrayKey issues --item @new-issue.json --autoId
|
|
33
|
+
pi-context read-block-page --block framework-gaps --offset 0 --limit 50
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Global flags
|
|
37
|
+
|
|
38
|
+
- `--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
|
|
40
|
+
- `--yes`, `--force` — pre-authorize an auth-gated op in a non-interactive context
|
|
41
|
+
- `--writer <json>` — override the auto-resolved writer identity
|
|
42
|
+
- `--help`, `-h` — top-level help, or per-op help after an op name
|
|
43
|
+
|
|
44
|
+
## Writer identity
|
|
45
|
+
|
|
46
|
+
Ops that declare a `writer` parameter (e.g. `promote-item`, `write-schema-migration`) get it injected automatically when not passed via `--writer`. The identity is resolved by cascade: `git config user.email`, then `$USER`, then the literal `"operator"`. Pass `--writer '{"kind":"human","user":"you@example.com"}'` to override.
|
|
47
|
+
|
|
48
|
+
## Auth-gated ops
|
|
49
|
+
|
|
50
|
+
Ops marked `authGated` (writes that mutate config / schemas / migrations) require authorization, mirroring the in-pi dispatch gate:
|
|
51
|
+
|
|
52
|
+
- `--yes` / `--force` proceeds immediately
|
|
53
|
+
- on an interactive terminal you are prompted (`Authorize <op>? [y/N]`)
|
|
54
|
+
- in a non-interactive context without `--yes` the op refuses
|
|
55
|
+
|
|
56
|
+
## Exit codes
|
|
57
|
+
|
|
58
|
+
- `0` — success
|
|
59
|
+
- `1` — op/runtime error, or declined authorization
|
|
60
|
+
- `2` — usage error (unknown op, unknown flag, missing required field)
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { type OpDefinition } from "@davidorex/pi-context/ops";
|
|
3
|
+
/**
|
|
4
|
+
* The surfaced command set: every op the CLI exposes. Derived by reflection —
|
|
5
|
+
* NOT a hardcoded list. A `surface: "process"` op (currently only list-tools)
|
|
6
|
+
* is excluded here by the partition, never by name.
|
|
7
|
+
*/
|
|
8
|
+
export declare const useOps: OpDefinition[];
|
|
9
|
+
/** Field-type tag rendered in help and used to pick a coercion strategy. */
|
|
10
|
+
export type FieldType = "string" | "number" | "boolean" | "json";
|
|
11
|
+
interface FieldSchema {
|
|
12
|
+
type?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
anyOf?: Array<{
|
|
15
|
+
type?: string;
|
|
16
|
+
const?: unknown;
|
|
17
|
+
enum?: unknown[];
|
|
18
|
+
}>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Extract the literal string values of a string-enum field, or null for any
|
|
22
|
+
* non-enum shape. A typebox `Type.Union([Type.Literal("eq"), …])` serializes at
|
|
23
|
+
* runtime to `{ anyOf: [{ type: "string", const: "eq" }, …] }` with no
|
|
24
|
+
* top-level `type` — so the union members must be read off `anyOf`.
|
|
25
|
+
*
|
|
26
|
+
* Returns the string values only when `anyOf` is a non-empty array and EVERY
|
|
27
|
+
* element contributes string members (a `const` string, or — for forward
|
|
28
|
+
* safety against an element-level `enum` shape — string members of an `enum`
|
|
29
|
+
* array). Any element that fails to contribute makes the whole shape non-enum
|
|
30
|
+
* (returns null), so mixed unions and non-string literals are left untouched
|
|
31
|
+
* and continue to flow through the JSON path.
|
|
32
|
+
*/
|
|
33
|
+
export declare function stringEnumValues(field: FieldSchema): string[] | null;
|
|
34
|
+
/**
|
|
35
|
+
* Map a typebox field schema to a CLI field type. Scalars carry an explicit
|
|
36
|
+
* `type`; Type.Unknown() has no `type`; Type.Record/Type.Object report
|
|
37
|
+
* `type:"object"`; arrays `type:"array"` — all of which are JSON-arg fields.
|
|
38
|
+
*/
|
|
39
|
+
export declare function fieldType(field: FieldSchema): FieldType;
|
|
40
|
+
/** Look up a surfaced op by name. Returns undefined for unknown/non-use ops. */
|
|
41
|
+
export declare function resolveOp(name: string): OpDefinition | undefined;
|
|
42
|
+
/** True when `name` is a real op but not surfaced via the CLI (surface!=="use"). */
|
|
43
|
+
export declare function isProcessOnlyOp(name: string): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Resolve the operator identity for schema-driven writer injection. Cascade
|
|
46
|
+
* (replicated from pi-agent-dispatch getVerifiedOperatorIdentity, which is not
|
|
47
|
+
* importable without dragging the dispatch tree):
|
|
48
|
+
* (1) `git config user.email`, trimmed, if non-empty
|
|
49
|
+
* (2) process.env.USER, if non-empty
|
|
50
|
+
* (3) null
|
|
51
|
+
* Dependencies are injectable for unit testing.
|
|
52
|
+
*/
|
|
53
|
+
export declare function resolveIdentity(deps?: {
|
|
54
|
+
gitEmail?: () => string | null;
|
|
55
|
+
envUser?: string | undefined;
|
|
56
|
+
}): string | null;
|
|
57
|
+
export interface ParsedArgs {
|
|
58
|
+
cwd: string;
|
|
59
|
+
json: boolean;
|
|
60
|
+
yes: boolean;
|
|
61
|
+
help: boolean;
|
|
62
|
+
explicitWriter?: unknown;
|
|
63
|
+
params: Record<string, unknown>;
|
|
64
|
+
}
|
|
65
|
+
export declare class UsageError extends Error {
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Parse the argv tail (everything after the op name) against the op's schema.
|
|
69
|
+
* Throws UsageError on unknown flags, missing required fields, or malformed
|
|
70
|
+
* values. Does NOT inject the writer or evaluate the auth gate — callers do
|
|
71
|
+
* that after parsing so those concerns stay independently testable.
|
|
72
|
+
*/
|
|
73
|
+
export declare function parseOpArgs(op: OpDefinition, argv: string[], cwdBase?: string): ParsedArgs;
|
|
74
|
+
/**
|
|
75
|
+
* Schema-driven writer injection: when the op declares a `writer` field and the
|
|
76
|
+
* caller did not pass `--writer`, fill params.writer from the resolved operator
|
|
77
|
+
* identity (falling back to "operator"). Mutates and returns `params`.
|
|
78
|
+
*/
|
|
79
|
+
export declare function injectWriter(op: OpDefinition, params: Record<string, unknown>, identity: string | null): Record<string, unknown>;
|
|
80
|
+
export type AuthDecision = {
|
|
81
|
+
allow: true;
|
|
82
|
+
} | {
|
|
83
|
+
allow: false;
|
|
84
|
+
reason: string;
|
|
85
|
+
needsPrompt: boolean;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Pure auth-gate decision (no I/O). Mirrors the pi-agent-dispatch gate:
|
|
89
|
+
* - not gated → allow
|
|
90
|
+
* - --yes/--force → allow
|
|
91
|
+
* - interactive TTY → defer to a prompt (needsPrompt)
|
|
92
|
+
* - non-interactive without --yes → refuse
|
|
93
|
+
*/
|
|
94
|
+
export declare function authDecision(op: OpDefinition, opts: {
|
|
95
|
+
yes: boolean;
|
|
96
|
+
interactive: boolean;
|
|
97
|
+
}): AuthDecision;
|
|
98
|
+
/** Per-op help text: description + one line per declared field. */
|
|
99
|
+
export declare function deriveHelp(op: OpDefinition): string;
|
|
100
|
+
/** Top-level help: one line per surfaced op + global flag notes. */
|
|
101
|
+
export declare function deriveTopHelp(): string;
|
|
102
|
+
export declare function main(argv: string[]): Promise<number>;
|
|
103
|
+
export {};
|
|
104
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AA+BA,OAAO,EAAE,KAAK,YAAY,EAAO,MAAM,2BAA2B,CAAC;AAEnE;;;;GAIG;AACH,eAAO,MAAM,MAAM,EAAE,YAAY,EAA2C,CAAC;AAE7E,4EAA4E;AAC5E,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;AAEjE,UAAU,WAAW;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC,CAAC;CACpE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,EAAE,GAAG,IAAI,CAmBpE;AAYD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,CAgBvD;AAED,gFAAgF;AAChF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAEhE;AAED,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE;IACtC,QAAQ,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,GAAG,MAAM,GAAG,IAAI,CAmBhB;AAED,MAAM,WAAW,UAAU;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,qBAAa,UAAW,SAAQ,KAAK;CAAG;AAExC;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,SAAgB,GAAG,UAAU,CAwGjG;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC3B,EAAE,EAAE,YAAY,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,EAAE,MAAM,GAAG,IAAI,GACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMzB;AAED,MAAM,MAAM,YAAY,GAAG;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CAAC;AAEpG;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,GAAG,YAAY,CASzG;AAED,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,EAAE,EAAE,YAAY,GAAG,MAAM,CAoBnD;AAED,oEAAoE;AACpE,wBAAgB,aAAa,IAAI,MAAM,CAgBtC;AAcD,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAsE1D"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* pi-context — auto-tracking command-line interface over the pi-context
|
|
4
|
+
* op-registry.
|
|
5
|
+
*
|
|
6
|
+
* The command set is derived by REFLECTION over the imported `ops` array
|
|
7
|
+
* (`@davidorex/pi-context/ops`): every OpDefinition whose `surface === "use"`
|
|
8
|
+
* becomes a CLI command. Adding an op to pi-context surfaces a new CLI command
|
|
9
|
+
* with zero edits here — there is intentionally NO hardcoded op-name list. The
|
|
10
|
+
* one op that depends on a pi-runtime handle (list-tools) carries
|
|
11
|
+
* `surface: "process"` at source and is therefore filtered out by the same
|
|
12
|
+
* partition, not by name.
|
|
13
|
+
*
|
|
14
|
+
* Per-op flags are derived from each op's typebox `parameters` schema: scalar
|
|
15
|
+
* fields (string/number/boolean) take `--field value` (boolean is a presence
|
|
16
|
+
* flag); object/array/typeless fields take a JSON argument (`--field '<json>'`
|
|
17
|
+
* or `--field @file.json`). Required fields (op.parameters.required) are
|
|
18
|
+
* enforced before invocation, except `writer`, which is schema-driven
|
|
19
|
+
* auto-injected from the resolved operator identity when not passed explicitly.
|
|
20
|
+
*
|
|
21
|
+
* authGated ops mirror the pi-agent-dispatch auth-gate: `--yes`/`--force`
|
|
22
|
+
* proceeds; interactive TTY prompts; non-interactive without `--yes` refuses.
|
|
23
|
+
*
|
|
24
|
+
* The pure pieces (resolveOp / parseOpArgs / deriveHelp / deriveTopHelp /
|
|
25
|
+
* resolveIdentity / authDecision / useOps) are exported for unit testing.
|
|
26
|
+
*/
|
|
27
|
+
import { execSync } from "node:child_process";
|
|
28
|
+
import { readFileSync } from "node:fs";
|
|
29
|
+
import path from "node:path";
|
|
30
|
+
import { createInterface } from "node:readline";
|
|
31
|
+
import { fileURLToPath } from "node:url";
|
|
32
|
+
import { ops } from "@davidorex/pi-context/ops";
|
|
33
|
+
/**
|
|
34
|
+
* The surfaced command set: every op the CLI exposes. Derived by reflection —
|
|
35
|
+
* NOT a hardcoded list. A `surface: "process"` op (currently only list-tools)
|
|
36
|
+
* is excluded here by the partition, never by name.
|
|
37
|
+
*/
|
|
38
|
+
export const useOps = ops.filter((o) => o.surface === "use");
|
|
39
|
+
/**
|
|
40
|
+
* Extract the literal string values of a string-enum field, or null for any
|
|
41
|
+
* non-enum shape. A typebox `Type.Union([Type.Literal("eq"), …])` serializes at
|
|
42
|
+
* runtime to `{ anyOf: [{ type: "string", const: "eq" }, …] }` with no
|
|
43
|
+
* top-level `type` — so the union members must be read off `anyOf`.
|
|
44
|
+
*
|
|
45
|
+
* Returns the string values only when `anyOf` is a non-empty array and EVERY
|
|
46
|
+
* element contributes string members (a `const` string, or — for forward
|
|
47
|
+
* safety against an element-level `enum` shape — string members of an `enum`
|
|
48
|
+
* array). Any element that fails to contribute makes the whole shape non-enum
|
|
49
|
+
* (returns null), so mixed unions and non-string literals are left untouched
|
|
50
|
+
* and continue to flow through the JSON path.
|
|
51
|
+
*/
|
|
52
|
+
export function stringEnumValues(field) {
|
|
53
|
+
const anyOf = field.anyOf;
|
|
54
|
+
if (!Array.isArray(anyOf) || anyOf.length === 0)
|
|
55
|
+
return null;
|
|
56
|
+
const values = [];
|
|
57
|
+
for (const el of anyOf) {
|
|
58
|
+
if (el.type === "string" && typeof el.const === "string") {
|
|
59
|
+
values.push(el.const);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (Array.isArray(el.enum)) {
|
|
63
|
+
const strings = el.enum.filter((e) => typeof e === "string");
|
|
64
|
+
if (strings.length === el.enum.length && strings.length > 0) {
|
|
65
|
+
values.push(...strings);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
return values.length > 0 ? values : null;
|
|
72
|
+
}
|
|
73
|
+
/** The typebox Type.Object value carried at runtime on op.parameters. */
|
|
74
|
+
function objectSchema(op) {
|
|
75
|
+
return op.parameters ?? {};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Map a typebox field schema to a CLI field type. Scalars carry an explicit
|
|
79
|
+
* `type`; Type.Unknown() has no `type`; Type.Record/Type.Object report
|
|
80
|
+
* `type:"object"`; arrays `type:"array"` — all of which are JSON-arg fields.
|
|
81
|
+
*/
|
|
82
|
+
export function fieldType(field) {
|
|
83
|
+
// String-enum unions (Type.Union of string literals) coerce as verbatim
|
|
84
|
+
// strings — identical to a plain string field — not as JSON.
|
|
85
|
+
if (stringEnumValues(field) !== null)
|
|
86
|
+
return "string";
|
|
87
|
+
switch (field.type) {
|
|
88
|
+
case "string":
|
|
89
|
+
return "string";
|
|
90
|
+
case "number":
|
|
91
|
+
case "integer":
|
|
92
|
+
return "number";
|
|
93
|
+
case "boolean":
|
|
94
|
+
return "boolean";
|
|
95
|
+
default:
|
|
96
|
+
// object | array | undefined (Type.Unknown) → JSON argument
|
|
97
|
+
return "json";
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/** Look up a surfaced op by name. Returns undefined for unknown/non-use ops. */
|
|
101
|
+
export function resolveOp(name) {
|
|
102
|
+
return useOps.find((o) => o.name === name);
|
|
103
|
+
}
|
|
104
|
+
/** True when `name` is a real op but not surfaced via the CLI (surface!=="use"). */
|
|
105
|
+
export function isProcessOnlyOp(name) {
|
|
106
|
+
return ops.some((o) => o.name === name) && !useOps.some((o) => o.name === name);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Resolve the operator identity for schema-driven writer injection. Cascade
|
|
110
|
+
* (replicated from pi-agent-dispatch getVerifiedOperatorIdentity, which is not
|
|
111
|
+
* importable without dragging the dispatch tree):
|
|
112
|
+
* (1) `git config user.email`, trimmed, if non-empty
|
|
113
|
+
* (2) process.env.USER, if non-empty
|
|
114
|
+
* (3) null
|
|
115
|
+
* Dependencies are injectable for unit testing.
|
|
116
|
+
*/
|
|
117
|
+
export function resolveIdentity(deps) {
|
|
118
|
+
const gitEmail = deps?.gitEmail ??
|
|
119
|
+
(() => {
|
|
120
|
+
try {
|
|
121
|
+
return execSync("git config user.email", {
|
|
122
|
+
encoding: "utf8",
|
|
123
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
124
|
+
}).trim();
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
const envUser = deps && "envUser" in deps ? deps.envUser : process.env.USER;
|
|
131
|
+
const email = gitEmail();
|
|
132
|
+
if (email && email.length > 0)
|
|
133
|
+
return email;
|
|
134
|
+
if (envUser && envUser.length > 0)
|
|
135
|
+
return envUser;
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
export class UsageError extends Error {
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Parse the argv tail (everything after the op name) against the op's schema.
|
|
142
|
+
* Throws UsageError on unknown flags, missing required fields, or malformed
|
|
143
|
+
* values. Does NOT inject the writer or evaluate the auth gate — callers do
|
|
144
|
+
* that after parsing so those concerns stay independently testable.
|
|
145
|
+
*/
|
|
146
|
+
export function parseOpArgs(op, argv, cwdBase = process.cwd()) {
|
|
147
|
+
const schema = objectSchema(op);
|
|
148
|
+
const props = schema.properties ?? {};
|
|
149
|
+
const out = {
|
|
150
|
+
cwd: cwdBase,
|
|
151
|
+
json: false,
|
|
152
|
+
yes: false,
|
|
153
|
+
help: false,
|
|
154
|
+
params: {},
|
|
155
|
+
};
|
|
156
|
+
for (let i = 0; i < argv.length; i++) {
|
|
157
|
+
const tok = argv[i];
|
|
158
|
+
if (tok === "--help" || tok === "-h") {
|
|
159
|
+
out.help = true;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (tok === "--json") {
|
|
163
|
+
out.json = true;
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (tok === "--yes" || tok === "--force") {
|
|
167
|
+
out.yes = true;
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (tok === "--cwd") {
|
|
171
|
+
const v = argv[++i];
|
|
172
|
+
if (v === undefined)
|
|
173
|
+
throw new UsageError("--cwd requires a directory argument");
|
|
174
|
+
out.cwd = path.isAbsolute(v) ? v : path.resolve(cwdBase, v);
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (tok === "--writer") {
|
|
178
|
+
const v = argv[++i];
|
|
179
|
+
if (v === undefined)
|
|
180
|
+
throw new UsageError("--writer requires a JSON argument");
|
|
181
|
+
try {
|
|
182
|
+
out.explicitWriter = v.startsWith("@") ? JSON.parse(readFileSync(v.slice(1), "utf8")) : JSON.parse(v);
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
throw new UsageError(`--writer: ${err instanceof Error ? err.message : String(err)}`);
|
|
186
|
+
}
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
if (!tok.startsWith("--")) {
|
|
190
|
+
throw new UsageError(`unexpected argument: ${tok}`);
|
|
191
|
+
}
|
|
192
|
+
const field = tok.slice(2);
|
|
193
|
+
const fschema = props[field];
|
|
194
|
+
if (fschema === undefined) {
|
|
195
|
+
throw new UsageError(`unknown flag: ${tok}`);
|
|
196
|
+
}
|
|
197
|
+
const kind = fieldType(fschema);
|
|
198
|
+
if (kind === "boolean") {
|
|
199
|
+
// Presence flag; accept an optional explicit true|false next token.
|
|
200
|
+
const next = argv[i + 1];
|
|
201
|
+
if (next === "true" || next === "false") {
|
|
202
|
+
out.params[field] = next === "true";
|
|
203
|
+
i++;
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
out.params[field] = true;
|
|
207
|
+
}
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
const value = argv[++i];
|
|
211
|
+
if (value === undefined)
|
|
212
|
+
throw new UsageError(`--${field} requires a value`);
|
|
213
|
+
if (kind === "number") {
|
|
214
|
+
const n = Number(value);
|
|
215
|
+
if (Number.isNaN(n))
|
|
216
|
+
throw new UsageError(`--${field} expects a number, got '${value}'`);
|
|
217
|
+
out.params[field] = n;
|
|
218
|
+
}
|
|
219
|
+
else if (kind === "string") {
|
|
220
|
+
const vals = stringEnumValues(fschema);
|
|
221
|
+
if (vals !== null && !vals.includes(value)) {
|
|
222
|
+
throw new UsageError(`--${field} expects one of: ${vals.join(", ")}; got '${value}'`);
|
|
223
|
+
}
|
|
224
|
+
out.params[field] = value;
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
// json: inline JSON or @file
|
|
228
|
+
try {
|
|
229
|
+
out.params[field] = value.startsWith("@")
|
|
230
|
+
? JSON.parse(readFileSync(value.slice(1), "utf8"))
|
|
231
|
+
: JSON.parse(value);
|
|
232
|
+
}
|
|
233
|
+
catch (err) {
|
|
234
|
+
throw new UsageError(`--${field}: ${err instanceof Error ? err.message : String(err)}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (out.explicitWriter !== undefined) {
|
|
239
|
+
out.params.writer = out.explicitWriter;
|
|
240
|
+
}
|
|
241
|
+
// Required-field check — `writer` is exempt (schema-driven auto-injected
|
|
242
|
+
// after parse when the op declares it and none was passed).
|
|
243
|
+
if (!out.help) {
|
|
244
|
+
const required = (schema.required ?? []).filter((r) => r !== "writer");
|
|
245
|
+
const missing = required.filter((r) => !(r in out.params));
|
|
246
|
+
if (missing.length > 0) {
|
|
247
|
+
throw new UsageError(`missing required: ${missing.map((m) => `--${m}`).join(", ")}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return out;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Schema-driven writer injection: when the op declares a `writer` field and the
|
|
254
|
+
* caller did not pass `--writer`, fill params.writer from the resolved operator
|
|
255
|
+
* identity (falling back to "operator"). Mutates and returns `params`.
|
|
256
|
+
*/
|
|
257
|
+
export function injectWriter(op, params, identity) {
|
|
258
|
+
const props = objectSchema(op).properties ?? {};
|
|
259
|
+
if (props.writer !== undefined && params.writer === undefined) {
|
|
260
|
+
params.writer = { kind: "human", user: identity ?? "operator" };
|
|
261
|
+
}
|
|
262
|
+
return params;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Pure auth-gate decision (no I/O). Mirrors the pi-agent-dispatch gate:
|
|
266
|
+
* - not gated → allow
|
|
267
|
+
* - --yes/--force → allow
|
|
268
|
+
* - interactive TTY → defer to a prompt (needsPrompt)
|
|
269
|
+
* - non-interactive without --yes → refuse
|
|
270
|
+
*/
|
|
271
|
+
export function authDecision(op, opts) {
|
|
272
|
+
if (op.authGated !== true)
|
|
273
|
+
return { allow: true };
|
|
274
|
+
if (opts.yes)
|
|
275
|
+
return { allow: true };
|
|
276
|
+
if (opts.interactive)
|
|
277
|
+
return { allow: false, needsPrompt: true, reason: "interactive confirmation required" };
|
|
278
|
+
return {
|
|
279
|
+
allow: false,
|
|
280
|
+
needsPrompt: false,
|
|
281
|
+
reason: `${op.name} requires authorization; re-run with --yes in a non-interactive context`,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
/** Per-op help text: description + one line per declared field. */
|
|
285
|
+
export function deriveHelp(op) {
|
|
286
|
+
const schema = objectSchema(op);
|
|
287
|
+
const props = schema.properties ?? {};
|
|
288
|
+
const required = new Set(schema.required ?? []);
|
|
289
|
+
const lines = [`${op.name} — ${op.description}`, ""];
|
|
290
|
+
const entries = Object.entries(props);
|
|
291
|
+
if (entries.length === 0) {
|
|
292
|
+
lines.push(" (no parameters)");
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
lines.push("Flags:");
|
|
296
|
+
for (const [field, fschema] of entries) {
|
|
297
|
+
const vals = stringEnumValues(fschema);
|
|
298
|
+
const t = vals ? vals.join("|") : fieldType(fschema);
|
|
299
|
+
const req = required.has(field) ? "required" : "optional";
|
|
300
|
+
const desc = fschema.description ? ` — ${fschema.description}` : "";
|
|
301
|
+
lines.push(` --${field} <${t}> (${req})${desc}`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
lines.push("", "Global flags: --cwd <dir> --json --yes --writer <json> --help");
|
|
305
|
+
return lines.join("\n");
|
|
306
|
+
}
|
|
307
|
+
/** Top-level help: one line per surfaced op + global flag notes. */
|
|
308
|
+
export function deriveTopHelp() {
|
|
309
|
+
const lines = ["pi-context <op> [flags]", "", "Commands:"];
|
|
310
|
+
const width = Math.max(...useOps.map((o) => o.name.length));
|
|
311
|
+
for (const op of useOps) {
|
|
312
|
+
lines.push(` ${op.name.padEnd(width)} — ${op.description.split("\n")[0]}`);
|
|
313
|
+
}
|
|
314
|
+
lines.push("", "Global flags:", " --cwd <dir> substrate root (default: cwd)", " --json emit { ok, op, output } envelope", " --yes, --force pre-authorize gated ops in non-interactive contexts", " --writer <json> override the auto-resolved writer identity", " --help, -h this help, or per-op help after an op name");
|
|
315
|
+
return lines.join("\n");
|
|
316
|
+
}
|
|
317
|
+
/** Prompt the operator on an interactive TTY. Resolves true on y/yes. */
|
|
318
|
+
function promptConfirm(opName) {
|
|
319
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
320
|
+
return new Promise((resolve) => {
|
|
321
|
+
rl.question(`Authorize ${opName}? [y/N] `, (answer) => {
|
|
322
|
+
rl.close();
|
|
323
|
+
const a = answer.trim().toLowerCase();
|
|
324
|
+
resolve(a === "y" || a === "yes");
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
export async function main(argv) {
|
|
329
|
+
const first = argv[0];
|
|
330
|
+
if (first === undefined || first === "--help" || first === "-h") {
|
|
331
|
+
process.stdout.write(`${deriveTopHelp()}\n`);
|
|
332
|
+
return 0;
|
|
333
|
+
}
|
|
334
|
+
const op = resolveOp(first);
|
|
335
|
+
if (op === undefined) {
|
|
336
|
+
if (isProcessOnlyOp(first)) {
|
|
337
|
+
process.stderr.write(`${first} is not available via the CLI (process-only op)\n`);
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
process.stderr.write(`unknown command: ${first}\n\n${deriveTopHelp()}\n`);
|
|
341
|
+
}
|
|
342
|
+
return 2;
|
|
343
|
+
}
|
|
344
|
+
let parsed;
|
|
345
|
+
try {
|
|
346
|
+
parsed = parseOpArgs(op, argv.slice(1));
|
|
347
|
+
}
|
|
348
|
+
catch (err) {
|
|
349
|
+
if (err instanceof UsageError) {
|
|
350
|
+
process.stderr.write(`error: ${err.message}\n\n${deriveHelp(op)}\n`);
|
|
351
|
+
return 2;
|
|
352
|
+
}
|
|
353
|
+
throw err;
|
|
354
|
+
}
|
|
355
|
+
if (parsed.help) {
|
|
356
|
+
process.stdout.write(`${deriveHelp(op)}\n`);
|
|
357
|
+
return 0;
|
|
358
|
+
}
|
|
359
|
+
injectWriter(op, parsed.params, resolveIdentity());
|
|
360
|
+
const decision = authDecision(op, {
|
|
361
|
+
yes: parsed.yes,
|
|
362
|
+
interactive: Boolean(process.stdin.isTTY && process.stdout.isTTY),
|
|
363
|
+
});
|
|
364
|
+
if (decision.allow === false) {
|
|
365
|
+
if (decision.needsPrompt) {
|
|
366
|
+
const ok = await promptConfirm(op.name);
|
|
367
|
+
if (!ok) {
|
|
368
|
+
process.stderr.write(`declined: ${op.name} not authorized\n`);
|
|
369
|
+
return 1;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
process.stderr.write(`${decision.reason}\n`);
|
|
374
|
+
return 1;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
try {
|
|
378
|
+
const text = await op.run(parsed.cwd, parsed.params);
|
|
379
|
+
if (parsed.json) {
|
|
380
|
+
process.stdout.write(`${JSON.stringify({ ok: true, op: op.name, output: text })}\n`);
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
process.stdout.write(`${text}\n`);
|
|
384
|
+
}
|
|
385
|
+
return 0;
|
|
386
|
+
}
|
|
387
|
+
catch (err) {
|
|
388
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
389
|
+
if (parsed.json) {
|
|
390
|
+
process.stdout.write(`${JSON.stringify({ ok: false, op: op.name, error: message })}\n`);
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
process.stderr.write(`error: ${message}\n`);
|
|
394
|
+
}
|
|
395
|
+
return 1;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* True when this module is the process entrypoint (invoked as `pi-context …`),
|
|
400
|
+
* false when it is merely imported (e.g. by the unit tests). Guards the
|
|
401
|
+
* auto-run so importing the module to test its pure helpers does not execute
|
|
402
|
+
* main() against the test runner's argv.
|
|
403
|
+
*/
|
|
404
|
+
function isEntrypoint() {
|
|
405
|
+
const invoked = process.argv[1];
|
|
406
|
+
if (invoked === undefined)
|
|
407
|
+
return false;
|
|
408
|
+
try {
|
|
409
|
+
return fileURLToPath(import.meta.url) === path.resolve(invoked);
|
|
410
|
+
}
|
|
411
|
+
catch {
|
|
412
|
+
return false;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
// Module entrypoint: run main() and map its resolved exit code. A thrown
|
|
416
|
+
// (non-UsageError) error maps to exit 1.
|
|
417
|
+
if (isEntrypoint()) {
|
|
418
|
+
main(process.argv.slice(2))
|
|
419
|
+
.then((code) => {
|
|
420
|
+
process.exitCode = code;
|
|
421
|
+
})
|
|
422
|
+
.catch((err) => {
|
|
423
|
+
process.stderr.write(`error: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
424
|
+
process.exitCode = 1;
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@davidorex/pi-context-cli",
|
|
3
|
+
"version": "0.28.0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"description": "Auto-tracking command-line interface over the pi-context op-registry — every substrate op surfaces as a CLI command by reflection, no hardcoded command list",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"author": "David Ryan",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"pi-context",
|
|
13
|
+
"cli"
|
|
14
|
+
],
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/davidorex/pi-project-workflows.git",
|
|
18
|
+
"directory": "packages/pi-context-cli"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://github.com/davidorex/pi-project-workflows/tree/main/packages/pi-context-cli",
|
|
21
|
+
"main": "./dist/cli.js",
|
|
22
|
+
"bin": {
|
|
23
|
+
"pi-context": "./dist/cli.js"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist/",
|
|
27
|
+
"*.md"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"clean": "rm -rf dist",
|
|
31
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
|
32
|
+
"prepublishOnly": "npm run clean && npm run build",
|
|
33
|
+
"test": "tsx --test src/*.test.ts"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@davidorex/pi-context": "^0.28.0",
|
|
37
|
+
"typebox": "^1.1.24"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=22.19.0"
|
|
41
|
+
}
|
|
42
|
+
}
|