@agent-surface/cli 0.12.1 → 0.13.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 +44 -6
- package/dist/bin.js +5 -5
- package/dist/{check-POE5VRSE.js → check-TJIX7NDE.js} +111 -53
- package/dist/check-TJIX7NDE.js.map +1 -0
- package/dist/{chunk-QIVOZAWX.js → chunk-3AJ343NA.js} +12 -3
- package/dist/{chunk-QIVOZAWX.js.map → chunk-3AJ343NA.js.map} +1 -1
- package/dist/chunk-IALBMW3R.js +278 -0
- package/dist/chunk-IALBMW3R.js.map +1 -0
- package/dist/{chunk-J2NN3J5N.js → chunk-L7GHSC2Z.js} +146 -222
- package/dist/chunk-L7GHSC2Z.js.map +1 -0
- package/dist/{chunk-Q5WOLWEW.js → chunk-UGCLJ5JX.js} +26 -286
- package/dist/chunk-UGCLJ5JX.js.map +1 -0
- package/dist/chunk-VX6GBEP3.js +539 -0
- package/dist/chunk-VX6GBEP3.js.map +1 -0
- package/dist/{init-LFQ5R3G7.js → init-6XV64LK2.js} +9 -8
- package/dist/{init-LFQ5R3G7.js.map → init-6XV64LK2.js.map} +1 -1
- package/dist/{ink-P23VKP4H.js → ink-QR7X7TAC.js} +99 -25
- package/dist/ink-QR7X7TAC.js.map +1 -0
- package/dist/inspect-NJ4J3MPP.js +242 -0
- package/dist/inspect-NJ4J3MPP.js.map +1 -0
- package/dist/{snapshot-FLXE5UC6.js → snapshot-ZGTAF2Y5.js} +28 -12
- package/dist/snapshot-ZGTAF2Y5.js.map +1 -0
- package/package.json +4 -4
- package/dist/check-POE5VRSE.js.map +0 -1
- package/dist/chunk-DYDSJM7R.js +0 -170
- package/dist/chunk-DYDSJM7R.js.map +0 -1
- package/dist/chunk-J2NN3J5N.js.map +0 -1
- package/dist/chunk-Q5WOLWEW.js.map +0 -1
- package/dist/ink-P23VKP4H.js.map +0 -1
- package/dist/inspect-XMDZBSK2.js +0 -119
- package/dist/inspect-XMDZBSK2.js.map +0 -1
- package/dist/snapshot-FLXE5UC6.js.map +0 -1
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
-
renderCoveragePlain,
|
|
3
2
|
renderFailuresPlain,
|
|
3
|
+
renderSurfaceSummaryPlain,
|
|
4
4
|
scenarioBaseline
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import
|
|
5
|
+
} from "./chunk-L7GHSC2Z.js";
|
|
6
|
+
import {
|
|
7
|
+
buildView,
|
|
8
|
+
displayPath,
|
|
9
|
+
flatRows,
|
|
10
|
+
scenarioStats,
|
|
11
|
+
trackReach
|
|
12
|
+
} from "./chunk-VX6GBEP3.js";
|
|
7
13
|
import {
|
|
8
14
|
baselinePath,
|
|
9
15
|
joinCoverage,
|
|
@@ -11,15 +17,15 @@ import {
|
|
|
11
17
|
readInventory,
|
|
12
18
|
writeBaseline,
|
|
13
19
|
writeScenarioManifest
|
|
14
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-IALBMW3R.js";
|
|
15
21
|
import {
|
|
16
22
|
UsageError,
|
|
17
23
|
write,
|
|
18
24
|
writeError
|
|
19
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-3AJ343NA.js";
|
|
26
|
+
import "./chunk-UGCLJ5JX.js";
|
|
20
27
|
|
|
21
28
|
// src/commands/snapshot.ts
|
|
22
|
-
import { relative } from "path";
|
|
23
29
|
async function runSnapshot(options) {
|
|
24
30
|
if (options.depth === "static") {
|
|
25
31
|
throw new UsageError(
|
|
@@ -40,14 +46,24 @@ async function runSnapshot(options) {
|
|
|
40
46
|
for (const result of runtime.results) {
|
|
41
47
|
const path = baselinePath(runtime.baselineDir, result.scenario);
|
|
42
48
|
writeBaseline(path, scenarioBaseline(result));
|
|
43
|
-
write(`wrote ${
|
|
49
|
+
write(`wrote ${displayPath(path)}`);
|
|
44
50
|
}
|
|
45
51
|
writeScenarioManifest(runtime.baselineDir, runtime.declaredScenarios);
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
write(renderCoveragePlain(coverage));
|
|
52
|
+
const reach = /* @__PURE__ */ new Map();
|
|
53
|
+
for (const result of runtime.results) {
|
|
54
|
+
trackReach(reach, flatRows(buildView(result)), result.scenario);
|
|
50
55
|
}
|
|
56
|
+
const coverage = joinCoverage(inventory, runtime, analysis);
|
|
57
|
+
write("");
|
|
58
|
+
write(
|
|
59
|
+
renderSurfaceSummaryPlain({
|
|
60
|
+
depth: options.depth,
|
|
61
|
+
...coverage ? { coverage } : {},
|
|
62
|
+
scenarios: runtime.results.map(scenarioStats),
|
|
63
|
+
failures: runtime.failures.length,
|
|
64
|
+
reach
|
|
65
|
+
})
|
|
66
|
+
);
|
|
51
67
|
if (runtime.failures.length > 0) {
|
|
52
68
|
writeError(`
|
|
53
69
|
${renderFailuresPlain(runtime.failures)}`);
|
|
@@ -58,4 +74,4 @@ ${renderFailuresPlain(runtime.failures)}`);
|
|
|
58
74
|
export {
|
|
59
75
|
runSnapshot
|
|
60
76
|
};
|
|
61
|
-
//# sourceMappingURL=snapshot-
|
|
77
|
+
//# sourceMappingURL=snapshot-ZGTAF2Y5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/snapshot.ts"],"sourcesContent":["import {\n joinCoverage,\n mountScenarios,\n readInventory,\n UsageError,\n type AnalysisOptions,\n type Depth,\n} from \"../analysis.js\";\nimport { baselinePath, writeBaseline, writeScenarioManifest } from \"../baseline.js\";\nimport { scenarioBaseline } from \"../report.js\";\nimport { buildView, flatRows } from \"../render/model.js\";\nimport { renderFailuresPlain, renderSurfaceSummaryPlain } from \"../render/plain.js\";\nimport {\n displayPath,\n scenarioStats,\n trackReach,\n type CapabilityReach,\n} from \"../render/summary.js\";\nimport { write, writeError } from \"../output.js\";\n\nexport interface SnapshotOptions {\n configPath: string;\n depth: Depth;\n scenario?: string;\n scope?: string[];\n tsconfig?: string;\n baselineDir?: string;\n}\n\n/**\n * Writes (or refreshes) the committed baseline `check` compares against.\n *\n * It prints the coverage verdict too. This is the command you run to *accept* a\n * change to the surface, which makes it the last moment before a reviewer sees\n * the diff — and accepting a projection while a capability sits behind a route\n * no scenario visits is exactly the state worth hearing about. It reports;\n * `check` is still the only thing that fails.\n */\nexport async function runSnapshot(options: SnapshotOptions): Promise<number> {\n if (options.depth === \"static\") {\n throw new UsageError(\n \"snapshot --depth static has nothing to write — a baseline is a projection, and \" +\n \"at this depth nothing is mounted.\",\n );\n }\n\n const analysis: AnalysisOptions = {\n configPath: options.configPath,\n depth: options.depth,\n ...(options.scenario ? { scenario: options.scenario } : {}),\n ...(options.scope ? { scope: options.scope } : {}),\n ...(options.tsconfig ? { tsconfig: options.tsconfig } : {}),\n ...(options.baselineDir ? { baselineDir: options.baselineDir } : {}),\n };\n\n const inventory = readInventory(analysis);\n const runtime = await mountScenarios(analysis);\n if (!runtime) throw new UsageError(\"snapshot needs a mount, and this depth performs none\");\n\n for (const result of runtime.results) {\n const path = baselinePath(runtime.baselineDir, result.scenario);\n writeBaseline(path, scenarioBaseline(result));\n write(`wrote ${displayPath(path)}`);\n }\n writeScenarioManifest(runtime.baselineDir, runtime.declaredScenarios);\n\n const reach = new Map<string, CapabilityReach>();\n for (const result of runtime.results) {\n trackReach(reach, flatRows(buildView(result)), result.scenario);\n }\n const coverage = joinCoverage(inventory, runtime, analysis);\n write(\"\");\n write(\n renderSurfaceSummaryPlain({\n depth: options.depth,\n ...(coverage ? { coverage } : {}),\n scenarios: runtime.results.map(scenarioStats),\n failures: runtime.failures.length,\n reach,\n }),\n );\n\n if (runtime.failures.length > 0) {\n // A baseline written for some scenarios and not others is a baseline that\n // will fail `check` for a reason that has nothing to do with the surface.\n writeError(`\\n${renderFailuresPlain(runtime.failures)}`);\n return 2;\n }\n return 0;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA,eAAsB,YAAY,SAA2C;AAC3E,MAAI,QAAQ,UAAU,UAAU;AAC9B,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AAEA,QAAM,WAA4B;AAAA,IAChC,YAAY,QAAQ;AAAA,IACpB,OAAO,QAAQ;AAAA,IACf,GAAI,QAAQ,WAAW,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,IACzD,GAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,IAChD,GAAI,QAAQ,WAAW,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,IACzD,GAAI,QAAQ,cAAc,EAAE,aAAa,QAAQ,YAAY,IAAI,CAAC;AAAA,EACpE;AAEA,QAAM,YAAY,cAAc,QAAQ;AACxC,QAAM,UAAU,MAAM,eAAe,QAAQ;AAC7C,MAAI,CAAC,QAAS,OAAM,IAAI,WAAW,sDAAsD;AAEzF,aAAW,UAAU,QAAQ,SAAS;AACpC,UAAM,OAAO,aAAa,QAAQ,aAAa,OAAO,QAAQ;AAC9D,kBAAc,MAAM,iBAAiB,MAAM,CAAC;AAC5C,UAAM,SAAS,YAAY,IAAI,CAAC,EAAE;AAAA,EACpC;AACA,wBAAsB,QAAQ,aAAa,QAAQ,iBAAiB;AAEpE,QAAM,QAAQ,oBAAI,IAA6B;AAC/C,aAAW,UAAU,QAAQ,SAAS;AACpC,eAAW,OAAO,SAAS,UAAU,MAAM,CAAC,GAAG,OAAO,QAAQ;AAAA,EAChE;AACA,QAAM,WAAW,aAAa,WAAW,SAAS,QAAQ;AAC1D,QAAM,EAAE;AACR;AAAA,IACE,0BAA0B;AAAA,MACxB,OAAO,QAAQ;AAAA,MACf,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,MAC/B,WAAW,QAAQ,QAAQ,IAAI,aAAa;AAAA,MAC5C,UAAU,QAAQ,SAAS;AAAA,MAC3B;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,SAAS,SAAS,GAAG;AAG/B,eAAW;AAAA,EAAK,oBAAoB,QAAQ,QAAQ,CAAC,EAAE;AACvD,WAAO;AAAA,EACT;AACA,SAAO;AACT;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-surface/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.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",
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"typescript": "^5.9.2",
|
|
32
32
|
"vite": "^7.1.3",
|
|
33
33
|
"vite-node": "^3.2.4",
|
|
34
|
-
"@agent-surface/
|
|
35
|
-
"@agent-surface/
|
|
36
|
-
"@agent-surface/testing": "^0.
|
|
34
|
+
"@agent-surface/react": "^0.13.0",
|
|
35
|
+
"@agent-surface/core": "^0.13.0",
|
|
36
|
+
"@agent-surface/testing": "^0.13.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@testing-library/react": ">=14",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/check.ts"],"sourcesContent":["import { existsSync, readdirSync } from \"node:fs\";\nimport { relative } from \"node:path\";\nimport {\n UsageError,\n joinCoverage,\n mountScenarios,\n readInventory,\n type AnalysisOptions,\n type Depth,\n} from \"../analysis.js\";\nimport {\n annotate,\n baselinePath,\n diff,\n readBaseline,\n readScenarioManifest,\n SCENARIO_MANIFEST_FILE,\n type DiffEntry,\n} from \"../baseline.js\";\nimport { ALLOWLIST_FILE, coverageExitCode, UNREAD_ALLOWLIST_FILE } from \"../coverage.js\";\nimport {\n renderCoveragePlain,\n renderCheckOverviewPlain,\n renderDriftPlain,\n renderFailuresPlain,\n renderNoVerdictPlain,\n} from \"../render/plain.js\";\nimport { write, writeError } from \"../output.js\";\nimport { coverageReport, scenarioBaseline } from \"../report.js\";\n\nexport interface CheckOptions {\n configPath: string;\n depth: Depth;\n scenario?: string;\n scope?: string[];\n tsconfig?: string;\n baselineDir?: string;\n allowUnresolved?: boolean;\n json?: boolean;\n plain?: boolean;\n detail?: boolean;\n}\n\ninterface ScenarioDrift {\n scenario: string;\n missingBaseline?: boolean;\n entries: DiffEntry[];\n}\n\ninterface RejectedScenario {\n scenario: string;\n rejections: Array<{ componentType: string; instanceId: string; reason: string }>;\n}\n\n/**\n * The gate. The only command in this package that fails on a finding, which is\n * why every finding has to reach it.\n *\n * It used to fail on exactly one class — the projection drifting from its\n * baseline — and print a line telling you that capabilities no scenario mounts\n * were a different command's question. A gate that names the check it is not\n * performing is a gate with a hole in it, and in CI the hole was silent: a\n * whole unreached route sat behind a green tick.\n *\n * So it now fails on every incomplete or changed report:\n *\n * - **drift** — the surface changed against its committed baseline;\n * - **a missing baseline** — nothing to compare, which is not the same as a match;\n * - **an unreached capability** — authored, and no scenario mounts it;\n * - **an unread call site** — the catalog is incomplete, so the third check\n * above is computed over a denominator that is only a floor;\n * - **a rejected registration** — authored surface was refused;\n * - **scenario drift** — config, manifest and baseline files disagree.\n *\n * `.agent-surface/coverage-allow.json` ratchets the third; `--allow-unresolved`\n * accepts the fourth. Both are deliberate, committed decisions rather than\n * flags that quietly widen the gate.\n *\n * Output is always plain, with no rendering framework in its path at all: this\n * is a report that gets pasted into a pull request and read out of a CI log,\n * and neither of those is a terminal.\n */\nexport async function runCheck(options: CheckOptions): Promise<number> {\n if (options.depth === \"static\") {\n throw new UsageError(\n \"check --depth static has nothing to compare — a baseline is a projection, and \" +\n \"at this depth nothing is mounted. Use --depth runtime for drift alone, or full for both.\",\n );\n }\n\n const analysis: AnalysisOptions = {\n configPath: options.configPath,\n depth: options.depth,\n ...(options.scenario ? { scenario: options.scenario } : {}),\n ...(options.scope ? { scope: options.scope } : {}),\n ...(options.tsconfig ? { tsconfig: options.tsconfig } : {}),\n ...(options.baselineDir ? { baselineDir: options.baselineDir } : {}),\n };\n\n const inventory = readInventory(analysis);\n // No streaming here, unlike `inspect`. A report is read top-down and has to\n // lead with its findings, which means every finding has to exist first.\n const runtime = await mountScenarios(analysis);\n if (!runtime) throw new UsageError(\"check needs a mount, and this depth performs none\");\n\n const drifted: ScenarioDrift[] = [];\n for (const result of runtime.results) {\n const path = baselinePath(runtime.baselineDir, result.scenario);\n const expected = readBaseline(path);\n if (expected === undefined) {\n drifted.push({ scenario: result.scenario, missingBaseline: true, entries: [] });\n continue;\n }\n const actual = scenarioBaseline(result);\n const entries = annotate(diff(expected, actual), actual, expected);\n if (entries.length > 0) drifted.push({ scenario: result.scenario, entries });\n }\n\n const committedScenarios = readScenarioManifest(runtime.baselineDir);\n const declared = [...runtime.declaredScenarios].sort();\n const scenarioManifestMismatch =\n committedScenarios === undefined ||\n JSON.stringify(committedScenarios) !== JSON.stringify(declared);\n const reserved = new Set([SCENARIO_MANIFEST_FILE, ALLOWLIST_FILE, UNREAD_ALLOWLIST_FILE]);\n const staleBaselineFiles = (existsSync(runtime.baselineDir)\n ? readdirSync(runtime.baselineDir, { withFileTypes: true })\n : [])\n .filter((entry) => entry.isFile() && entry.name.endsWith(\".json\") && !reserved.has(entry.name))\n .map((entry) => entry.name.slice(0, -5))\n .filter((scenario) => !runtime.declaredScenarios.includes(scenario))\n .sort();\n\n const rejected: RejectedScenario[] = runtime.results\n .filter((result) => result.rejections.length > 0)\n .map((result) => ({ scenario: result.scenario, rejections: result.rejections }));\n\n const coverage = joinCoverage(inventory, runtime, analysis);\n const coverageFailed =\n coverage !== undefined &&\n coverageExitCode(coverage, { allowUnresolved: options.allowUnresolved === true }) !== 0;\n const couldNotRun = runtime.failures.length > 0;\n const ok =\n drifted.length === 0 &&\n !coverageFailed &&\n !couldNotRun &&\n rejected.length === 0 &&\n !scenarioManifestMismatch &&\n staleBaselineFiles.length === 0;\n\n if (options.json) {\n write(\n JSON.stringify(\n {\n ok,\n drifted,\n failures: runtime.failures,\n rejected,\n scenarioManifest: {\n expected: declared,\n committed: committedScenarios ?? null,\n staleBaselines: staleBaselineFiles,\n },\n coverage: coverageReport(coverage),\n },\n null,\n 2,\n ),\n );\n return couldNotRun ? 2 : ok ? 0 : 1;\n }\n\n const overview = renderCheckOverviewPlain({\n status: couldNotRun ? \"ERROR\" : ok ? \"PASS\" : \"FAIL\",\n ...(coverage ? { coverage } : {}),\n unresolvedAllowed: options.allowUnresolved === true,\n baselineCurrent: Math.max(0, runtime.results.length - drifted.length),\n baselineTotal: runtime.scenarios.length,\n scenarioManifestOk: !scenarioManifestMismatch && staleBaselineFiles.length === 0,\n rejected: rejected.reduce((sum, entry) => sum + entry.rejections.length, 0),\n mountFailures: runtime.failures.length,\n scenarios: runtime.scenarios,\n });\n if (ok) write(overview);\n else writeError(overview);\n\n // The gap leads, because it is the finding this command could not previously\n // make at all. Drift follows, because it is the one it always could.\n if (coverage) {\n const rendered = renderCoveragePlain(coverage, {\n compact: true,\n ...(options.detail ? { detail: true } : {}),\n });\n if (rendered) {\n if (coverageFailed) writeError(`\\n${rendered}`);\n else write(`\\n${rendered}`);\n }\n }\n\n // \"No baseline\" is not drift, and filing it under a heading that says the\n // surface changed would be a claim about a comparison that never happened.\n const missing = drifted.filter((entry) => entry.missingBaseline);\n const changed = drifted.filter((entry) => !entry.missingBaseline);\n\n if (rejected.length > 0) {\n writeError(\n [\n `${coverage ? \"\\n\" : \"\"}REJECTED REGISTRATIONS — the runtime refused authored surface (${rejected.reduce((sum, entry) => sum + entry.rejections.length, 0)})`,\n ...rejected.flatMap((entry) =>\n entry.rejections.map(\n (rejection) =>\n ` ${entry.scenario}: ${rejection.componentType}@${rejection.instanceId} (${rejection.reason})`,\n ),\n ),\n ].join(\"\\n\"),\n );\n }\n\n if (scenarioManifestMismatch || staleBaselineFiles.length > 0) {\n const committed = committedScenarios?.join(\", \") ?? \"missing\";\n writeError(\n [\n `${coverage || rejected.length > 0 ? \"\\n\" : \"\"}SCENARIO DRIFT — committed baselines do not match config`,\n ` config: ${declared.join(\", \")}`,\n ` manifest: ${committed}`,\n ...(staleBaselineFiles.length > 0\n ? [` stale baselines: ${staleBaselineFiles.join(\", \")}`]\n : []),\n \" run `agent-surface snapshot` and commit the manifest\",\n ].join(\"\\n\"),\n );\n }\n\n if (missing.length > 0) {\n writeError(\n [\n `${coverage ? \"\\n\" : \"\"}NO BASELINE — nothing to compare against, which is not the same as a match (${missing.length})`,\n ...missing.map(\n (entry) =>\n ` ${entry.scenario}: ${relative(\n process.cwd(),\n baselinePath(runtime.baselineDir, entry.scenario),\n )} does not exist — run \\`agent-surface snapshot\\` and commit it`,\n ),\n ].join(\"\\n\"),\n );\n }\n\n if (changed.length > 0) {\n writeError(\n [\n `${coverage || missing.length > 0 ? \"\\n\" : \"\"}DRIFT — the surface changed against its baseline (${changed.length})`,\n ...changed.map((entry) => renderDriftPlain(entry.scenario, entry.entries)),\n \"\",\n `surface drift in ${changed.length} scenario${\n changed.length === 1 ? \"\" : \"s\"\n } — review the change, then \\`agent-surface snapshot\\` to accept it`,\n ].join(\"\\n\"),\n );\n }\n\n if (couldNotRun) {\n writeError(`\\n${renderFailuresPlain(runtime.failures)}`);\n if (inventory) writeError(`\\n${renderNoVerdictPlain(runtime.failures)}`);\n return 2;\n }\n\n if (ok) {\n return 0;\n }\n return 1;\n}\n"],"mappings":"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","names":[]}
|
package/dist/chunk-DYDSJM7R.js
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
// src/render/model.ts
|
|
2
|
-
function flatRows(view) {
|
|
3
|
-
return view.groups.flatMap((group) => group.rows);
|
|
4
|
-
}
|
|
5
|
-
function pathOf(capabilityId) {
|
|
6
|
-
return capabilityId.replace(/^(view|domain):/, "");
|
|
7
|
-
}
|
|
8
|
-
function leafOf(capabilityId) {
|
|
9
|
-
const withoutPlane = pathOf(capabilityId);
|
|
10
|
-
const dot = withoutPlane.lastIndexOf(".");
|
|
11
|
-
return dot === -1 ? withoutPlane : withoutPlane.slice(dot + 1);
|
|
12
|
-
}
|
|
13
|
-
function actionFlags(action) {
|
|
14
|
-
const flags = [];
|
|
15
|
-
if (action.idempotent) flags.push("idempotent");
|
|
16
|
-
if (action.reversible) flags.push("reversible");
|
|
17
|
-
if (action.confirmation !== "never") flags.push(`confirmation:${action.confirmation}`);
|
|
18
|
-
return flags;
|
|
19
|
-
}
|
|
20
|
-
function procedureFlags(procedure) {
|
|
21
|
-
const flags = [];
|
|
22
|
-
if (procedure.confirmation !== "never") flags.push(`confirmation:${procedure.confirmation}`);
|
|
23
|
-
for (const field of procedure.boundFields) {
|
|
24
|
-
flags.push(`${field.path} bound${field.locked ? "+locked" : ""}`);
|
|
25
|
-
}
|
|
26
|
-
return flags;
|
|
27
|
-
}
|
|
28
|
-
function explanationIndex(explanation) {
|
|
29
|
-
const index = /* @__PURE__ */ new Map();
|
|
30
|
-
for (const capability of explanation.capabilities) {
|
|
31
|
-
index.set(`${capability.capabilityId}\0${capability.registrationId}`, capability);
|
|
32
|
-
}
|
|
33
|
-
return index;
|
|
34
|
-
}
|
|
35
|
-
function buildView(result, options = {}) {
|
|
36
|
-
const { snapshot, explanation } = result;
|
|
37
|
-
const index = explanationIndex(explanation);
|
|
38
|
-
const groups = [];
|
|
39
|
-
const counts = { callable: 0, disabled: 0, hidden: 0 };
|
|
40
|
-
const enrich = (row, capabilityId, registrationId) => {
|
|
41
|
-
const explained = index.get(`${capabilityId}\0${registrationId}`);
|
|
42
|
-
if (options.explain && explained) {
|
|
43
|
-
row.policies = explained.policies;
|
|
44
|
-
row.availability = explained.availability;
|
|
45
|
-
}
|
|
46
|
-
return row;
|
|
47
|
-
};
|
|
48
|
-
for (const component of snapshot.components) {
|
|
49
|
-
const rows = [];
|
|
50
|
-
for (const observation of component.observations) {
|
|
51
|
-
rows.push(
|
|
52
|
-
enrich(
|
|
53
|
-
rowFor(observation, "observation", void 0, [], options, {
|
|
54
|
-
input: void 0,
|
|
55
|
-
output: observation.outputSchema
|
|
56
|
-
}),
|
|
57
|
-
observation.capabilityId,
|
|
58
|
-
component.registrationId
|
|
59
|
-
)
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
for (const action of component.actions) {
|
|
63
|
-
rows.push(
|
|
64
|
-
enrich(
|
|
65
|
-
rowFor(action, "action", action.effect, actionFlags(action), options, {
|
|
66
|
-
input: action.inputSchema,
|
|
67
|
-
output: action.outputSchema
|
|
68
|
-
}),
|
|
69
|
-
action.capabilityId,
|
|
70
|
-
component.registrationId
|
|
71
|
-
)
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
groups.push({
|
|
75
|
-
heading: component.instanceId === "default" ? component.type : `${component.type}@${component.instanceId}`,
|
|
76
|
-
rows
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
if (snapshot.procedures.length > 0) {
|
|
80
|
-
groups.push({
|
|
81
|
-
heading: "authoritative (domain)",
|
|
82
|
-
rows: snapshot.procedures.map(
|
|
83
|
-
(procedure) => enrich(
|
|
84
|
-
{
|
|
85
|
-
capabilityId: procedure.procedureId,
|
|
86
|
-
name: procedure.procedureId.replace(/^domain:/, ""),
|
|
87
|
-
path: pathOf(procedure.procedureId),
|
|
88
|
-
kind: "procedure",
|
|
89
|
-
plane: "domain",
|
|
90
|
-
outcome: procedure.available ? "expose" : "disable",
|
|
91
|
-
description: procedure.description,
|
|
92
|
-
...procedure.unavailableReason ? { reason: procedure.unavailableReason } : {},
|
|
93
|
-
effect: procedure.effect,
|
|
94
|
-
flags: procedureFlags(procedure),
|
|
95
|
-
tags: [procedure.effect, ...procedureFlags(procedure)],
|
|
96
|
-
...options.schemas ? { schemas: { input: procedure.inputSchema, output: procedure.outputSchema } } : {}
|
|
97
|
-
},
|
|
98
|
-
procedure.procedureId,
|
|
99
|
-
procedure.registrationId
|
|
100
|
-
)
|
|
101
|
-
)
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
const hidden = explanation.capabilities.filter((c) => c.outcome === "hide");
|
|
105
|
-
if (hidden.length > 0) {
|
|
106
|
-
groups.push({
|
|
107
|
-
heading: "hidden by policy (absent from the snapshot)",
|
|
108
|
-
rows: hidden.map((capability) => ({
|
|
109
|
-
capabilityId: capability.capabilityId,
|
|
110
|
-
name: leafOf(capability.capabilityId),
|
|
111
|
-
path: pathOf(capability.capabilityId),
|
|
112
|
-
kind: capability.kind,
|
|
113
|
-
plane: capability.plane,
|
|
114
|
-
outcome: "hide",
|
|
115
|
-
description: capability.description,
|
|
116
|
-
// No reason line, deliberately. The reason a hidden capability carries
|
|
117
|
-
// is its *availability* reason — "The drawer is not open" — and printing
|
|
118
|
-
// that under a row marked `hidden` says the UI declined when authority
|
|
119
|
-
// did. Authority hides, state discloses (D11/D12), and the two must
|
|
120
|
-
// never look alike. Why it was hidden is a policy question, which is
|
|
121
|
-
// what `--explain` answers.
|
|
122
|
-
//
|
|
123
|
-
// A hidden capability has no snapshot entry, so there is no effect to
|
|
124
|
-
// report — the table prints an em dash rather than inventing one. The
|
|
125
|
-
// capability path already carries the component type; only a non-default
|
|
126
|
-
// instance adds anything.
|
|
127
|
-
flags: capability.component.instanceId === "default" ? [] : [`@${capability.component.instanceId}`],
|
|
128
|
-
tags: [`${capability.component.type}@${capability.component.instanceId}`],
|
|
129
|
-
...options.explain ? { policies: capability.policies, availability: capability.availability } : {}
|
|
130
|
-
}))
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
for (const capability of explanation.capabilities) {
|
|
134
|
-
if (capability.outcome === "expose") counts.callable += 1;
|
|
135
|
-
else if (capability.outcome === "disable") counts.disabled += 1;
|
|
136
|
-
else counts.hidden += 1;
|
|
137
|
-
}
|
|
138
|
-
return {
|
|
139
|
-
scenario: result.scenario,
|
|
140
|
-
...snapshot.route?.path ? { route: snapshot.route.path } : {},
|
|
141
|
-
...result.scope ? { scope: result.scope } : {},
|
|
142
|
-
groups,
|
|
143
|
-
counts,
|
|
144
|
-
rejections: result.rejections ?? [],
|
|
145
|
-
explained: options.explain === true
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
function rowFor(descriptor, kind, effect, flags, options, schemas) {
|
|
149
|
-
return {
|
|
150
|
-
capabilityId: descriptor.capabilityId,
|
|
151
|
-
name: descriptor.name,
|
|
152
|
-
path: pathOf(descriptor.capabilityId),
|
|
153
|
-
kind,
|
|
154
|
-
plane: "view",
|
|
155
|
-
outcome: descriptor.available ? "expose" : "disable",
|
|
156
|
-
description: descriptor.description,
|
|
157
|
-
...descriptor.unavailableReason ? { reason: descriptor.unavailableReason } : {},
|
|
158
|
-
...effect ? { effect } : {},
|
|
159
|
-
flags,
|
|
160
|
-
// The grouped detail view prints one combined list, the way it always has.
|
|
161
|
-
tags: effect ? [effect, ...flags] : [kind, ...flags],
|
|
162
|
-
...options.schemas ? { schemas } : {}
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
export {
|
|
167
|
-
flatRows,
|
|
168
|
-
buildView
|
|
169
|
-
};
|
|
170
|
-
//# sourceMappingURL=chunk-DYDSJM7R.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/render/model.ts"],"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, RegistrationRejection } 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 /**\n * The id minus its plane prefix. The table is flat, so its first column has\n * to carry the whole path; the grouped detail view uses `name`.\n */\n path: string;\n kind: \"observation\" | \"action\" | \"procedure\";\n plane: \"view\" | \"domain\";\n outcome: \"expose\" | \"disable\" | \"hide\";\n description: string;\n reason?: string;\n /** The effect, alone, for the table's own column. Observations have none. */\n effect?: string;\n /** What is left of `tags` once the effect has its own column. */\n flags: string[];\n /** Effect and flags together — what the grouped detail view prints. */\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 /**\n * The scope the counts below were computed under (`AS-CLI-007`). A scope\n * filters the snapshot *and* the explanation, so without it on screen the\n * header reads as a statement about the whole surface when it is a statement\n * about one prefix of it.\n */\n scope?: string[];\n groups: CapabilityGroup[];\n counts: { callable: number; disabled: number; hidden: number };\n /** Refused during the mount — absent from both projections (`AS-CLI-006`). */\n rejections: RegistrationRejection[];\n explained: boolean;\n}\n\nexport interface ViewOptions {\n explain?: boolean;\n schemas?: boolean;\n}\n\n/**\n * The table is flat — `groups` exist for the grouped detail view, which is what\n * `--detail`, `--explain` and `--schemas` render. Flattening here rather than in\n * each renderer keeps the two views over one order.\n */\nexport function flatRows(view: SurfaceView): CapabilityRow[] {\n return view.groups.flatMap((group) => group.rows);\n}\n\nfunction pathOf(capabilityId: string): string {\n return capabilityId.replace(/^(view|domain):/, \"\");\n}\n\nfunction leafOf(capabilityId: string): string {\n const withoutPlane = pathOf(capabilityId);\n const dot = withoutPlane.lastIndexOf(\".\");\n return dot === -1 ? withoutPlane : withoutPlane.slice(dot + 1);\n}\n\n/**\n * The effect gets its own table column; everything else is a flag. An\n * observation reads state and has no effect at all, which the table shows as\n * an em dash rather than inventing one.\n */\nfunction actionFlags(action: AgentActionDescriptor): string[] {\n const flags: string[] = [];\n if (action.idempotent) flags.push(\"idempotent\");\n if (action.reversible) flags.push(\"reversible\");\n if (action.confirmation !== \"never\") flags.push(`confirmation:${action.confirmation}`);\n return flags;\n}\n\nfunction procedureFlags(procedure: AgentProcedureDescriptor): string[] {\n const flags: string[] = [];\n if (procedure.confirmation !== \"never\") flags.push(`confirmation:${procedure.confirmation}`);\n for (const field of procedure.boundFields) {\n flags.push(`${field.path} bound${field.locked ? \"+locked\" : \"\"}`);\n }\n return flags;\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\", undefined, [], 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\", action.effect, actionFlags(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 path: pathOf(procedure.procedureId),\n kind: \"procedure\",\n plane: \"domain\",\n outcome: procedure.available ? \"expose\" : \"disable\",\n description: procedure.description,\n ...(procedure.unavailableReason ? { reason: procedure.unavailableReason } : {}),\n effect: procedure.effect,\n flags: procedureFlags(procedure),\n tags: [procedure.effect, ...procedureFlags(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 //\n // Unconditional, not behind `--explain`, for the reason `AS-CLI-007` moved\n // the hidden *count* out from behind it: signed out, the example app rendered\n // `0 callable, 0 visible-disabled` over eleven perfectly good capabilities\n // that authority had hidden, and a reader who did not know to re-run with a\n // flag read that as an app which annotated nothing. The explanation is\n // collected on every run regardless, so this costs nothing. The policy\n // *attribution* still needs `--explain`; only the rows moved.\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 path: pathOf(capability.capabilityId),\n kind: capability.kind,\n plane: capability.plane,\n outcome: \"hide\" as const,\n description: capability.description,\n // No reason line, deliberately. The reason a hidden capability carries\n // is its *availability* reason — \"The drawer is not open\" — and printing\n // that under a row marked `hidden` says the UI declined when authority\n // did. Authority hides, state discloses (D11/D12), and the two must\n // never look alike. Why it was hidden is a policy question, which is\n // what `--explain` answers.\n //\n // A hidden capability has no snapshot entry, so there is no effect to\n // report — the table prints an em dash rather than inventing one. The\n // capability path already carries the component type; only a non-default\n // instance adds anything.\n flags:\n capability.component.instanceId === \"default\"\n ? []\n : [`@${capability.component.instanceId}`],\n tags: [`${capability.component.type}@${capability.component.instanceId}`],\n ...(options.explain\n ? { policies: capability.policies, 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 ...(result.scope ? { scope: result.scope } : {}),\n groups,\n counts,\n rejections: result.rejections ?? [],\n explained: options.explain === true,\n };\n}\n\nfunction rowFor(\n descriptor: AgentObservationDescriptor | AgentActionDescriptor,\n kind: \"observation\" | \"action\",\n effect: string | undefined,\n flags: string[],\n options: ViewOptions,\n schemas: { input?: unknown; output?: unknown },\n): CapabilityRow {\n return {\n capabilityId: descriptor.capabilityId,\n name: descriptor.name,\n path: pathOf(descriptor.capabilityId),\n kind,\n plane: \"view\",\n outcome: descriptor.available ? \"expose\" : \"disable\",\n description: descriptor.description,\n ...(descriptor.unavailableReason ? { reason: descriptor.unavailableReason } : {}),\n ...(effect ? { effect } : {}),\n flags,\n // The grouped detail view prints one combined list, the way it always has.\n tags: effect ? [effect, ...flags] : [kind, ...flags],\n ...(options.schemas ? { schemas } : {}),\n };\n}\n"],"mappings":";AAuEO,SAAS,SAAS,MAAoC;AAC3D,SAAO,KAAK,OAAO,QAAQ,CAAC,UAAU,MAAM,IAAI;AAClD;AAEA,SAAS,OAAO,cAA8B;AAC5C,SAAO,aAAa,QAAQ,mBAAmB,EAAE;AACnD;AAEA,SAAS,OAAO,cAA8B;AAC5C,QAAM,eAAe,OAAO,YAAY;AACxC,QAAM,MAAM,aAAa,YAAY,GAAG;AACxC,SAAO,QAAQ,KAAK,eAAe,aAAa,MAAM,MAAM,CAAC;AAC/D;AAOA,SAAS,YAAY,QAAyC;AAC5D,QAAM,QAAkB,CAAC;AACzB,MAAI,OAAO,WAAY,OAAM,KAAK,YAAY;AAC9C,MAAI,OAAO,WAAY,OAAM,KAAK,YAAY;AAC9C,MAAI,OAAO,iBAAiB,QAAS,OAAM,KAAK,gBAAgB,OAAO,YAAY,EAAE;AACrF,SAAO;AACT;AAEA,SAAS,eAAe,WAA+C;AACrE,QAAM,QAAkB,CAAC;AACzB,MAAI,UAAU,iBAAiB,QAAS,OAAM,KAAK,gBAAgB,UAAU,YAAY,EAAE;AAC3F,aAAW,SAAS,UAAU,aAAa;AACzC,UAAM,KAAK,GAAG,MAAM,IAAI,SAAS,MAAM,SAAS,YAAY,EAAE,EAAE;AAAA,EAClE;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,aAAqE;AAC7F,QAAM,QAAQ,oBAAI,IAAmC;AACrD,aAAW,cAAc,YAAY,cAAc;AAEjD,UAAM,IAAI,GAAG,WAAW,YAAY,KAAS,WAAW,cAAc,IAAI,UAAU;AAAA,EACtF;AACA,SAAO;AACT;AAEO,SAAS,UAAU,QAAuB,UAAuB,CAAC,GAAgB;AACvF,QAAM,EAAE,UAAU,YAAY,IAAI;AAClC,QAAM,QAAQ,iBAAiB,WAAW;AAC1C,QAAM,SAA4B,CAAC;AACnC,QAAM,SAAS,EAAE,UAAU,GAAG,UAAU,GAAG,QAAQ,EAAE;AAErD,QAAM,SAAS,CACb,KACA,cACA,mBACkB;AAClB,UAAM,YAAY,MAAM,IAAI,GAAG,YAAY,KAAS,cAAc,EAAE;AACpE,QAAI,QAAQ,WAAW,WAAW;AAChC,UAAI,WAAW,UAAU;AACzB,UAAI,eAAe,UAAU;AAAA,IAC/B;AACA,WAAO;AAAA,EACT;AAEA,aAAW,aAAa,SAAS,YAAY;AAC3C,UAAM,OAAwB,CAAC;AAE/B,eAAW,eAAe,UAAU,cAAc;AAChD,WAAK;AAAA,QACH;AAAA,UACE,OAAO,aAAa,eAAe,QAAW,CAAC,GAAG,SAAS;AAAA,YACzD,OAAO;AAAA,YACP,QAAQ,YAAY;AAAA,UACtB,CAAC;AAAA,UACD,YAAY;AAAA,UACZ,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AACA,eAAW,UAAU,UAAU,SAAS;AACtC,WAAK;AAAA,QACH;AAAA,UACE,OAAO,QAAQ,UAAU,OAAO,QAAQ,YAAY,MAAM,GAAG,SAAS;AAAA,YACpE,OAAO,OAAO;AAAA,YACd,QAAQ,OAAO;AAAA,UACjB,CAAC;AAAA,UACD,OAAO;AAAA,UACP,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,MACV,SACE,UAAU,eAAe,YACrB,UAAU,OACV,GAAG,UAAU,IAAI,IAAI,UAAU,UAAU;AAAA,MAC/C;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,SAAS,WAAW,SAAS,GAAG;AAClC,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM,SAAS,WAAW;AAAA,QAAI,CAAC,cAC7B;AAAA,UACE;AAAA,YACE,cAAc,UAAU;AAAA,YACxB,MAAM,UAAU,YAAY,QAAQ,YAAY,EAAE;AAAA,YAClD,MAAM,OAAO,UAAU,WAAW;AAAA,YAClC,MAAM;AAAA,YACN,OAAO;AAAA,YACP,SAAS,UAAU,YAAY,WAAW;AAAA,YAC1C,aAAa,UAAU;AAAA,YACvB,GAAI,UAAU,oBAAoB,EAAE,QAAQ,UAAU,kBAAkB,IAAI,CAAC;AAAA,YAC7E,QAAQ,UAAU;AAAA,YAClB,OAAO,eAAe,SAAS;AAAA,YAC/B,MAAM,CAAC,UAAU,QAAQ,GAAG,eAAe,SAAS,CAAC;AAAA,YACrD,GAAI,QAAQ,UACR,EAAE,SAAS,EAAE,OAAO,UAAU,aAAa,QAAQ,UAAU,aAAa,EAAE,IAC5E,CAAC;AAAA,UACP;AAAA,UACA,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAYA,QAAM,SAAS,YAAY,aAAa,OAAO,CAAC,MAAM,EAAE,YAAY,MAAM;AAC1E,MAAI,OAAO,SAAS,GAAG;AACrB,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM,OAAO,IAAI,CAAC,gBAAgB;AAAA,QAChC,cAAc,WAAW;AAAA,QACzB,MAAM,OAAO,WAAW,YAAY;AAAA,QACpC,MAAM,OAAO,WAAW,YAAY;AAAA,QACpC,MAAM,WAAW;AAAA,QACjB,OAAO,WAAW;AAAA,QAClB,SAAS;AAAA,QACT,aAAa,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAYxB,OACE,WAAW,UAAU,eAAe,YAChC,CAAC,IACD,CAAC,IAAI,WAAW,UAAU,UAAU,EAAE;AAAA,QAC5C,MAAM,CAAC,GAAG,WAAW,UAAU,IAAI,IAAI,WAAW,UAAU,UAAU,EAAE;AAAA,QACxE,GAAI,QAAQ,UACR,EAAE,UAAU,WAAW,UAAU,cAAc,WAAW,aAAa,IACvE,CAAC;AAAA,MACP,EAAE;AAAA,IACJ,CAAC;AAAA,EACH;AAEA,aAAW,cAAc,YAAY,cAAc;AACjD,QAAI,WAAW,YAAY,SAAU,QAAO,YAAY;AAAA,aAC/C,WAAW,YAAY,UAAW,QAAO,YAAY;AAAA,QACzD,QAAO,UAAU;AAAA,EACxB;AAEA,SAAO;AAAA,IACL,UAAU,OAAO;AAAA,IACjB,GAAI,SAAS,OAAO,OAAO,EAAE,OAAO,SAAS,MAAM,KAAK,IAAI,CAAC;AAAA,IAC7D,GAAI,OAAO,QAAQ,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC;AAAA,IAC9C;AAAA,IACA;AAAA,IACA,YAAY,OAAO,cAAc,CAAC;AAAA,IAClC,WAAW,QAAQ,YAAY;AAAA,EACjC;AACF;AAEA,SAAS,OACP,YACA,MACA,QACA,OACA,SACA,SACe;AACf,SAAO;AAAA,IACL,cAAc,WAAW;AAAA,IACzB,MAAM,WAAW;AAAA,IACjB,MAAM,OAAO,WAAW,YAAY;AAAA,IACpC;AAAA,IACA,OAAO;AAAA,IACP,SAAS,WAAW,YAAY,WAAW;AAAA,IAC3C,aAAa,WAAW;AAAA,IACxB,GAAI,WAAW,oBAAoB,EAAE,QAAQ,WAAW,kBAAkB,IAAI,CAAC;AAAA,IAC/E,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,IAC3B;AAAA;AAAA,IAEA,MAAM,SAAS,CAAC,QAAQ,GAAG,KAAK,IAAI,CAAC,MAAM,GAAG,KAAK;AAAA,IACnD,GAAI,QAAQ,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,EACvC;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/render/plain.ts","../src/report.ts"],"sourcesContent":["import { relative } from \"node:path\";\nimport type { CapabilityRow, SurfaceView } from \"./model.js\";\nimport { flatRows } from \"./model.js\";\nimport type { DiffEntry } from \"../baseline.js\";\nimport { formatValue } from \"../baseline.js\";\nimport type { ScenarioFailure } from \"../analysis.js\";\nimport {\n authoredIds,\n unresolved,\n type AuthoredCapability,\n type CapabilityInventory,\n} from \"../extract.js\";\nimport { unreadKey, type CoverageReport } from \"../coverage.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;\nconst STATE = { expose: \"callable\", disable: \"disabled\", hide: \"hidden\" } as const;\nconst NONE = \"—\";\nconst REPORT_WIDTH = 100;\n\n/** Deterministic wrapping: readable in logs, independent of terminal width. */\nfunction wrapText(text: string, width: number): string[] {\n const words = text.split(/\\s+/).filter(Boolean);\n const lines: string[] = [];\n let line = \"\";\n for (const word of words) {\n if (line && line.length + 1 + word.length > width) {\n lines.push(line);\n line = word;\n } else {\n line = line ? `${line} ${word}` : word;\n }\n }\n if (line) lines.push(line);\n return lines.length > 0 ? lines : [\"\"];\n}\n\n/**\n * Column widths come from the *content*, never from `process.stdout.columns`.\n *\n * `AS-CLI-003` requires plain output to be byte-stable across runs, and a table\n * laid out against the terminal it happened to run in is stable only until two\n * people diff the same CI log from different windows. Same rows in, same bytes\n * out, everywhere.\n *\n * The last column is not padded, so no line ever carries trailing whitespace —\n * which some diff tools render and others strip, i.e. another way for identical\n * output to look different.\n */\nfunction renderTable(headers: string[], rows: Array<{ cells: string[]; note?: string }>): string[] {\n const widths = headers.map((header, column) =>\n Math.max(header.length, ...rows.map((row) => (row.cells[column] ?? \"\").length)),\n );\n const line = (cells: string[]): string =>\n cells\n .map((cell, column) => (column === headers.length - 1 ? cell : cell.padEnd(widths[column]!)))\n .join(\" \")\n .trimEnd();\n\n const lines = [line(headers)];\n for (const row of rows) {\n lines.push(line(row.cells));\n // The unavailability reason is prose of unbounded length. A column for it\n // would set the table's width by its longest sentence; a continuation line\n // keeps the grid aligned and puts the reason directly under its capability.\n if (row.note) {\n for (const [index, note] of wrapText(row.note, REPORT_WIDTH - 6).entries()) {\n lines.push(` ${index === 0 ? \"⤷ \" : \" \"}${note}`);\n }\n }\n }\n return lines;\n}\n\n/** `UNREACHED — authored, and no scenario mounts it (1)` */\nfunction section(title: string, gloss: string, count: number): string {\n return `${title} — ${gloss} (${count})`;\n}\n\nfunction renderDetailRow(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(\"/\") : NONE;\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\n/**\n * The counts line, and everything it is relative to (`AS-CLI-007`).\n *\n * `hidden` is printed unconditionally. It is computed on every run — the\n * explanation is always collected — and suppressing it outside `--explain`\n * meant a surface with a policy-hidden half rendered as a complete one. The\n * *attribution* still needs `--explain`; the count and the rows do not.\n */\nexport function renderCountsPlain(view: SurfaceView): string {\n return (\n `${view.counts.callable} callable, ${view.counts.disabled} visible-disabled, ` +\n `${view.counts.hidden} hidden` +\n (view.rejections.length > 0\n ? `, ${view.rejections.length} registration${view.rejections.length === 1 ? \"\" : \"s\"} rejected`\n : \"\")\n );\n}\n\nfunction renderHeader(view: SurfaceView, lines: string[]): void {\n lines.push(\n `scenario ${view.scenario}${view.route ? ` route ${view.route}` : \"\"}${\n view.scope && view.scope.length > 0 ? ` scope ${view.scope.join(\" \")}` : \"\"\n }`,\n );\n lines.push(renderCountsPlain(view));\n}\n\nfunction renderRejections(view: SurfaceView, lines: string[]): void {\n if (view.rejections.length === 0) return;\n lines.push(\"\");\n lines.push(\n section(\"REJECTED\", \"the registry refused these during the mount\", view.rejections.length),\n );\n for (const rejection of view.rejections) {\n const why =\n rejection.reason === \"duplicate\"\n ? \"duplicate — an earlier registration holds this key\"\n : \"guard — onRegister rejected this registration\";\n lines.push(` ! ${rejection.componentType} (${rejection.instanceId}) ${why}`);\n }\n}\n\nfunction renderEmpty(view: SurfaceView, lines: string[]): void {\n lines.push(\"\");\n // \"Nothing is registered\" is only true when nothing was hidden. Saying it\n // over a surface a policy emptied sends the reader to the wrong file.\n if (view.counts.hidden > 0) {\n lines.push(\n `Nothing is callable here — all ${view.counts.hidden} registered capabilities were hidden by policy.`,\n );\n if (!view.explained) lines.push(\"Re-run with --explain to see which policy hid them.\");\n } else {\n lines.push(\"Nothing is registered for this scenario — the agent has no surface here.\");\n if (!view.explained) lines.push(\"Re-run with --explain to see whether a policy hid it.\");\n }\n}\n\nexport interface SurfaceRenderOptions {\n /** The grouped, one-capability-per-paragraph view. Implied by --explain/--schemas. */\n detail?: boolean;\n}\n\n/**\n * One capability per line, aligned. The default, because the question `inspect`\n * is usually asked is *what is on this surface* — which is a scanning question,\n * and prose does not scan.\n *\n * Policy chains and JSON Schemas are multi-line by nature and cannot live in a\n * cell, so `--explain` and `--schemas` fall back to the detail view rather than\n * producing a table with most of the answer missing.\n */\nexport function renderSurfacePlain(\n view: SurfaceView,\n options: SurfaceRenderOptions = {},\n): string {\n const lines: string[] = [];\n renderHeader(view, lines);\n renderRejections(view, lines);\n\n const rows = flatRows(view);\n if (rows.length === 0) {\n renderEmpty(view, lines);\n return lines.join(\"\\n\");\n }\n\n if (options.detail) {\n for (const group of view.groups.filter((group) => group.rows.length > 0)) {\n lines.push(\"\");\n lines.push(`${group.heading} (${group.rows.length})`);\n for (const row of group.rows) renderDetailRow(row, lines);\n }\n return lines.join(\"\\n\");\n }\n\n lines.push(\"\");\n lines.push(\n ...renderTable(\n [\"CAPABILITY\", \"KIND\", \"EFFECT\", \"STATE\", \"FLAGS\"],\n rows.map((row) => ({\n cells: [\n row.path,\n row.kind,\n row.effect ?? NONE,\n STATE[row.outcome],\n row.flags.length > 0 ? row.flags.join(\" · \") : NONE,\n ],\n ...(row.reason ? { note: row.reason } : {}),\n })),\n ),\n );\n return lines.join(\"\\n\");\n}\n\n/**\n * The static catalog (`AS-COVER-001…003`). The summary says \"upper bound\" in so\n * many words: a tsconfig's include globs are wider than what a bundle reaches,\n * so a capability in a component no route renders any more is in here. That is\n * dead code — a different finding, not a false positive — and the reader has to\n * be told which number they are holding.\n */\nexport interface CatalogRenderOptions {\n /**\n * This catalog *is* the command's output, rather than its preamble.\n *\n * True at `--depth static`: there are no scenario tables and no verdict, so\n * the listing and the unread call sites have nowhere else to appear.\n *\n * False at `--depth full`, where the scenario tables below name every\n * capability a scenario reached, the `UNREACHED` section names the ones it did\n * not, and the verdict carries the unread call sites — so printing any of it\n * here is the same information a second time, above the answer instead of in\n * it. Only the summary line survives.\n */\n standalone?: boolean;\n /** Authoritative domain manifest entries, when runtime config was loaded. */\n domainCapabilities?: number;\n /** Show origins, notes and per-site allowlist keys. */\n detail?: boolean;\n}\n\nfunction componentOf(capabilityId: string): string {\n const path = capabilityId.replace(/^(view|domain):/, \"\");\n const dot = path.lastIndexOf(\".\");\n return dot === -1 ? path : path.slice(0, dot);\n}\n\nexport function renderCatalogPlain(\n inventory: CapabilityInventory,\n options: CatalogRenderOptions = {},\n): string {\n const lines: string[] = [];\n const resolved = inventory.capabilities.filter((c) => c.resolution !== \"unresolved\");\n const unreadEntries = unresolved(inventory);\n const dynamicMetadata = resolved.filter((c) => c.resolution === \"partial\").length;\n const ids = authoredIds(inventory);\n const authored = ids.size + (options.domainCapabilities ?? 0);\n\n lines.push(\"STATIC CATALOG\");\n lines.push(\n `STATUS ${unreadEntries.length > 0 ? \"INCOMPLETE\" : \"COMPLETE\"}${\n unreadEntries.length > 0\n ? ` — ${unreadEntries.length} unread capability identit${unreadEntries.length === 1 ? \"y\" : \"ies\"}`\n : \" — every capability identity resolved\"\n }`,\n );\n lines.push(\n `Capabilities ${authored} authored (upper bound) · ${resolved.length} resolved call site${\n resolved.length === 1 ? \"\" : \"s\"\n }`,\n );\n lines.push(\n `Program ${inventory.filesAnalyzed} file${inventory.filesAnalyzed === 1 ? \"\" : \"s\"} analyzed` +\n (inventory.filesOutsideRoot > 0\n ? ` · ${inventory.filesOutsideRoot} agent-surface implementation file${\n inventory.filesOutsideRoot === 1 ? \"\" : \"s\"\n } excluded`\n : \"\"),\n );\n lines.push(\n `Metadata ${dynamicMetadata} call site${dynamicMetadata === 1 ? \"\" : \"s\"} partially read` +\n (dynamicMetadata > 0 ? \" · identity remains resolved\" : \"\"),\n );\n lines.push(\n options.domainCapabilities === undefined\n ? \"Domain not analyzed at static depth; full depth reads the oRPC manifest\"\n : `Domain ${options.domainCapabilities} manifest capabilit${\n options.domainCapabilities === 1 ? \"y\" : \"ies\"\n }`,\n );\n\n if (!options.standalone) return lines.join(\"\\n\");\n\n const components = new Map<\n string,\n { ids: Set<string>; sites: number; partial: number }\n >();\n for (const capability of resolved) {\n const component = componentOf(capability.capabilityId);\n const current = components.get(component) ?? { ids: new Set<string>(), sites: 0, partial: 0 };\n current.ids.add(capability.capabilityId);\n current.sites += 1;\n if (capability.resolution === \"partial\") current.partial += 1;\n components.set(component, current);\n }\n\n if (components.size > 0) {\n lines.push(\"\");\n lines.push(`COMPONENTS (${components.size})`);\n lines.push(\n ...renderTable(\n [\"COMPONENT\", \"CAPABILITIES\", \"CALL SITES\", \"DYNAMIC META\"],\n [...components.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([component, data]) => ({\n cells: [\n `view:${component}`,\n String(data.ids.size),\n String(data.sites),\n data.partial > 0 ? String(data.partial) : NONE,\n ],\n note: [...data.ids].sort().join(\" · \"),\n })),\n ),\n );\n }\n\n if (unreadEntries.length > 0) {\n const groups = new Map<string, number>();\n for (const entry of unreadEntries) {\n const key = `${entry.origin.file}\\0${entry.reason ?? \"unknown\"}`;\n groups.set(key, (groups.get(key) ?? 0) + 1);\n }\n lines.push(\"\");\n lines.push(`UNREAD SITES (${unreadEntries.length})`);\n lines.push(\"Counts above are a floor until these sites are resolved or explicitly accepted.\");\n lines.push(\n ...renderTable(\n [\"FILE\", \"REASON\", \"SITES\"],\n [...groups.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([key, count]) => {\n const [file, reason] = key.split(\"\\0\");\n return { cells: [file ?? \"?\", reason ?? \"unknown\", String(count)] };\n }),\n ),\n );\n lines.push(\"\", \"ALLOWLIST KEYS\");\n for (const entry of unreadEntries) lines.push(` allowlist key: ${unreadKey(entry)}`);\n }\n\n if (options.detail) {\n const byId = [...resolved].sort((a, b) => a.capabilityId.localeCompare(b.capabilityId));\n if (byId.length > 0) {\n lines.push(\"\");\n lines.push(`CAPABILITY DETAILS (${byId.length} call sites)`);\n lines.push(\n ...renderTable(\n [\"CAPABILITY\", \"KIND\", \"ORIGIN\", \"READ\"],\n byId.map((capability) => ({\n cells: [\n capability.capabilityId,\n capability.kind,\n `${capability.origin.file}:${capability.origin.line}`,\n capability.resolution,\n ],\n ...(capability.note ? { note: capability.note } : {}),\n })),\n ),\n );\n }\n const unread = renderUnread(unreadEntries);\n if (unread.length > 0) lines.push(\"\", ...unread);\n } else if (unreadEntries.length > 0 || resolved.length > 0) {\n lines.push(\"\");\n lines.push(\n \"Details: re-run with --detail for origins, metadata diagnostics, and allowlist keys.\",\n );\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Call sites the extractor could not read. Reported with file and line, never\n * dropped: an inventory that silently omitted what it failed to parse would\n * understate the denominator, and every number built on it would claim a\n * completeness it never had.\n */\nfunction renderUnread(entries: AuthoredCapability[]): string[] {\n if (entries.length === 0) return [];\n const lines: string[] = [];\n lines.push(\n section(\n \"UNREAD CALL SITES\",\n \"the catalog is incomplete, so every count above is a floor\",\n entries.length,\n ),\n );\n for (const capability of entries) {\n lines.push(` ? ${capability.origin.file}:${capability.origin.line}`);\n lines.push(` ${capability.note ?? \"the extractor could not read this call site\"}`);\n // The allowlist key, spelled out. It is `file#reason#site`, and the site is\n // a hash — not the line the reader is looking at — so leaving them to infer\n // it guarantees a wrong guess and an entry that never matches.\n lines.push(` allowlist key: ${unreadKey(capability)}`);\n }\n return lines;\n}\n\n/**\n * The verdict: authored minus reached (`AS-COVER-004…005`).\n *\n * This is the finding the command surface used to hide behind a fifth command,\n * so it is the last thing printed and the thing a reader stops on.\n */\nexport interface CoverageRenderOptions {\n /** Check already prints an executive summary; render findings only. */\n compact?: boolean;\n /** Include non-gating inventories such as undeclared runtime ids. */\n detail?: boolean;\n}\n\nexport function renderCoveragePlain(\n report: CoverageReport,\n options: CoverageRenderOptions = {},\n): string {\n const lines: string[] = [];\n\n if (report.unreached.length > 0) {\n lines.push(\n section(\"UNREACHED\", \"authored, and no scenario mounts it\", report.unreached.length),\n );\n lines.push(\n ...renderTable(\n [\"CAPABILITY\", \"ORIGIN\"],\n report.unreached.map((entry) => ({\n cells: [entry.capabilityId, `${entry.origin.file}:${entry.origin.line}`],\n })),\n ),\n );\n lines.push(\"\");\n }\n\n if (report.undeclared.length > 0) {\n if (!options.compact || options.detail) {\n lines.push(\n section(\n \"UNDECLARED\",\n \"present at runtime with no static origin — a dynamic registration, or a gap here\",\n report.undeclared.length,\n ),\n );\n for (const id of report.undeclared) lines.push(` ${id}`);\n } else {\n lines.push(\n `NOTICE — ${report.undeclared.length} runtime capabilit${\n report.undeclared.length === 1 ? \"y has\" : \"ies have\"\n } no static origin; re-run check with --detail to list them.`,\n );\n }\n lines.push(\"\");\n }\n\n if (report.unmanifestedDomain.length > 0) {\n lines.push(\n section(\n \"UNMANIFESTED DOMAIN\",\n \"mounted, but absent from the authoritative oRPC manifest\",\n report.unmanifestedDomain.length,\n ),\n );\n for (const id of report.unmanifestedDomain) lines.push(` ${id}`);\n lines.push(\"\");\n }\n\n if (report.staleAllowlist.length > 0) {\n lines.push(\n section(\n \"STALE ALLOWLIST\",\n \"a scenario reaches these now, so delete them before the list rots\",\n report.staleAllowlist.length,\n ),\n );\n for (const id of report.staleAllowlist) lines.push(` ${id}`);\n lines.push(\"\");\n }\n\n if (report.staleUnreadAllowlist.length > 0) {\n lines.push(\n section(\n \"STALE UNREAD ALLOWLIST\",\n \"the extractor reads these now, so delete them before the list rots\",\n report.staleUnreadAllowlist.length,\n ),\n );\n for (const key of report.staleUnreadAllowlist) lines.push(` ${key}`);\n lines.push(\"\");\n }\n\n if (report.unresolved.length > 0) {\n lines.push(...renderUnread(report.unresolved), \"\");\n }\n\n if (!options.compact) lines.push(...renderCoverageSummary(report));\n return lines.join(\"\\n\");\n}\n\nexport interface CheckOverview {\n status: \"PASS\" | \"FAIL\" | \"ERROR\";\n coverage?: CoverageReport;\n unresolvedAllowed: boolean;\n baselineCurrent: number;\n baselineTotal: number;\n scenarioManifestOk: boolean;\n rejected: number;\n mountFailures: number;\n scenarios: string[];\n}\n\nfunction overviewRow(label: string, status: \"PASS\" | \"WARN\" | \"FAIL\" | \"ERROR\", text: string): string {\n return `${label.padEnd(12)}${status.padEnd(7)}${text}`;\n}\n\nfunction wrappedList(items: string[]): string[] {\n const prefix = \" \";\n return wrapText(items.join(\", \"), REPORT_WIDTH - prefix.length).map((line) => `${prefix}${line}`);\n}\n\n/** First-screen answer for `check`: verdict and health dimensions before detail. */\nexport function renderCheckOverviewPlain(input: CheckOverview): string {\n const lines = [`SURFACE CHECK ${input.status}`, \"\"];\n const coverage = input.coverage;\n if (coverage) {\n const coverageStatus =\n coverage.unreached.length > 0 || coverage.staleAllowlist.length > 0\n ? \"FAIL\"\n : coverage.allowed.length > 0\n ? \"WARN\"\n : \"PASS\";\n lines.push(\n overviewRow(\n \"Coverage\",\n coverageStatus,\n `${coverage.reached}/${coverage.authored} authored capabilities reached` +\n (coverage.unreached.length > 0 ? ` · ${coverage.unreached.length} unreached` : \"\") +\n (coverage.allowed.length > 0\n ? ` · ${coverage.allowed.length} unreached allowlisted`\n : \"\") +\n (coverage.staleAllowlist.length > 0\n ? ` · ${coverage.staleAllowlist.length} stale allowlist entr${\n coverage.staleAllowlist.length === 1 ? \"y\" : \"ies\"\n }`\n : \"\"),\n ),\n );\n const unread = coverage.unresolved.length;\n const accepted = coverage.allowedUnread.length;\n const catalogStatus =\n coverage.staleUnreadAllowlist.length > 0 || (unread > 0 && !input.unresolvedAllowed)\n ? \"FAIL\"\n : unread > 0 || accepted > 0\n ? \"WARN\"\n : \"PASS\";\n lines.push(\n overviewRow(\n \"Catalog\",\n catalogStatus,\n coverage.staleUnreadAllowlist.length > 0\n ? `${coverage.staleUnreadAllowlist.length} stale unread allowlist entr${\n coverage.staleUnreadAllowlist.length === 1 ? \"y\" : \"ies\"\n }`\n : unread > 0\n ? `${unread} unread static site${unread === 1 ? \"\" : \"s\"}${\n input.unresolvedAllowed ? \" accepted by --allow-unresolved\" : \"\"\n }`\n : accepted > 0\n ? `${accepted} unread static site${accepted === 1 ? \"\" : \"s\"} allowlisted`\n : \"all static sites resolved\",\n ),\n );\n lines.push(\n overviewRow(\n \"Domain\",\n coverage.unmanifestedDomain.length > 0 ? \"FAIL\" : coverage.domainAuthoritative ? \"PASS\" : \"WARN\",\n coverage.unmanifestedDomain.length > 0\n ? `${coverage.unmanifestedDomain.length} mounted capabilit${\n coverage.unmanifestedDomain.length === 1 ? \"y\" : \"ies\"\n } absent from manifest`\n : coverage.domainAuthoritative\n ? `${coverage.domainReached.length} manifest capabilit${\n coverage.domainReached.length === 1 ? \"y\" : \"ies\"\n } reached`\n : \"authoritative manifest not configured\",\n ),\n );\n } else {\n lines.push(\n overviewRow(\n \"Coverage\",\n input.status === \"ERROR\" ? \"ERROR\" : \"WARN\",\n input.status === \"ERROR\"\n ? \"no verdict; runtime analysis incomplete\"\n : \"not evaluated — statement about these scenarios only; re-run with --depth full\",\n ),\n );\n }\n\n const baselineOk = input.baselineCurrent === input.baselineTotal && input.scenarioManifestOk;\n lines.push(\n overviewRow(\n \"Baselines\",\n baselineOk ? \"PASS\" : \"FAIL\",\n `${input.baselineCurrent}/${input.baselineTotal} scenario baselines current` +\n (input.scenarioManifestOk ? \"\" : \" · scenario manifest differs\"),\n ),\n );\n lines.push(\n overviewRow(\n \"Runtime\",\n input.mountFailures > 0 ? \"ERROR\" : input.rejected > 0 ? \"FAIL\" : \"PASS\",\n input.mountFailures > 0\n ? `${input.mountFailures} scenario${input.mountFailures === 1 ? \"\" : \"s\"} did not mount`\n : input.rejected > 0\n ? `${input.rejected} registration${input.rejected === 1 ? \"\" : \"s\"} rejected`\n : `${input.scenarios.length} scenario${input.scenarios.length === 1 ? \"\" : \"s\"} mounted`,\n ),\n );\n lines.push(\"\", `SCENARIOS (${input.scenarios.length})`, ...wrappedList(input.scenarios));\n return lines.join(\"\\n\");\n}\n\n/** The one line a reader who stops at the bottom takes away. */\nfunction renderCoverageSummary(report: CoverageReport): string[] {\n const qualifiers = [\n `${report.scenarios.length} scenario${report.scenarios.length === 1 ? \"\" : \"s\"} (${report.scenarios.join(\n \", \",\n )})`,\n ];\n // Every count is relative to the scope, so the scope is printed with them\n // (`AS-CLI-007`) — `10 authored` under a scope is a claim about one prefix of\n // the codebase, not about the codebase.\n if (report.scope && report.scope.length > 0) qualifiers.push(`scope ${report.scope.join(\" \")}`);\n\n const lines = [\n `${report.authored} authored · ${report.reached} reached · ${report.unreached.length} unreached` +\n ` · ${qualifiers.join(\" · \")}`,\n ];\n\n if (report.domainReached.length > 0) {\n lines.push(\n `${report.domainReached.length} domain capabilit${\n report.domainReached.length === 1 ? \"y\" : \"ies\"\n } reached${\n report.domainAuthoritative\n ? \" against the authoritative oRPC manifest\"\n : \" and held apart — configure the authoritative oRPC manifest to cover that plane\"\n }`,\n );\n }\n if (report.allowed.length > 0) {\n lines.push(\n `${report.allowed.length} unreached capabilit${\n report.allowed.length === 1 ? \"y is\" : \"ies are\"\n } allowlisted in ${relative(process.cwd(), report.allowlistPath)}`,\n );\n }\n if (report.allowedUnread.length > 0) {\n lines.push(\n `${report.allowedUnread.length} unread call site${\n report.allowedUnread.length === 1 ? \" is\" : \"s are\"\n } allowlisted in ${relative(process.cwd(), report.unreadAllowlistPath)}`,\n );\n }\n if (report.allowlistOutOfScope > 0) {\n lines.push(\n `${report.allowlistOutOfScope} allowlist entr${\n report.allowlistOutOfScope === 1 ? \"y\" : \"ies\"\n } outside this scope were not judged either way`,\n );\n }\n\n // Each bucket gets its own remedy. \"Add a scenario, or delete the component\"\n // is the right advice for an unreached capability and useless advice for a\n // call site the extractor could not read.\n if (\n report.unreached.length === 0 &&\n report.unresolved.length === 0 &&\n report.staleAllowlist.length === 0 &&\n report.staleUnreadAllowlist.length === 0 &&\n report.unmanifestedDomain.length === 0\n ) {\n lines.push(\n report.allowed.length > 0\n ? \"no new surface coverage gaps — the allowlist still holds the known ones\"\n : \"every authored capability is reached by a scenario\",\n );\n }\n return lines;\n}\n\n/**\n * Why there is no coverage verdict. Never silence: a reader who asked for the\n * complete answer and got a partial one has to be told which part is missing,\n * or the partial one reads as the complete one.\n */\nexport function renderNoVerdictPlain(failures: ScenarioFailure[]): string {\n return [\n section(\"NO COVERAGE VERDICT\", \"a scenario did not mount, so nothing reached anything\", failures.length),\n ...failures.flatMap((failure) => [` ${failure.scenario}`, ` ${failure.message}`]),\n \"\",\n \"Every capability those scenarios would have surfaced would be reported unreached,\",\n \"so no verdict is printed at all. Fix the mount, or name a scenario that works.\",\n ].join(\"\\n\");\n}\n\nexport function renderFailuresPlain(failures: ScenarioFailure[]): string {\n return [\n section(\"DID NOT MOUNT\", \"these scenarios threw, and were skipped\", failures.length),\n ...failures.flatMap((failure) => [` ${failure.scenario}`, ` ${failure.message}`]),\n ].join(\"\\n\");\n}\n\nexport function renderDriftPlain(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","import { basename, relative } from \"node:path\";\nimport type { CollectResult } from \"./collect.js\";\nimport type { CoverageReport } from \"./coverage.js\";\nimport type { CapabilityInventory } from \"./extract.js\";\nimport { normalize } from \"./baseline.js\";\nimport { buildView, flatRows, type CapabilityRow } from \"./render/model.js\";\n\n/** Stable, complete per-scenario document shared by JSON, baselines and check. */\nexport interface ScenarioReport {\n scenario: string;\n scope?: string[];\n snapshot: unknown;\n capabilities: CapabilityRow[];\n rejections: CollectResult[\"rejections\"];\n explanation?: { capabilities: CapabilityRow[] };\n}\n\nexport function scenarioReport(\n result: CollectResult,\n options: { attribution?: boolean; schemas?: boolean } = {},\n): ScenarioReport {\n const view = buildView(result, {\n ...(options.attribution ? { explain: true } : {}),\n ...(options.schemas ? { schemas: true } : {}),\n });\n const capabilities = flatRows(view);\n return {\n scenario: result.scenario,\n ...(result.scope ? { scope: result.scope } : {}),\n snapshot: normalize(result.snapshot),\n // Includes expose, disable and hide. Rows never contain runtime ids.\n capabilities,\n rejections: [...result.rejections].sort(\n (a, b) =>\n a.componentType.localeCompare(b.componentType) ||\n a.instanceId.localeCompare(b.instanceId) ||\n a.reason.localeCompare(b.reason),\n ),\n ...(options.attribution ? { explanation: { capabilities } } : {}),\n };\n}\n\n/** Baseline payload: same semantic document, without invocation-only labels. */\nexport function scenarioBaseline(result: CollectResult): Record<string, unknown> {\n const report = scenarioReport(result);\n return {\n ...(report.snapshot as Record<string, unknown>),\n capabilities: report.capabilities,\n rejections: report.rejections,\n };\n}\n\n/** Machine output must not contain checkout-specific absolute paths. */\nexport function inventoryReport(\n inventory: CapabilityInventory | undefined,\n domainCapabilities?: string[],\n): unknown {\n if (!inventory) return null;\n return {\n ...inventory,\n root: \".\",\n tsconfig: relative(inventory.root, inventory.tsconfig) || \"tsconfig.json\",\n ...(domainCapabilities\n ? { domain: { source: \"manifest\", capabilities: [...domainCapabilities].sort() } }\n : {}),\n };\n}\n\nexport function coverageReport(report: CoverageReport | undefined): unknown {\n if (!report) return null;\n return {\n ...report,\n allowlistPath: basename(report.allowlistPath),\n unreadAllowlistPath: basename(report.unreadAllowlistPath),\n };\n}\n"],"mappings":"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","names":["group","relative","relative"]}
|