@agent-surface/cli 0.8.0 → 0.9.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/README.md
CHANGED
|
@@ -42,6 +42,8 @@ agent-surface snapshot [scenario] # write/refresh the committed baseline
|
|
|
42
42
|
agent-surface check [scenario] # exit non-zero when the surface drifts
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
+
Every command covers all scenarios in the config unless you name one. `inspect` prints each in turn:
|
|
46
|
+
|
|
45
47
|
```text
|
|
46
48
|
scenario admin route /devices
|
|
47
49
|
9 callable, 2 visible-disabled
|
|
@@ -57,6 +59,12 @@ authoritative (domain) (1)
|
|
|
57
59
|
~ devices.disable [destructive, confirmation:required, deviceIds bound+locked]
|
|
58
60
|
Disable the given devices
|
|
59
61
|
reason: Select at least one device first
|
|
62
|
+
|
|
63
|
+
scenario anonymous route /devices
|
|
64
|
+
0 callable, 0 visible-disabled
|
|
65
|
+
|
|
66
|
+
Nothing is registered for this scenario — the agent has no surface here.
|
|
67
|
+
Re-run with --explain to see whether a policy hid it.
|
|
60
68
|
```
|
|
61
69
|
|
|
62
70
|
### Why is my capability missing?
|
package/dist/bin.js
CHANGED
|
@@ -45,6 +45,8 @@ Usage
|
|
|
45
45
|
agent-surface snapshot [scenario] write/refresh the committed baseline
|
|
46
46
|
agent-surface check [scenario] fail if the surface drifted from the baseline
|
|
47
47
|
|
|
48
|
+
Every command covers all scenarios in the config unless you name one.
|
|
49
|
+
|
|
48
50
|
Options
|
|
49
51
|
--config <path> path to agent-surface.config.* (default: nearest, searching upward)
|
|
50
52
|
--baseline-dir where baselines live (default: .agent-surface next to the config)
|
|
@@ -116,7 +118,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
116
118
|
...values["baseline-dir"] ? { baselineDir: values["baseline-dir"] } : {}
|
|
117
119
|
};
|
|
118
120
|
if (command === "inspect") {
|
|
119
|
-
const { runInspect } = await import("./inspect-
|
|
121
|
+
const { runInspect } = await import("./inspect-SLYLBZAH.js");
|
|
120
122
|
return await runInspect({
|
|
121
123
|
...shared,
|
|
122
124
|
...values.explain ? { explain: true } : {},
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bin.ts","../src/dom.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { realpathSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { parseArgs } from \"node:util\";\nimport { installDom } from \"./dom.js\";\nimport { findConfig } from \"./load.js\";\nimport { writeError, write } from \"./output.js\";\n\nconst USAGE = `agent-surface — inspect and check the agent surface your app exposes\n\nUsage\n agent-surface inspect [scenario] what an agent can see right now\n agent-surface snapshot [scenario] write/refresh the committed baseline\n agent-surface check [scenario] fail if the surface drifted from the baseline\n\nOptions\n --config <path> path to agent-surface.config.* (default: nearest, searching upward)\n --baseline-dir where baselines live (default: .agent-surface next to the config)\n --scope <prefix> restrict to a component-type prefix (repeatable)\n --explain name the policies behind every decision, hidden ones included\n --schemas include input/output JSON Schemas\n --json emit data instead of a rendered view\n --plain force plain text (implied when piped, or under CI / NO_COLOR)\n -h, --help show this\n -v, --version print the version\n`;\n\nexport async function main(argv: string[] = process.argv.slice(2)): Promise<number> {\n let parsed;\n try {\n parsed = parseArgs({\n args: argv,\n allowPositionals: true,\n options: {\n config: { type: \"string\" },\n \"baseline-dir\": { type: \"string\" },\n scope: { type: \"string\", multiple: true },\n explain: { type: \"boolean\", default: false },\n schemas: { type: \"boolean\", default: false },\n json: { type: \"boolean\", default: false },\n plain: { type: \"boolean\", default: false },\n help: { type: \"boolean\", short: \"h\", default: false },\n version: { type: \"boolean\", short: \"v\", default: false },\n },\n });\n } catch (error) {\n writeError(error instanceof Error ? error.message : String(error));\n writeError(USAGE);\n return 2;\n }\n\n const { values, positionals } = parsed;\n if (values.help) {\n write(USAGE);\n return 0;\n }\n if (values.version) {\n write(await readVersion());\n return 0;\n }\n\n const [command, scenario] = positionals;\n if (!command) {\n write(USAGE);\n return 2;\n }\n if (![\"inspect\", \"snapshot\", \"check\"].includes(command)) {\n writeError(`unknown command \"${command}\"`);\n writeError(USAGE);\n return 2;\n }\n\n const configPath = values.config ?? findConfig();\n if (!configPath) {\n writeError(\n \"no agent-surface.config.* found (searched upward from the working directory).\\n\" +\n \"Create one that points at your app's composition root — see https://agent-surface-docs.vercel.app/20-cli\",\n );\n return 2;\n }\n\n // A presentation surface needs a DOM to mount into, and react-dom reads these\n // globals at import time — so this must happen before any app module loads.\n const uninstallDom = installDom();\n try {\n const shared = {\n configPath,\n ...(scenario ? { scenario } : {}),\n ...(values.scope ? { scope: values.scope } : {}),\n ...(values.json ? { json: true } : {}),\n ...(values.plain ? { plain: true } : {}),\n ...(values[\"baseline-dir\"] ? { baselineDir: values[\"baseline-dir\"] } : {}),\n };\n\n if (command === \"inspect\") {\n const { runInspect } = await import(\"./commands/inspect.js\");\n return await runInspect({\n ...shared,\n ...(values.explain ? { explain: true } : {}),\n ...(values.schemas ? { schemas: true } : {}),\n });\n }\n if (command === \"snapshot\") {\n const { runSnapshot } = await import(\"./commands/snapshot.js\");\n return await runSnapshot(shared);\n }\n const { runCheck } = await import(\"./commands/check.js\");\n return await runCheck(shared);\n } catch (error) {\n writeError(error instanceof Error ? error.message : String(error));\n if (error instanceof Error && error.stack && process.env[\"AGENT_SURFACE_DEBUG\"]) {\n writeError(error.stack);\n }\n return 1;\n } finally {\n uninstallDom();\n }\n}\n\nasync function readVersion(): Promise<string> {\n try {\n const { readFileSync } = await import(\"node:fs\");\n const path = fileURLToPath(new URL(\"../package.json\", import.meta.url));\n return (JSON.parse(readFileSync(path, \"utf8\")) as { version: string }).version;\n } catch {\n return \"unknown\";\n }\n}\n\n/**\n * Self-execute only as a binary; importing this module (tests) must not run it.\n * `argv[1]` is compared through `realpathSync` because package managers install\n * the bin as a symlink — comparing the raw path silently never matches, and the\n * CLI exits 0 having done nothing.\n */\nfunction invokedAsBinary(): boolean {\n const entry = process.argv[1];\n if (!entry) return false;\n try {\n return fileURLToPath(import.meta.url) === realpathSync(entry);\n } catch {\n return false;\n }\n}\n\nif (invokedAsBinary()) {\n main().then(\n (code) => {\n process.exitCode = code;\n },\n (error: unknown) => {\n writeError(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n },\n );\n}\n","import { JSDOM } from \"jsdom\";\n\n/**\n * A presentation surface only exists once components mount, and mounting needs\n * a DOM. Vitest gets one from its `jsdom` environment; a plain Node process has\n * to install one itself — *before* anything imports `react-dom`, which reads\n * these globals at module scope.\n *\n * Process-wide on purpose: the app tree runs inside the vite-node graph, which\n * shares this realm's globals.\n */\nexport function installDom(url = \"http://localhost/\"): () => void {\n const globals = globalThis as Record<string, unknown>;\n if (typeof globals[\"document\"] !== \"undefined\") return noop;\n\n const dom = new JSDOM(\"<!doctype html><html><body></body></html>\", {\n url,\n pretendToBeVisual: true,\n });\n const { window } = dom;\n\n // Everything jsdom's window defines that this realm does not already have.\n // Skipping existing keys matters: Node's own `fetch`, `URL` and timers are\n // more capable than jsdom's shims, and clobbering them breaks app code.\n for (const key of Object.getOwnPropertyNames(window)) {\n if (key.startsWith(\"_\")) continue;\n if (key in globals) continue;\n const descriptor = Object.getOwnPropertyDescriptor(window, key);\n if (!descriptor) continue;\n Object.defineProperty(globals, key, descriptor);\n }\n\n for (const key of [\"window\", \"document\", \"navigator\"] as const) {\n if (!(key in globals)) {\n Object.defineProperty(globals, key, { value: window[key], configurable: true });\n }\n }\n\n return noop;\n}\n\n/**\n * Teardown is deliberately a no-op, and the DOM is deliberately process-wide.\n *\n * `react-dom` captures `window`/`document` when it is first imported. Removing\n * the globals — or worse, calling `window.close()` — leaves that captured\n * reference pointing at a dead realm, so the *next* mount in the same process\n * fails in a way that looks nothing like its cause. A CLI invocation ends by\n * exiting, so there is nothing to reclaim; only in-process callers (the test\n * suite) run more than one command, and those are exactly the ones this\n * protects.\n */\nfunction noop(): void {}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/bin.ts","../src/dom.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { realpathSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { parseArgs } from \"node:util\";\nimport { installDom } from \"./dom.js\";\nimport { findConfig } from \"./load.js\";\nimport { writeError, write } from \"./output.js\";\n\nconst USAGE = `agent-surface — inspect and check the agent surface your app exposes\n\nUsage\n agent-surface inspect [scenario] what an agent can see right now\n agent-surface snapshot [scenario] write/refresh the committed baseline\n agent-surface check [scenario] fail if the surface drifted from the baseline\n\nEvery command covers all scenarios in the config unless you name one.\n\nOptions\n --config <path> path to agent-surface.config.* (default: nearest, searching upward)\n --baseline-dir where baselines live (default: .agent-surface next to the config)\n --scope <prefix> restrict to a component-type prefix (repeatable)\n --explain name the policies behind every decision, hidden ones included\n --schemas include input/output JSON Schemas\n --json emit data instead of a rendered view\n --plain force plain text (implied when piped, or under CI / NO_COLOR)\n -h, --help show this\n -v, --version print the version\n`;\n\nexport async function main(argv: string[] = process.argv.slice(2)): Promise<number> {\n let parsed;\n try {\n parsed = parseArgs({\n args: argv,\n allowPositionals: true,\n options: {\n config: { type: \"string\" },\n \"baseline-dir\": { type: \"string\" },\n scope: { type: \"string\", multiple: true },\n explain: { type: \"boolean\", default: false },\n schemas: { type: \"boolean\", default: false },\n json: { type: \"boolean\", default: false },\n plain: { type: \"boolean\", default: false },\n help: { type: \"boolean\", short: \"h\", default: false },\n version: { type: \"boolean\", short: \"v\", default: false },\n },\n });\n } catch (error) {\n writeError(error instanceof Error ? error.message : String(error));\n writeError(USAGE);\n return 2;\n }\n\n const { values, positionals } = parsed;\n if (values.help) {\n write(USAGE);\n return 0;\n }\n if (values.version) {\n write(await readVersion());\n return 0;\n }\n\n const [command, scenario] = positionals;\n if (!command) {\n write(USAGE);\n return 2;\n }\n if (![\"inspect\", \"snapshot\", \"check\"].includes(command)) {\n writeError(`unknown command \"${command}\"`);\n writeError(USAGE);\n return 2;\n }\n\n const configPath = values.config ?? findConfig();\n if (!configPath) {\n writeError(\n \"no agent-surface.config.* found (searched upward from the working directory).\\n\" +\n \"Create one that points at your app's composition root — see https://agent-surface-docs.vercel.app/20-cli\",\n );\n return 2;\n }\n\n // A presentation surface needs a DOM to mount into, and react-dom reads these\n // globals at import time — so this must happen before any app module loads.\n const uninstallDom = installDom();\n try {\n const shared = {\n configPath,\n ...(scenario ? { scenario } : {}),\n ...(values.scope ? { scope: values.scope } : {}),\n ...(values.json ? { json: true } : {}),\n ...(values.plain ? { plain: true } : {}),\n ...(values[\"baseline-dir\"] ? { baselineDir: values[\"baseline-dir\"] } : {}),\n };\n\n if (command === \"inspect\") {\n const { runInspect } = await import(\"./commands/inspect.js\");\n return await runInspect({\n ...shared,\n ...(values.explain ? { explain: true } : {}),\n ...(values.schemas ? { schemas: true } : {}),\n });\n }\n if (command === \"snapshot\") {\n const { runSnapshot } = await import(\"./commands/snapshot.js\");\n return await runSnapshot(shared);\n }\n const { runCheck } = await import(\"./commands/check.js\");\n return await runCheck(shared);\n } catch (error) {\n writeError(error instanceof Error ? error.message : String(error));\n if (error instanceof Error && error.stack && process.env[\"AGENT_SURFACE_DEBUG\"]) {\n writeError(error.stack);\n }\n return 1;\n } finally {\n uninstallDom();\n }\n}\n\nasync function readVersion(): Promise<string> {\n try {\n const { readFileSync } = await import(\"node:fs\");\n const path = fileURLToPath(new URL(\"../package.json\", import.meta.url));\n return (JSON.parse(readFileSync(path, \"utf8\")) as { version: string }).version;\n } catch {\n return \"unknown\";\n }\n}\n\n/**\n * Self-execute only as a binary; importing this module (tests) must not run it.\n * `argv[1]` is compared through `realpathSync` because package managers install\n * the bin as a symlink — comparing the raw path silently never matches, and the\n * CLI exits 0 having done nothing.\n */\nfunction invokedAsBinary(): boolean {\n const entry = process.argv[1];\n if (!entry) return false;\n try {\n return fileURLToPath(import.meta.url) === realpathSync(entry);\n } catch {\n return false;\n }\n}\n\nif (invokedAsBinary()) {\n main().then(\n (code) => {\n process.exitCode = code;\n },\n (error: unknown) => {\n writeError(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n },\n );\n}\n","import { JSDOM } from \"jsdom\";\n\n/**\n * A presentation surface only exists once components mount, and mounting needs\n * a DOM. Vitest gets one from its `jsdom` environment; a plain Node process has\n * to install one itself — *before* anything imports `react-dom`, which reads\n * these globals at module scope.\n *\n * Process-wide on purpose: the app tree runs inside the vite-node graph, which\n * shares this realm's globals.\n */\nexport function installDom(url = \"http://localhost/\"): () => void {\n const globals = globalThis as Record<string, unknown>;\n if (typeof globals[\"document\"] !== \"undefined\") return noop;\n\n const dom = new JSDOM(\"<!doctype html><html><body></body></html>\", {\n url,\n pretendToBeVisual: true,\n });\n const { window } = dom;\n\n // Everything jsdom's window defines that this realm does not already have.\n // Skipping existing keys matters: Node's own `fetch`, `URL` and timers are\n // more capable than jsdom's shims, and clobbering them breaks app code.\n for (const key of Object.getOwnPropertyNames(window)) {\n if (key.startsWith(\"_\")) continue;\n if (key in globals) continue;\n const descriptor = Object.getOwnPropertyDescriptor(window, key);\n if (!descriptor) continue;\n Object.defineProperty(globals, key, descriptor);\n }\n\n for (const key of [\"window\", \"document\", \"navigator\"] as const) {\n if (!(key in globals)) {\n Object.defineProperty(globals, key, { value: window[key], configurable: true });\n }\n }\n\n return noop;\n}\n\n/**\n * Teardown is deliberately a no-op, and the DOM is deliberately process-wide.\n *\n * `react-dom` captures `window`/`document` when it is first imported. Removing\n * the globals — or worse, calling `window.close()` — leaves that captured\n * reference pointing at a dead realm, so the *next* mount in the same process\n * fails in a way that looks nothing like its cause. A CLI invocation ends by\n * exiting, so there is nothing to reclaim; only in-process callers (the test\n * suite) run more than one command, and those are exactly the ones this\n * protects.\n */\nfunction noop(): void {}\n"],"mappings":";;;;;;;;AACA,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAC9B,SAAS,iBAAiB;;;ACH1B,SAAS,aAAa;AAWf,SAAS,WAAW,MAAM,qBAAiC;AAChE,QAAM,UAAU;AAChB,MAAI,OAAO,QAAQ,UAAU,MAAM,YAAa,QAAO;AAEvD,QAAM,MAAM,IAAI,MAAM,6CAA6C;AAAA,IACjE;AAAA,IACA,mBAAmB;AAAA,EACrB,CAAC;AACD,QAAM,EAAE,OAAO,IAAI;AAKnB,aAAW,OAAO,OAAO,oBAAoB,MAAM,GAAG;AACpD,QAAI,IAAI,WAAW,GAAG,EAAG;AACzB,QAAI,OAAO,QAAS;AACpB,UAAM,aAAa,OAAO,yBAAyB,QAAQ,GAAG;AAC9D,QAAI,CAAC,WAAY;AACjB,WAAO,eAAe,SAAS,KAAK,UAAU;AAAA,EAChD;AAEA,aAAW,OAAO,CAAC,UAAU,YAAY,WAAW,GAAY;AAC9D,QAAI,EAAE,OAAO,UAAU;AACrB,aAAO,eAAe,SAAS,KAAK,EAAE,OAAO,OAAO,GAAG,GAAG,cAAc,KAAK,CAAC;AAAA,IAChF;AAAA,EACF;AAEA,SAAO;AACT;AAaA,SAAS,OAAa;AAAC;;;AD5CvB,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBd,eAAsB,KAAK,OAAiB,QAAQ,KAAK,MAAM,CAAC,GAAoB;AAClF,MAAI;AACJ,MAAI;AACF,aAAS,UAAU;AAAA,MACjB,MAAM;AAAA,MACN,kBAAkB;AAAA,MAClB,SAAS;AAAA,QACP,QAAQ,EAAE,MAAM,SAAS;AAAA,QACzB,gBAAgB,EAAE,MAAM,SAAS;AAAA,QACjC,OAAO,EAAE,MAAM,UAAU,UAAU,KAAK;AAAA,QACxC,SAAS,EAAE,MAAM,WAAW,SAAS,MAAM;AAAA,QAC3C,SAAS,EAAE,MAAM,WAAW,SAAS,MAAM;AAAA,QAC3C,MAAM,EAAE,MAAM,WAAW,SAAS,MAAM;AAAA,QACxC,OAAO,EAAE,MAAM,WAAW,SAAS,MAAM;AAAA,QACzC,MAAM,EAAE,MAAM,WAAW,OAAO,KAAK,SAAS,MAAM;AAAA,QACpD,SAAS,EAAE,MAAM,WAAW,OAAO,KAAK,SAAS,MAAM;AAAA,MACzD;AAAA,IACF,CAAC;AAAA,EACH,SAAS,OAAO;AACd,eAAW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AACjE,eAAW,KAAK;AAChB,WAAO;AAAA,EACT;AAEA,QAAM,EAAE,QAAQ,YAAY,IAAI;AAChC,MAAI,OAAO,MAAM;AACf,UAAM,KAAK;AACX,WAAO;AAAA,EACT;AACA,MAAI,OAAO,SAAS;AAClB,UAAM,MAAM,YAAY,CAAC;AACzB,WAAO;AAAA,EACT;AAEA,QAAM,CAAC,SAAS,QAAQ,IAAI;AAC5B,MAAI,CAAC,SAAS;AACZ,UAAM,KAAK;AACX,WAAO;AAAA,EACT;AACA,MAAI,CAAC,CAAC,WAAW,YAAY,OAAO,EAAE,SAAS,OAAO,GAAG;AACvD,eAAW,oBAAoB,OAAO,GAAG;AACzC,eAAW,KAAK;AAChB,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,OAAO,UAAU,WAAW;AAC/C,MAAI,CAAC,YAAY;AACf;AAAA,MACE;AAAA,IAEF;AACA,WAAO;AAAA,EACT;AAIA,QAAM,eAAe,WAAW;AAChC,MAAI;AACF,UAAM,SAAS;AAAA,MACb;AAAA,MACA,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,MAC/B,GAAI,OAAO,QAAQ,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC;AAAA,MAC9C,GAAI,OAAO,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AAAA,MACpC,GAAI,OAAO,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;AAAA,MACtC,GAAI,OAAO,cAAc,IAAI,EAAE,aAAa,OAAO,cAAc,EAAE,IAAI,CAAC;AAAA,IAC1E;AAEA,QAAI,YAAY,WAAW;AACzB,YAAM,EAAE,WAAW,IAAI,MAAM,OAAO,uBAAuB;AAC3D,aAAO,MAAM,WAAW;AAAA,QACtB,GAAG;AAAA,QACH,GAAI,OAAO,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;AAAA,QAC1C,GAAI,OAAO,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;AAAA,MAC5C,CAAC;AAAA,IACH;AACA,QAAI,YAAY,YAAY;AAC1B,YAAM,EAAE,YAAY,IAAI,MAAM,OAAO,wBAAwB;AAC7D,aAAO,MAAM,YAAY,MAAM;AAAA,IACjC;AACA,UAAM,EAAE,SAAS,IAAI,MAAM,OAAO,qBAAqB;AACvD,WAAO,MAAM,SAAS,MAAM;AAAA,EAC9B,SAAS,OAAO;AACd,eAAW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AACjE,QAAI,iBAAiB,SAAS,MAAM,SAAS,QAAQ,IAAI,qBAAqB,GAAG;AAC/E,iBAAW,MAAM,KAAK;AAAA,IACxB;AACA,WAAO;AAAA,EACT,UAAE;AACA,iBAAa;AAAA,EACf;AACF;AAEA,eAAe,cAA+B;AAC5C,MAAI;AACF,UAAM,EAAE,aAAa,IAAI,MAAM,OAAO,IAAS;AAC/C,UAAM,OAAO,cAAc,IAAI,IAAI,mBAAmB,YAAY,GAAG,CAAC;AACtE,WAAQ,KAAK,MAAM,aAAa,MAAM,MAAM,CAAC,EAA0B;AAAA,EACzE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQA,SAAS,kBAA2B;AAClC,QAAM,QAAQ,QAAQ,KAAK,CAAC;AAC5B,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI;AACF,WAAO,cAAc,YAAY,GAAG,MAAM,aAAa,KAAK;AAAA,EAC9D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,IAAI,gBAAgB,GAAG;AACrB,OAAK,EAAE;AAAA,IACL,CAAC,SAAS;AACR,cAAQ,WAAW;AAAA,IACrB;AAAA,IACA,CAAC,UAAmB;AAClB,iBAAW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AACjE,cAAQ,WAAW;AAAA,IACrB;AAAA,EACF;AACF;","names":[]}
|
|
@@ -156,41 +156,43 @@ function rowFor(descriptor, kind, tags, options, schemas) {
|
|
|
156
156
|
|
|
157
157
|
// src/commands/inspect.tsx
|
|
158
158
|
import { jsx } from "react/jsx-runtime";
|
|
159
|
+
function jsonFor(result, explain) {
|
|
160
|
+
return {
|
|
161
|
+
scenario: result.scenario,
|
|
162
|
+
snapshot: result.snapshot,
|
|
163
|
+
...explain ? { explanation: result.explanation } : {}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
159
166
|
async function runInspect(options) {
|
|
160
167
|
const runner = await createSurfaceRunner(options.configPath);
|
|
161
168
|
const ink = isPlain(options) ? null : await loadInk();
|
|
162
169
|
try {
|
|
163
|
-
const
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
result
|
|
168
|
-
|
|
169
|
-
|
|
170
|
+
const scenarios = options.scenario ? [options.scenario] : runner.scenarioNames;
|
|
171
|
+
const collected = [];
|
|
172
|
+
for (const [index, scenario] of scenarios.entries()) {
|
|
173
|
+
const stop = ink ? await transient(/* @__PURE__ */ jsx(ink.Loading, { label: `mounting ${scenario}\u2026` })) : void 0;
|
|
174
|
+
let result;
|
|
175
|
+
try {
|
|
176
|
+
result = await runner.collect({
|
|
177
|
+
scenario,
|
|
178
|
+
...options.scope ? { scope: options.scope } : {}
|
|
179
|
+
});
|
|
180
|
+
} finally {
|
|
181
|
+
stop?.();
|
|
182
|
+
}
|
|
183
|
+
if (options.json) {
|
|
184
|
+
collected.push(jsonFor(result, options.explain === true));
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
const view = buildView(result, {
|
|
188
|
+
...options.explain ? { explain: true } : {},
|
|
189
|
+
...options.schemas ? { schemas: true } : {}
|
|
170
190
|
});
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
if (options.json) {
|
|
175
|
-
write(
|
|
176
|
-
JSON.stringify(
|
|
177
|
-
{
|
|
178
|
-
scenario: result.scenario,
|
|
179
|
-
snapshot: result.snapshot,
|
|
180
|
-
...options.explain ? { explanation: result.explanation } : {}
|
|
181
|
-
},
|
|
182
|
-
null,
|
|
183
|
-
2
|
|
184
|
-
)
|
|
185
|
-
);
|
|
186
|
-
return 0;
|
|
191
|
+
if (ink) await paint(/* @__PURE__ */ jsx(ink.Surface, { view }));
|
|
192
|
+
else write(index === 0 ? renderSurfacePlain(view) : `
|
|
193
|
+
${renderSurfacePlain(view)}`);
|
|
187
194
|
}
|
|
188
|
-
|
|
189
|
-
...options.explain ? { explain: true } : {},
|
|
190
|
-
...options.schemas ? { schemas: true } : {}
|
|
191
|
-
});
|
|
192
|
-
if (ink) await paint(/* @__PURE__ */ jsx(ink.Surface, { view }));
|
|
193
|
-
else write(renderSurfacePlain(view));
|
|
195
|
+
if (options.json) write(JSON.stringify({ scenarios: collected }, null, 2));
|
|
194
196
|
return 0;
|
|
195
197
|
} finally {
|
|
196
198
|
await runner.close();
|
|
@@ -199,4 +201,4 @@ async function runInspect(options) {
|
|
|
199
201
|
export {
|
|
200
202
|
runInspect
|
|
201
203
|
};
|
|
202
|
-
//# sourceMappingURL=inspect-
|
|
204
|
+
//# sourceMappingURL=inspect-SLYLBZAH.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/render/model.ts","../src/commands/inspect.tsx"],"sourcesContent":["import type {\n AgentActionDescriptor,\n AgentObservationDescriptor,\n AgentProcedureDescriptor,\n AgentSurfaceSnapshot,\n} from \"@agent-surface/core\";\nimport type { CapabilityExplanation, SurfaceExplanation } from \"@agent-surface/core/explain\";\nimport type { CollectResult } from \"../collect.js\";\n\n/**\n * One view model, two renderers. The Ink UI and the plain-text fallback both\n * consume this, so `--plain` can never drift into showing something different\n * from what a TTY shows.\n */\nexport interface CapabilityRow {\n capabilityId: string;\n /** Leaf name — the group heading already carries the rest of the id. */\n name: string;\n kind: \"observation\" | \"action\" | \"procedure\";\n plane: \"view\" | \"domain\";\n outcome: \"expose\" | \"disable\" | \"hide\";\n description: string;\n reason?: string;\n tags: string[];\n policies?: CapabilityExplanation[\"policies\"];\n availability?: CapabilityExplanation[\"availability\"];\n schemas?: { input?: unknown; output?: unknown };\n}\n\nexport interface CapabilityGroup {\n heading: string;\n rows: CapabilityRow[];\n}\n\nexport interface SurfaceView {\n scenario: string;\n route?: string;\n groups: CapabilityGroup[];\n counts: { callable: number; disabled: number; hidden: number };\n explained: boolean;\n}\n\nexport interface ViewOptions {\n explain?: boolean;\n schemas?: boolean;\n}\n\nfunction leafOf(capabilityId: string): string {\n const withoutPlane = capabilityId.replace(/^(view|domain):/, \"\");\n const dot = withoutPlane.lastIndexOf(\".\");\n return dot === -1 ? withoutPlane : withoutPlane.slice(dot + 1);\n}\n\nfunction observationTags(): string[] {\n return [\"observation\"];\n}\n\nfunction actionTags(action: AgentActionDescriptor): string[] {\n const tags: string[] = [action.effect];\n if (action.idempotent) tags.push(\"idempotent\");\n if (action.reversible) tags.push(\"reversible\");\n if (action.confirmation !== \"never\") tags.push(`confirmation:${action.confirmation}`);\n return tags;\n}\n\nfunction procedureTags(procedure: AgentProcedureDescriptor): string[] {\n const tags: string[] = [procedure.effect];\n if (procedure.confirmation !== \"never\") tags.push(`confirmation:${procedure.confirmation}`);\n for (const field of procedure.boundFields) {\n tags.push(`${field.path} bound${field.locked ? \"+locked\" : \"\"}`);\n }\n return tags;\n}\n\nfunction explanationIndex(explanation: SurfaceExplanation): Map<string, CapabilityExplanation> {\n const index = new Map<string, CapabilityExplanation>();\n for (const capability of explanation.capabilities) {\n // Keyed by id + registration so two instances of one component stay apart.\n index.set(`${capability.capabilityId}\u0000${capability.registrationId}`, capability);\n }\n return index;\n}\n\nexport function buildView(result: CollectResult, options: ViewOptions = {}): SurfaceView {\n const { snapshot, explanation } = result;\n const index = explanationIndex(explanation);\n const groups: CapabilityGroup[] = [];\n const counts = { callable: 0, disabled: 0, hidden: 0 };\n\n const enrich = (\n row: CapabilityRow,\n capabilityId: string,\n registrationId: string,\n ): CapabilityRow => {\n const explained = index.get(`${capabilityId}\u0000${registrationId}`);\n if (options.explain && explained) {\n row.policies = explained.policies;\n row.availability = explained.availability;\n }\n return row;\n };\n\n for (const component of snapshot.components) {\n const rows: CapabilityRow[] = [];\n\n for (const observation of component.observations) {\n rows.push(\n enrich(\n rowFor(observation, \"observation\", observationTags(), options, {\n input: undefined,\n output: observation.outputSchema,\n }),\n observation.capabilityId,\n component.registrationId,\n ),\n );\n }\n for (const action of component.actions) {\n rows.push(\n enrich(\n rowFor(action, \"action\", actionTags(action), options, {\n input: action.inputSchema,\n output: action.outputSchema,\n }),\n action.capabilityId,\n component.registrationId,\n ),\n );\n }\n\n groups.push({\n heading:\n component.instanceId === \"default\"\n ? component.type\n : `${component.type}@${component.instanceId}`,\n rows,\n });\n }\n\n if (snapshot.procedures.length > 0) {\n groups.push({\n heading: \"authoritative (domain)\",\n rows: snapshot.procedures.map((procedure) =>\n enrich(\n {\n capabilityId: procedure.procedureId,\n name: procedure.procedureId.replace(/^domain:/, \"\"),\n kind: \"procedure\",\n plane: \"domain\",\n outcome: procedure.available ? \"expose\" : \"disable\",\n description: procedure.description,\n ...(procedure.unavailableReason ? { reason: procedure.unavailableReason } : {}),\n tags: procedureTags(procedure),\n ...(options.schemas\n ? { schemas: { input: procedure.inputSchema, output: procedure.outputSchema } }\n : {}),\n },\n procedure.procedureId,\n procedure.registrationId,\n ),\n ),\n });\n }\n\n // Hidden capabilities exist only in the explanation — that is the whole point\n // of it. They get their own group so nobody mistakes them for callable.\n if (options.explain) {\n const hidden = explanation.capabilities.filter((c) => c.outcome === \"hide\");\n if (hidden.length > 0) {\n groups.push({\n heading: \"hidden by policy (absent from the snapshot)\",\n rows: hidden.map((capability) => ({\n capabilityId: capability.capabilityId,\n name: leafOf(capability.capabilityId),\n kind: capability.kind,\n plane: capability.plane,\n outcome: \"hide\" as const,\n description: capability.description,\n tags: [`${capability.component.type}@${capability.component.instanceId}`],\n policies: capability.policies,\n availability: capability.availability,\n })),\n });\n }\n }\n\n for (const capability of explanation.capabilities) {\n if (capability.outcome === \"expose\") counts.callable += 1;\n else if (capability.outcome === \"disable\") counts.disabled += 1;\n else counts.hidden += 1;\n }\n\n return {\n scenario: result.scenario,\n ...(snapshot.route?.path ? { route: snapshot.route.path } : {}),\n groups,\n counts,\n explained: options.explain === true,\n };\n}\n\nfunction rowFor(\n descriptor: AgentObservationDescriptor | AgentActionDescriptor,\n kind: \"observation\" | \"action\",\n tags: string[],\n options: ViewOptions,\n schemas: { input?: unknown; output?: unknown },\n): CapabilityRow {\n return {\n capabilityId: descriptor.capabilityId,\n name: descriptor.name,\n kind,\n plane: \"view\",\n outcome: descriptor.available ? \"expose\" : \"disable\",\n description: descriptor.description,\n ...(descriptor.unavailableReason ? { reason: descriptor.unavailableReason } : {}),\n tags,\n ...(options.schemas ? { schemas } : {}),\n };\n}\n","import { createSurfaceRunner } from \"../load.js\";\nimport { buildView } from \"../render/model.js\";\nimport { renderSurfacePlain } from \"../render/plain.js\";\nimport { isPlain, loadInk, paint, transient, write } from \"../output.js\";\n\nexport interface InspectOptions {\n configPath: string;\n scenario?: string;\n scope?: string[];\n explain?: boolean;\n schemas?: boolean;\n json?: boolean;\n plain?: boolean;\n}\n\nexport async function runInspect(options: InspectOptions): Promise<number> {\n const runner = await createSurfaceRunner(options.configPath);\n // `null` when Ink cannot run here (React 18 host), which is a fallback to\n // plain text rather than a failed command — see loadInk().\n const ink = isPlain(options) ? null : await loadInk();\n try {\n const scenario = options.scenario ?? runner.scenarioNames[0]!;\n const stop = ink ? await transient(<ink.Loading label={`mounting ${scenario}…`} />) : undefined;\n\n let result;\n try {\n result = await runner.collect({\n scenario,\n ...(options.scope ? { scope: options.scope } : {}),\n });\n } finally {\n stop?.();\n }\n\n if (options.json) {\n write(\n JSON.stringify(\n {\n scenario: result.scenario,\n snapshot: result.snapshot,\n ...(options.explain ? { explanation: result.explanation } : {}),\n },\n null,\n 2,\n ),\n );\n return 0;\n }\n\n const view = buildView(result, {\n ...(options.explain ? { explain: true } : {}),\n ...(options.schemas ? { schemas: true } : {}),\n });\n\n if (ink) await paint(<ink.Surface view={view} />);\n else write(renderSurfacePlain(view));\n return 0;\n } finally {\n await runner.close();\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/render/model.ts","../src/commands/inspect.tsx"],"sourcesContent":["import type {\n AgentActionDescriptor,\n AgentObservationDescriptor,\n AgentProcedureDescriptor,\n AgentSurfaceSnapshot,\n} from \"@agent-surface/core\";\nimport type { CapabilityExplanation, SurfaceExplanation } from \"@agent-surface/core/explain\";\nimport type { CollectResult } from \"../collect.js\";\n\n/**\n * One view model, two renderers. The Ink UI and the plain-text fallback both\n * consume this, so `--plain` can never drift into showing something different\n * from what a TTY shows.\n */\nexport interface CapabilityRow {\n capabilityId: string;\n /** Leaf name — the group heading already carries the rest of the id. */\n name: string;\n kind: \"observation\" | \"action\" | \"procedure\";\n plane: \"view\" | \"domain\";\n outcome: \"expose\" | \"disable\" | \"hide\";\n description: string;\n reason?: string;\n tags: string[];\n policies?: CapabilityExplanation[\"policies\"];\n availability?: CapabilityExplanation[\"availability\"];\n schemas?: { input?: unknown; output?: unknown };\n}\n\nexport interface CapabilityGroup {\n heading: string;\n rows: CapabilityRow[];\n}\n\nexport interface SurfaceView {\n scenario: string;\n route?: string;\n groups: CapabilityGroup[];\n counts: { callable: number; disabled: number; hidden: number };\n explained: boolean;\n}\n\nexport interface ViewOptions {\n explain?: boolean;\n schemas?: boolean;\n}\n\nfunction leafOf(capabilityId: string): string {\n const withoutPlane = capabilityId.replace(/^(view|domain):/, \"\");\n const dot = withoutPlane.lastIndexOf(\".\");\n return dot === -1 ? withoutPlane : withoutPlane.slice(dot + 1);\n}\n\nfunction observationTags(): string[] {\n return [\"observation\"];\n}\n\nfunction actionTags(action: AgentActionDescriptor): string[] {\n const tags: string[] = [action.effect];\n if (action.idempotent) tags.push(\"idempotent\");\n if (action.reversible) tags.push(\"reversible\");\n if (action.confirmation !== \"never\") tags.push(`confirmation:${action.confirmation}`);\n return tags;\n}\n\nfunction procedureTags(procedure: AgentProcedureDescriptor): string[] {\n const tags: string[] = [procedure.effect];\n if (procedure.confirmation !== \"never\") tags.push(`confirmation:${procedure.confirmation}`);\n for (const field of procedure.boundFields) {\n tags.push(`${field.path} bound${field.locked ? \"+locked\" : \"\"}`);\n }\n return tags;\n}\n\nfunction explanationIndex(explanation: SurfaceExplanation): Map<string, CapabilityExplanation> {\n const index = new Map<string, CapabilityExplanation>();\n for (const capability of explanation.capabilities) {\n // Keyed by id + registration so two instances of one component stay apart.\n index.set(`${capability.capabilityId}\u0000${capability.registrationId}`, capability);\n }\n return index;\n}\n\nexport function buildView(result: CollectResult, options: ViewOptions = {}): SurfaceView {\n const { snapshot, explanation } = result;\n const index = explanationIndex(explanation);\n const groups: CapabilityGroup[] = [];\n const counts = { callable: 0, disabled: 0, hidden: 0 };\n\n const enrich = (\n row: CapabilityRow,\n capabilityId: string,\n registrationId: string,\n ): CapabilityRow => {\n const explained = index.get(`${capabilityId}\u0000${registrationId}`);\n if (options.explain && explained) {\n row.policies = explained.policies;\n row.availability = explained.availability;\n }\n return row;\n };\n\n for (const component of snapshot.components) {\n const rows: CapabilityRow[] = [];\n\n for (const observation of component.observations) {\n rows.push(\n enrich(\n rowFor(observation, \"observation\", observationTags(), options, {\n input: undefined,\n output: observation.outputSchema,\n }),\n observation.capabilityId,\n component.registrationId,\n ),\n );\n }\n for (const action of component.actions) {\n rows.push(\n enrich(\n rowFor(action, \"action\", actionTags(action), options, {\n input: action.inputSchema,\n output: action.outputSchema,\n }),\n action.capabilityId,\n component.registrationId,\n ),\n );\n }\n\n groups.push({\n heading:\n component.instanceId === \"default\"\n ? component.type\n : `${component.type}@${component.instanceId}`,\n rows,\n });\n }\n\n if (snapshot.procedures.length > 0) {\n groups.push({\n heading: \"authoritative (domain)\",\n rows: snapshot.procedures.map((procedure) =>\n enrich(\n {\n capabilityId: procedure.procedureId,\n name: procedure.procedureId.replace(/^domain:/, \"\"),\n kind: \"procedure\",\n plane: \"domain\",\n outcome: procedure.available ? \"expose\" : \"disable\",\n description: procedure.description,\n ...(procedure.unavailableReason ? { reason: procedure.unavailableReason } : {}),\n tags: procedureTags(procedure),\n ...(options.schemas\n ? { schemas: { input: procedure.inputSchema, output: procedure.outputSchema } }\n : {}),\n },\n procedure.procedureId,\n procedure.registrationId,\n ),\n ),\n });\n }\n\n // Hidden capabilities exist only in the explanation — that is the whole point\n // of it. They get their own group so nobody mistakes them for callable.\n if (options.explain) {\n const hidden = explanation.capabilities.filter((c) => c.outcome === \"hide\");\n if (hidden.length > 0) {\n groups.push({\n heading: \"hidden by policy (absent from the snapshot)\",\n rows: hidden.map((capability) => ({\n capabilityId: capability.capabilityId,\n name: leafOf(capability.capabilityId),\n kind: capability.kind,\n plane: capability.plane,\n outcome: \"hide\" as const,\n description: capability.description,\n tags: [`${capability.component.type}@${capability.component.instanceId}`],\n policies: capability.policies,\n availability: capability.availability,\n })),\n });\n }\n }\n\n for (const capability of explanation.capabilities) {\n if (capability.outcome === \"expose\") counts.callable += 1;\n else if (capability.outcome === \"disable\") counts.disabled += 1;\n else counts.hidden += 1;\n }\n\n return {\n scenario: result.scenario,\n ...(snapshot.route?.path ? { route: snapshot.route.path } : {}),\n groups,\n counts,\n explained: options.explain === true,\n };\n}\n\nfunction rowFor(\n descriptor: AgentObservationDescriptor | AgentActionDescriptor,\n kind: \"observation\" | \"action\",\n tags: string[],\n options: ViewOptions,\n schemas: { input?: unknown; output?: unknown },\n): CapabilityRow {\n return {\n capabilityId: descriptor.capabilityId,\n name: descriptor.name,\n kind,\n plane: \"view\",\n outcome: descriptor.available ? \"expose\" : \"disable\",\n description: descriptor.description,\n ...(descriptor.unavailableReason ? { reason: descriptor.unavailableReason } : {}),\n tags,\n ...(options.schemas ? { schemas } : {}),\n };\n}\n","import { createSurfaceRunner } from \"../load.js\";\nimport { buildView } from \"../render/model.js\";\nimport { renderSurfacePlain } from \"../render/plain.js\";\nimport { isPlain, loadInk, paint, transient, write } from \"../output.js\";\nimport type { CollectResult } from \"../collect.js\";\n\nexport interface InspectOptions {\n configPath: string;\n scenario?: string;\n scope?: string[];\n explain?: boolean;\n schemas?: boolean;\n json?: boolean;\n plain?: boolean;\n}\n\nfunction jsonFor(result: CollectResult, explain: boolean): Record<string, unknown> {\n return {\n scenario: result.scenario,\n snapshot: result.snapshot,\n ...(explain ? { explanation: result.explanation } : {}),\n };\n}\n\n/**\n * Renders the live surface. A bare `inspect` covers every scenario the config\n * defines, the same way bare `snapshot` and `check` do — a config lists the\n * contexts worth looking at, and picking one of them by `Object.keys` order\n * made the default silently depend on the order they happened to be written in.\n */\nexport async function runInspect(options: InspectOptions): Promise<number> {\n const runner = await createSurfaceRunner(options.configPath);\n // `null` when Ink cannot run here (React 18 host), which is a fallback to\n // plain text rather than a failed command — see loadInk().\n const ink = isPlain(options) ? null : await loadInk();\n try {\n const scenarios = options.scenario ? [options.scenario] : runner.scenarioNames;\n const collected: Array<Record<string, unknown>> = [];\n\n for (const [index, scenario] of scenarios.entries()) {\n const stop = ink\n ? await transient(<ink.Loading label={`mounting ${scenario}…`} />)\n : undefined;\n\n let result;\n try {\n result = await runner.collect({\n scenario,\n ...(options.scope ? { scope: options.scope } : {}),\n });\n } finally {\n stop?.();\n }\n\n // Each scenario is mounted and rendered before the next one is mounted,\n // so a slow config prints as it goes instead of after the last mount.\n // `--json` is the exception: one document, so it has to be complete.\n if (options.json) {\n collected.push(jsonFor(result, options.explain === true));\n continue;\n }\n\n const view = buildView(result, {\n ...(options.explain ? { explain: true } : {}),\n ...(options.schemas ? { schemas: true } : {}),\n });\n\n if (ink) await paint(<ink.Surface view={view} />);\n else write(index === 0 ? renderSurfacePlain(view) : `\\n${renderSurfacePlain(view)}`);\n }\n\n if (options.json) write(JSON.stringify({ scenarios: collected }, null, 2));\n return 0;\n } finally {\n await runner.close();\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-surface/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Inspect and check the agent surface your app exposes — in the terminal and in CI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
"react": "^19.1.1",
|
|
31
31
|
"vite": "^7.1.3",
|
|
32
32
|
"vite-node": "^3.2.4",
|
|
33
|
-
"@agent-surface/core": "^0.
|
|
34
|
-
"@agent-surface/react": "^0.
|
|
35
|
-
"@agent-surface/testing": "^0.
|
|
33
|
+
"@agent-surface/core": "^0.9.0",
|
|
34
|
+
"@agent-surface/react": "^0.9.0",
|
|
35
|
+
"@agent-surface/testing": "^0.9.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@testing-library/react": ">=14",
|