@agent-surface/cli 0.9.0 → 0.10.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/dist/bin.js +80 -29
- package/dist/bin.js.map +1 -1
- package/dist/capabilities-OLFYMHCL.js +37 -0
- package/dist/capabilities-OLFYMHCL.js.map +1 -0
- package/dist/{check-7Z2VNN5R.js → check-IN4XKAND.js} +10 -5
- package/dist/check-IN4XKAND.js.map +1 -0
- package/dist/chunk-4AEQKM2X.js +498 -0
- package/dist/chunk-4AEQKM2X.js.map +1 -0
- package/dist/chunk-A27Y7ALQ.js +51 -0
- package/dist/chunk-A27Y7ALQ.js.map +1 -0
- package/dist/{chunk-S2LM3N6D.js → chunk-FYEXHWGG.js} +2 -50
- package/dist/chunk-FYEXHWGG.js.map +1 -0
- package/dist/collect.js +18 -1
- package/dist/collect.js.map +1 -1
- package/dist/coverage-HCHLJTDD.js +133 -0
- package/dist/coverage-HCHLJTDD.js.map +1 -0
- package/dist/index.d.ts +112 -1
- package/dist/{ink-GCWDO4ML.js → ink-HBPOQTRS.js} +29 -3
- package/dist/ink-HBPOQTRS.js.map +1 -0
- package/dist/{inspect-SLYLBZAH.js → inspect-NJNB6CAS.js} +13 -4
- package/dist/inspect-NJNB6CAS.js.map +1 -0
- package/dist/{snapshot-3D55FL63.js → snapshot-JQAB73OV.js} +5 -3
- package/dist/{snapshot-3D55FL63.js.map → snapshot-JQAB73OV.js.map} +1 -1
- package/package.json +5 -4
- package/dist/check-7Z2VNN5R.js.map +0 -1
- package/dist/chunk-KZUR4CAU.js +0 -84
- package/dist/chunk-KZUR4CAU.js.map +0 -1
- package/dist/chunk-S2LM3N6D.js.map +0 -1
- package/dist/ink-GCWDO4ML.js.map +0 -1
- package/dist/inspect-SLYLBZAH.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-surface/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.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",
|
|
@@ -28,11 +28,12 @@
|
|
|
28
28
|
"ink-spinner": "^5.0.0",
|
|
29
29
|
"jsdom": "^26.1.0",
|
|
30
30
|
"react": "^19.1.1",
|
|
31
|
+
"typescript": "^5.9.2",
|
|
31
32
|
"vite": "^7.1.3",
|
|
32
33
|
"vite-node": "^3.2.4",
|
|
33
|
-
"@agent-surface/core": "^0.
|
|
34
|
-
"@agent-surface/react": "^0.
|
|
35
|
-
"@agent-surface/testing": "^0.
|
|
34
|
+
"@agent-surface/core": "^0.10.0",
|
|
35
|
+
"@agent-surface/react": "^0.10.0",
|
|
36
|
+
"@agent-surface/testing": "^0.10.0"
|
|
36
37
|
},
|
|
37
38
|
"peerDependencies": {
|
|
38
39
|
"@testing-library/react": ">=14",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/check.tsx"],"sourcesContent":["import { relative } from \"node:path\";\nimport { createSurfaceRunner } from \"../load.js\";\nimport {\n annotate,\n baselineDirFor,\n baselinePath,\n diff,\n normalize,\n readBaseline,\n type DiffEntry,\n} from \"../baseline.js\";\nimport { renderDiffPlain } from \"../render/plain.js\";\nimport { isPlain, loadInk, paint, write, writeError } from \"../output.js\";\n\nexport interface CheckOptions {\n configPath: string;\n scenario?: string;\n scope?: string[];\n baselineDir?: string;\n json?: boolean;\n plain?: boolean;\n}\n\ninterface ScenarioDrift {\n scenario: string;\n missingBaseline?: boolean;\n entries: DiffEntry[];\n}\n\n/**\n * Compares every scenario against its committed baseline. Exit code is the\n * point: 0 when the surface is what the repo says it is, 1 when it drifted —\n * so CI fails on an unreviewed change to what agents can see.\n */\nexport async function runCheck(options: CheckOptions): Promise<number> {\n const runner = await createSurfaceRunner(options.configPath);\n try {\n const scenarios = options.scenario ? [options.scenario] : runner.scenarioNames;\n const dir = baselineDirFor(options.configPath, options.baselineDir ?? runner.config.baselineDir);\n const drifted: ScenarioDrift[] = [];\n\n for (const scenario of scenarios) {\n const result = await runner.collect({\n scenario,\n ...(options.scope ? { scope: options.scope } : {}),\n });\n const path = baselinePath(dir, scenario);\n const expected = readBaseline(path);\n\n if (expected === undefined) {\n drifted.push({ scenario, missingBaseline: true, entries: [] });\n continue;\n }\n const actual = normalize(result.snapshot);\n const entries = annotate(diff(expected, actual), actual, expected);\n if (entries.length > 0) drifted.push({ scenario, entries });\n }\n\n if (options.json) {\n write(JSON.stringify({ ok: drifted.length === 0, drifted }, null, 2));\n return drifted.length === 0 ? 0 : 1;\n }\n\n if (drifted.length === 0) {\n write(`surface matches the baseline (${scenarios.length} scenario${scenarios.length === 1 ? \"\" : \"s\"})`);\n return 0;\n }\n\n const ink = isPlain(options) ? null : await loadInk();\n for (const entry of drifted) {\n if (entry.missingBaseline) {\n writeError(\n `${entry.scenario}: no baseline at ${relative(\n process.cwd(),\n baselinePath(dir, entry.scenario),\n )} — run \\`agent-surface snapshot\\` and commit it`,\n );\n continue;\n }\n if (ink) await paint(<ink.Drift scenario={entry.scenario} entries={entry.entries} />);\n else write(renderDiffPlain(entry.scenario, entry.entries));\n }\n writeError(\n `\\nsurface drift in ${drifted.length} scenario${drifted.length === 1 ? \"\" : \"s\"} — review the change, then \\`agent-surface snapshot\\` to accept it`,\n );\n return 1;\n } finally {\n await runner.close();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,gBAAgB;AA+EE;AA7C3B,eAAsB,SAAS,SAAwC;AACrE,QAAM,SAAS,MAAM,oBAAoB,QAAQ,UAAU;AAC3D,MAAI;AACF,UAAM,YAAY,QAAQ,WAAW,CAAC,QAAQ,QAAQ,IAAI,OAAO;AACjE,UAAM,MAAM,eAAe,QAAQ,YAAY,QAAQ,eAAe,OAAO,OAAO,WAAW;AAC/F,UAAM,UAA2B,CAAC;AAElC,eAAW,YAAY,WAAW;AAChC,YAAM,SAAS,MAAM,OAAO,QAAQ;AAAA,QAClC;AAAA,QACA,GAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,MAClD,CAAC;AACD,YAAM,OAAO,aAAa,KAAK,QAAQ;AACvC,YAAM,WAAW,aAAa,IAAI;AAElC,UAAI,aAAa,QAAW;AAC1B,gBAAQ,KAAK,EAAE,UAAU,iBAAiB,MAAM,SAAS,CAAC,EAAE,CAAC;AAC7D;AAAA,MACF;AACA,YAAM,SAAS,UAAU,OAAO,QAAQ;AACxC,YAAM,UAAU,SAAS,KAAK,UAAU,MAAM,GAAG,QAAQ,QAAQ;AACjE,UAAI,QAAQ,SAAS,EAAG,SAAQ,KAAK,EAAE,UAAU,QAAQ,CAAC;AAAA,IAC5D;AAEA,QAAI,QAAQ,MAAM;AAChB,YAAM,KAAK,UAAU,EAAE,IAAI,QAAQ,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAC,CAAC;AACpE,aAAO,QAAQ,WAAW,IAAI,IAAI;AAAA,IACpC;AAEA,QAAI,QAAQ,WAAW,GAAG;AACxB,YAAM,iCAAiC,UAAU,MAAM,YAAY,UAAU,WAAW,IAAI,KAAK,GAAG,GAAG;AACvG,aAAO;AAAA,IACT;AAEA,UAAM,MAAM,QAAQ,OAAO,IAAI,OAAO,MAAM,QAAQ;AACpD,eAAW,SAAS,SAAS;AAC3B,UAAI,MAAM,iBAAiB;AACzB;AAAA,UACE,GAAG,MAAM,QAAQ,oBAAoB;AAAA,YACnC,QAAQ,IAAI;AAAA,YACZ,aAAa,KAAK,MAAM,QAAQ;AAAA,UAClC,CAAC;AAAA,QACH;AACA;AAAA,MACF;AACA,UAAI,IAAK,OAAM,MAAM,oBAAC,IAAI,OAAJ,EAAU,UAAU,MAAM,UAAU,SAAS,MAAM,SAAS,CAAE;AAAA,UAC/E,OAAM,gBAAgB,MAAM,UAAU,MAAM,OAAO,CAAC;AAAA,IAC3D;AACA;AAAA,MACE;AAAA,mBAAsB,QAAQ,MAAM,YAAY,QAAQ,WAAW,IAAI,KAAK,GAAG;AAAA,IACjF;AACA,WAAO;AAAA,EACT,UAAE;AACA,UAAM,OAAO,MAAM;AAAA,EACrB;AACF;","names":[]}
|
package/dist/chunk-KZUR4CAU.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
formatValue
|
|
3
|
-
} from "./chunk-ODUIFFPM.js";
|
|
4
|
-
|
|
5
|
-
// src/render/plain.ts
|
|
6
|
-
var MARK = { expose: "+", disable: "~", hide: "-" };
|
|
7
|
-
function renderRow(row, lines) {
|
|
8
|
-
const tags = row.tags.length > 0 ? ` [${row.tags.join(", ")}]` : "";
|
|
9
|
-
lines.push(` ${MARK[row.outcome]} ${row.name}${tags}`);
|
|
10
|
-
lines.push(` ${row.description}`);
|
|
11
|
-
if (row.reason) lines.push(` reason: ${row.reason}`);
|
|
12
|
-
if (row.policies) {
|
|
13
|
-
if (row.policies.length === 0) {
|
|
14
|
-
lines.push(" policies: none");
|
|
15
|
-
} else {
|
|
16
|
-
for (const policy of row.policies) {
|
|
17
|
-
const vote = policy.discovery ? policy.discovery.decision === "disable" ? `disable \u2014 ${policy.discovery.reason}` : policy.discovery.decision : "no discovery hook";
|
|
18
|
-
const phases = policy.phases.length > 0 ? policy.phases.join("/") : "\u2014";
|
|
19
|
-
const flags = [
|
|
20
|
-
policy.threw ? "THREW" : "",
|
|
21
|
-
policy.confirmationEscalation ? "escalates-confirmation" : ""
|
|
22
|
-
].filter(Boolean).join(", ");
|
|
23
|
-
lines.push(
|
|
24
|
-
` policy ${policy.name} (${policy.scope}, ${phases}): ${vote}${flags ? ` [${flags}]` : ""}`
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
if (row.availability && !row.availability.available) {
|
|
29
|
-
lines.push(
|
|
30
|
-
` availability: unavailable${row.availability.reason ? ` \u2014 ${row.availability.reason}` : ""}`
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
if (row.schemas) {
|
|
35
|
-
if (row.schemas.input !== void 0) {
|
|
36
|
-
lines.push(` input: ${JSON.stringify(row.schemas.input)}`);
|
|
37
|
-
}
|
|
38
|
-
if (row.schemas.output !== void 0) {
|
|
39
|
-
lines.push(` output: ${JSON.stringify(row.schemas.output)}`);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
function renderSurfacePlain(view) {
|
|
44
|
-
const lines = [];
|
|
45
|
-
lines.push(`scenario ${view.scenario}${view.route ? ` route ${view.route}` : ""}`);
|
|
46
|
-
lines.push(
|
|
47
|
-
`${view.counts.callable} callable, ${view.counts.disabled} visible-disabled${view.explained ? `, ${view.counts.hidden} hidden` : ""}`
|
|
48
|
-
);
|
|
49
|
-
const populated = view.groups.filter((group) => group.rows.length > 0);
|
|
50
|
-
if (populated.length === 0) {
|
|
51
|
-
lines.push("");
|
|
52
|
-
lines.push("Nothing is registered for this scenario \u2014 the agent has no surface here.");
|
|
53
|
-
if (!view.explained) {
|
|
54
|
-
lines.push("Re-run with --explain to see whether a policy hid it.");
|
|
55
|
-
}
|
|
56
|
-
return lines.join("\n");
|
|
57
|
-
}
|
|
58
|
-
for (const group of populated) {
|
|
59
|
-
lines.push("");
|
|
60
|
-
lines.push(`${group.heading} (${group.rows.length})`);
|
|
61
|
-
for (const row of group.rows) renderRow(row, lines);
|
|
62
|
-
}
|
|
63
|
-
return lines.join("\n");
|
|
64
|
-
}
|
|
65
|
-
function renderDiffPlain(scenario, entries) {
|
|
66
|
-
const lines = [`${scenario}: ${entries.length} change${entries.length === 1 ? "" : "s"}`];
|
|
67
|
-
for (const entry of entries) {
|
|
68
|
-
const where = entry.subject ? `${entry.subject} (${entry.path})` : entry.path;
|
|
69
|
-
if (entry.kind === "added") lines.push(` + ${where} ${formatValue(entry.after)}`);
|
|
70
|
-
else if (entry.kind === "removed") lines.push(` - ${where} ${formatValue(entry.before)}`);
|
|
71
|
-
else {
|
|
72
|
-
lines.push(` ~ ${where}`);
|
|
73
|
-
lines.push(` before: ${formatValue(entry.before)}`);
|
|
74
|
-
lines.push(` after: ${formatValue(entry.after)}`);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return lines.join("\n");
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export {
|
|
81
|
-
renderSurfacePlain,
|
|
82
|
-
renderDiffPlain
|
|
83
|
-
};
|
|
84
|
-
//# sourceMappingURL=chunk-KZUR4CAU.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/render/plain.ts"],"sourcesContent":["import type { CapabilityRow, SurfaceView } from \"./model.js\";\nimport type { DiffEntry } from \"../baseline.js\";\nimport { formatValue } from \"../baseline.js\";\n\n/**\n * The no-colour, no-cursor rendering used when stdout is piped or when\n * `--plain`, `CI` or `NO_COLOR` is set. Same view model as the Ink UI, so the\n * two cannot disagree about what the surface contains.\n */\n\nconst MARK = { expose: \"+\", disable: \"~\", hide: \"-\" } as const;\n\nfunction renderRow(row: CapabilityRow, lines: string[]): void {\n const tags = row.tags.length > 0 ? ` [${row.tags.join(\", \")}]` : \"\";\n lines.push(` ${MARK[row.outcome]} ${row.name}${tags}`);\n lines.push(` ${row.description}`);\n if (row.reason) lines.push(` reason: ${row.reason}`);\n\n if (row.policies) {\n if (row.policies.length === 0) {\n lines.push(\" policies: none\");\n } else {\n for (const policy of row.policies) {\n const vote = policy.discovery\n ? policy.discovery.decision === \"disable\"\n ? `disable — ${policy.discovery.reason}`\n : policy.discovery.decision\n : \"no discovery hook\";\n const phases = policy.phases.length > 0 ? policy.phases.join(\"/\") : \"—\";\n const flags = [\n policy.threw ? \"THREW\" : \"\",\n policy.confirmationEscalation ? \"escalates-confirmation\" : \"\",\n ]\n .filter(Boolean)\n .join(\", \");\n lines.push(\n ` policy ${policy.name} (${policy.scope}, ${phases}): ${vote}${\n flags ? ` [${flags}]` : \"\"\n }`,\n );\n }\n }\n if (row.availability && !row.availability.available) {\n lines.push(\n ` availability: unavailable${\n row.availability.reason ? ` — ${row.availability.reason}` : \"\"\n }`,\n );\n }\n }\n\n if (row.schemas) {\n if (row.schemas.input !== undefined) {\n lines.push(` input: ${JSON.stringify(row.schemas.input)}`);\n }\n if (row.schemas.output !== undefined) {\n lines.push(` output: ${JSON.stringify(row.schemas.output)}`);\n }\n }\n}\n\nexport function renderSurfacePlain(view: SurfaceView): string {\n const lines: string[] = [];\n lines.push(`scenario ${view.scenario}${view.route ? ` route ${view.route}` : \"\"}`);\n lines.push(\n `${view.counts.callable} callable, ${view.counts.disabled} visible-disabled${\n view.explained ? `, ${view.counts.hidden} hidden` : \"\"\n }`,\n );\n\n const populated = view.groups.filter((group) => group.rows.length > 0);\n if (populated.length === 0) {\n lines.push(\"\");\n lines.push(\"Nothing is registered for this scenario — the agent has no surface here.\");\n if (!view.explained) {\n lines.push(\"Re-run with --explain to see whether a policy hid it.\");\n }\n return lines.join(\"\\n\");\n }\n\n for (const group of populated) {\n lines.push(\"\");\n lines.push(`${group.heading} (${group.rows.length})`);\n for (const row of group.rows) renderRow(row, lines);\n }\n return lines.join(\"\\n\");\n}\n\nexport function renderDiffPlain(scenario: string, entries: DiffEntry[]): string {\n const lines = [`${scenario}: ${entries.length} change${entries.length === 1 ? \"\" : \"s\"}`];\n for (const entry of entries) {\n const where = entry.subject ? `${entry.subject} (${entry.path})` : entry.path;\n if (entry.kind === \"added\") lines.push(` + ${where} ${formatValue(entry.after)}`);\n else if (entry.kind === \"removed\") lines.push(` - ${where} ${formatValue(entry.before)}`);\n else {\n lines.push(` ~ ${where}`);\n lines.push(` before: ${formatValue(entry.before)}`);\n lines.push(` after: ${formatValue(entry.after)}`);\n }\n }\n return lines.join(\"\\n\");\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/load.ts","../src/output.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { createServer, type ViteDevServer } from \"vite\";\nimport { ViteNodeServer } from \"vite-node/server\";\nimport { ViteNodeRunner } from \"vite-node/client\";\nimport { installSourcemapsSupport } from \"vite-node/source-map\";\nimport type { CollectOptions, CollectResult } from \"./collect.js\";\nimport type { SurfaceConfig } from \"./config.js\";\n\nconst CONFIG_NAMES = [\n \"agent-surface.config.tsx\",\n \"agent-surface.config.ts\",\n \"agent-surface.config.mjs\",\n \"agent-surface.config.js\",\n];\n\n/** Walks up from `from` looking for an `agent-surface.config.*`. */\nexport function findConfig(from: string = process.cwd()): string | undefined {\n let dir = resolve(from);\n for (;;) {\n for (const name of CONFIG_NAMES) {\n const candidate = join(dir, name);\n if (existsSync(candidate)) return candidate;\n }\n const parent = dirname(dir);\n if (parent === dir) return undefined;\n dir = parent;\n }\n}\n\n/** `dist/collect.js` when installed; `src/collect.ts` when run from source. */\nfunction collectorPath(): string {\n for (const ext of [\"js\", \"ts\"]) {\n const candidate = fileURLToPath(new URL(`./collect.${ext}`, import.meta.url));\n if (existsSync(candidate)) return candidate;\n }\n throw new Error(\"could not locate the agent-surface collector module\");\n}\n\nexport interface SurfaceRunner {\n config: SurfaceConfig;\n scenarioNames: string[];\n collect(options: CollectOptions): Promise<CollectResult>;\n close(): Promise<void>;\n}\n\n/**\n * Boots a Vite dev server on the app's own config, so the config file and the\n * app modules it imports are transformed and resolved exactly as the app\n * resolves them — its aliases, its plugins, its TSX.\n */\nexport async function createSurfaceRunner(configPath: string): Promise<SurfaceRunner> {\n const absoluteConfig = isAbsolute(configPath) ? configPath : resolve(configPath);\n if (!existsSync(absoluteConfig)) {\n throw new Error(`config not found: ${absoluteConfig}`);\n }\n const root = dirname(absoluteConfig);\n\n let server: ViteDevServer;\n try {\n server = await createServer({\n root,\n logLevel: \"error\",\n // `serve` so plugins behave as they do in dev; nothing is ever served.\n server: { middlewareMode: true, watch: null, fs: { strict: false } },\n optimizeDeps: { noDiscovery: true, include: [] },\n resolve: {\n // Both halves of the graph must agree on these. React because two\n // copies break hooks; core because `explainSurface` finds the registry\n // through a Symbol, which is per-module-instance (see collect.ts).\n dedupe: [\n \"react\",\n \"react-dom\",\n \"@agent-surface/core\",\n \"@agent-surface/react\",\n \"@agent-surface/testing\",\n ],\n },\n });\n } catch (error) {\n throw new Error(\n `could not start Vite for ${root}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n try {\n await server.pluginContainer.buildStart({});\n } catch {\n // Vite keeps moving this; a plugin that needs buildStart will say so itself.\n }\n\n const nodeServer = new ViteNodeServer(server);\n installSourcemapsSupport({ getSourceMap: (source) => nodeServer.getSourceMap(source) });\n\n const runner = new ViteNodeRunner({\n root: server.config.root,\n base: server.config.base,\n fetchModule: (id) => nodeServer.fetchModule(id),\n resolveId: (id, importer) => nodeServer.resolveId(id, importer),\n });\n\n const close = async (): Promise<void> => {\n await server.close();\n };\n\n try {\n const configModule = (await runner.executeFile(absoluteConfig)) as {\n default?: SurfaceConfig;\n };\n const config = configModule.default;\n if (!config || typeof config.mount !== \"function\") {\n throw new Error(\n `${absoluteConfig} must \\`export default defineSurface({ mount, scenarios })\\``,\n );\n }\n const scenarioNames = Object.keys(config.scenarios ?? {});\n if (scenarioNames.length === 0) {\n throw new Error(`${absoluteConfig} defines no scenarios`);\n }\n\n // Same runner ⇒ same module graph ⇒ the collector shares React and core\n // with the app tree it is about to mount.\n const collector = (await runner.executeFile(collectorPath())) as {\n collect(config: SurfaceConfig, options: CollectOptions): Promise<CollectResult>;\n };\n\n return {\n config,\n scenarioNames,\n collect: async (options) => {\n // Scoped to the mount, never process-wide: `act()` needs it, and Ink\n // renders its own React tree afterwards — with the flag still set,\n // every frame of the CLI's own UI prints React's \"not wrapped in\n // act(...)\" warning at the user.\n const globals = globalThis as Record<string, unknown>;\n const previous = globals[\"IS_REACT_ACT_ENVIRONMENT\"];\n globals[\"IS_REACT_ACT_ENVIRONMENT\"] = true;\n try {\n return await collector.collect(config, options);\n } finally {\n globals[\"IS_REACT_ACT_ENVIRONMENT\"] = previous;\n }\n },\n close,\n };\n } catch (error) {\n await close();\n throw error;\n }\n}\n","import type { ReactElement } from \"react\";\n\nexport interface OutputFlags {\n plain?: boolean;\n json?: boolean;\n}\n\n/**\n * Terminal-aware only when there is a terminal. Piped output, `--plain`, `CI`\n * and `NO_COLOR` all fall back to plain text — a CLI whose output changes shape\n * when redirected is unusable in a build log.\n */\nexport function isPlain(flags: OutputFlags): boolean {\n if (flags.json) return true;\n if (flags.plain) return true;\n if (process.env[\"CI\"]) return true;\n if (process.env[\"NO_COLOR\"]) return true;\n if (process.stdout.isTTY !== true) return true;\n // A TTY that cannot report its width (some CI ptys, `script` on macOS) makes\n // Ink lay out at zero columns and emit one character per line. Plain text is\n // the only honest rendering for a terminal whose size is unknown.\n return !process.stdout.columns;\n}\n\nexport function write(text: string): void {\n process.stdout.write(`${text}\\n`);\n}\n\nexport function writeError(text: string): void {\n process.stderr.write(`${text}\\n`);\n}\n\ntype InkModule = typeof import(\"./render/ink.js\");\n\nlet cached: InkModule | null | undefined;\n\n/**\n * Loads the Ink renderer, or returns `null` when it cannot run here.\n *\n * Two reasons this is lazy rather than a top-level import. It keeps `--plain`\n * and `--json` from paying for a terminal UI they never draw — and Ink drives\n * React through `react-reconciler`, which reads React 19 internals, so a host\n * that pins React 18 globally cannot load it at all. Neither is a reason to\n * fail a command that was about to print text.\n */\nexport async function loadInk(): Promise<InkModule | null> {\n if (cached !== undefined) return cached;\n try {\n cached = await import(\"./render/ink.js\");\n } catch {\n cached = null;\n }\n return cached;\n}\n\n/** Paints an Ink element once and returns when the frame has been flushed. */\nexport async function paint(element: ReactElement): Promise<void> {\n const { render } = await import(\"ink\");\n const instance = render(element);\n instance.unmount();\n await instance.waitUntilExit();\n}\n\n/** A live Ink frame (spinner) that is cleared before the real output lands. */\nexport async function transient(element: ReactElement): Promise<() => void> {\n const { render } = await import(\"ink\");\n const instance = render(element);\n return () => {\n instance.clear();\n instance.unmount();\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/ink-GCWDO4ML.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/render/ink.tsx"],"sourcesContent":["import type { ReactElement } from \"react\";\nimport { Box, Static, Text } from \"ink\";\nimport Spinner from \"ink-spinner\";\nimport type { CapabilityRow, CapabilityGroup, SurfaceView } from \"./model.js\";\nimport type { DiffEntry } from \"../baseline.js\";\nimport { formatValue } from \"../baseline.js\";\n\nconst OUTCOME = {\n expose: { mark: \"●\", color: \"green\" as const },\n disable: { mark: \"◐\", color: \"yellow\" as const },\n hide: { mark: \"○\", color: \"red\" as const },\n};\n\nexport function Loading({ label }: { label: string }): ReactElement {\n return (\n <Text>\n <Text color=\"cyan\">\n <Spinner type=\"dots\" />\n </Text>\n {` ${label}`}\n </Text>\n );\n}\n\nfunction PolicyLine({\n policy,\n}: {\n policy: NonNullable<CapabilityRow[\"policies\"]>[number];\n}): ReactElement {\n const vote = policy.discovery?.decision;\n const color = vote === \"hide\" ? \"red\" : vote === \"disable\" ? \"yellow\" : \"green\";\n return (\n <Box paddingLeft={6}>\n <Text dimColor>policy </Text>\n <Text bold>{policy.name}</Text>\n <Text dimColor>{` (${policy.scope}${policy.phases.length ? `, ${policy.phases.join(\"/\")}` : \"\"}) `}</Text>\n {vote ? (\n <Text color={color}>\n {vote}\n {policy.discovery?.decision === \"disable\" ? ` — ${policy.discovery.reason}` : \"\"}\n </Text>\n ) : (\n <Text dimColor>no discovery hook</Text>\n )}\n {policy.threw ? <Text color=\"red\" bold>{\" THREW\"}</Text> : null}\n {policy.confirmationEscalation ? (\n <Text color=\"magenta\">{\" escalates-confirmation\"}</Text>\n ) : null}\n </Box>\n );\n}\n\nfunction Capability({ row }: { row: CapabilityRow }): ReactElement {\n const outcome = OUTCOME[row.outcome];\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Box>\n <Text color={outcome.color}>{` ${outcome.mark} `}</Text>\n <Text bold>{row.name}</Text>\n {row.tags.length > 0 ? <Text dimColor>{` ${row.tags.join(\" · \")}`}</Text> : null}\n </Box>\n <Box paddingLeft={4}>\n <Text dimColor wrap=\"wrap\">\n {row.description}\n </Text>\n </Box>\n {row.reason ? (\n <Box paddingLeft={4}>\n <Text color=\"yellow\" wrap=\"wrap\">{`⤷ ${row.reason}`}</Text>\n </Box>\n ) : null}\n {row.policies\n ? row.policies.length > 0\n ? row.policies.map((policy, index) => (\n <PolicyLine key={`${policy.name}-${index}`} policy={policy} />\n ))\n : [\n <Box key=\"none\" paddingLeft={6}>\n <Text dimColor>policies: none</Text>\n </Box>,\n ]\n : null}\n {row.policies && row.availability && !row.availability.available ? (\n <Box paddingLeft={6}>\n <Text dimColor>{`availability: unavailable${\n row.availability.reason ? ` — ${row.availability.reason}` : \"\"\n }`}</Text>\n </Box>\n ) : null}\n {row.schemas?.input !== undefined ? (\n <Box paddingLeft={6}>\n <Text dimColor wrap=\"wrap\">{`input: ${JSON.stringify(row.schemas.input)}`}</Text>\n </Box>\n ) : null}\n {row.schemas?.output !== undefined ? (\n <Box paddingLeft={6}>\n <Text dimColor wrap=\"wrap\">{`output: ${JSON.stringify(row.schemas.output)}`}</Text>\n </Box>\n ) : null}\n </Box>\n );\n}\n\nfunction Group({ group }: { group: CapabilityGroup }): ReactElement {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Box>\n <Text backgroundColor=\"blueBright\" color=\"black\" bold>{` ${group.heading} `}</Text>\n <Text dimColor>{` ${group.rows.length}`}</Text>\n </Box>\n {group.rows.map((row) => (\n <Capability key={`${row.capabilityId}-${row.name}`} row={row} />\n ))}\n </Box>\n );\n}\n\nfunction Header({ view }: { view: SurfaceView }): ReactElement {\n return (\n <Box>\n <Text bold>{view.scenario}</Text>\n {view.route ? <Text dimColor>{` ${view.route}`}</Text> : null}\n <Text dimColor>{\" · \"}</Text>\n <Text color=\"green\">{`${view.counts.callable} callable`}</Text>\n <Text dimColor>{\", \"}</Text>\n <Text color=\"yellow\">{`${view.counts.disabled} visible-disabled`}</Text>\n {view.explained ? (\n <>\n <Text dimColor>{\", \"}</Text>\n <Text color=\"red\">{`${view.counts.hidden} hidden`}</Text>\n </>\n ) : null}\n </Box>\n );\n}\n\nfunction Empty({ view }: { view: SurfaceView }): ReactElement {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text dimColor wrap=\"wrap\">\n Nothing is registered for this scenario — the agent has no surface here. That is the\n default: capabilities exist only where they were explicitly annotated.\n </Text>\n {view.explained ? null : (\n <Text dimColor>Re-run with --explain to see whether a policy hid it.</Text>\n )}\n </Box>\n );\n}\n\ntype Block = { key: string; group?: CapabilityGroup };\n\nexport function Surface({ view }: { view: SurfaceView }): ReactElement {\n const populated = view.groups.filter((group) => group.rows.length > 0);\n\n // Everything goes through <Static>, header included. Ink paints static output\n // once, permanently, above the live frame — and erases the live frame on\n // unmount. A one-shot render that leaves anything outside <Static> therefore\n // prints it and then wipes it, which is exactly what happened to this header.\n const blocks: Block[] = [\n { key: \"__header\" },\n ...populated.map((group) => ({ key: group.heading, group })),\n ];\n\n return (\n <Static items={blocks}>\n {(block) =>\n block.group ? (\n <Group key={block.key} group={block.group} />\n ) : (\n <Box key={block.key} flexDirection=\"column\">\n <Header view={view} />\n {populated.length === 0 ? <Empty view={view} /> : null}\n </Box>\n )\n }\n </Static>\n );\n}\n\nexport function Drift({\n scenario,\n entries,\n}: {\n scenario: string;\n entries: DiffEntry[];\n}): ReactElement {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Box>\n <Text backgroundColor=\"yellow\" color=\"black\" bold>{` ${scenario} `}</Text>\n <Text dimColor>{` ${entries.length} change${entries.length === 1 ? \"\" : \"s\"}`}</Text>\n </Box>\n {entries.map((entry) => (\n <Box key={`${entry.kind}-${entry.path}`} flexDirection=\"column\" paddingLeft={2}>\n {entry.subject ? (\n <Text bold>\n {entry.subject}\n <Text dimColor>{` ${entry.path}`}</Text>\n </Text>\n ) : null}\n {entry.kind === \"added\" ? (\n <Text color=\"green\" wrap=\"wrap\">{`+ ${entry.path} ${formatValue(entry.after)}`}</Text>\n ) : entry.kind === \"removed\" ? (\n <Text color=\"red\" wrap=\"wrap\">{`- ${entry.path} ${formatValue(entry.before)}`}</Text>\n ) : (\n <>\n <Text color=\"yellow\">{`~ ${entry.path}`}</Text>\n <Text color=\"red\" wrap=\"wrap\">{` before: ${formatValue(entry.before)}`}</Text>\n <Text color=\"green\" wrap=\"wrap\">{` after: ${formatValue(entry.after)}`}</Text>\n </>\n )}\n </Box>\n ))}\n </Box>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
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":[]}
|