@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,21 +1,31 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildView,
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
coverageSections,
|
|
4
|
+
flatRows,
|
|
5
|
+
neverCallable,
|
|
6
|
+
neverCallableSection,
|
|
7
|
+
riskClause,
|
|
8
|
+
runContextRows,
|
|
9
|
+
scenarioTable,
|
|
10
|
+
surfaceSummaryRows,
|
|
11
|
+
unreadSection
|
|
12
|
+
} from "./chunk-VX6GBEP3.js";
|
|
5
13
|
import {
|
|
6
|
-
authoredIds,
|
|
7
14
|
formatValue,
|
|
8
|
-
normalize
|
|
15
|
+
normalize
|
|
16
|
+
} from "./chunk-IALBMW3R.js";
|
|
17
|
+
import {
|
|
9
18
|
unreadKey,
|
|
10
19
|
unresolved
|
|
11
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-UGCLJ5JX.js";
|
|
12
21
|
|
|
13
22
|
// src/render/plain.ts
|
|
14
|
-
import { relative } from "path";
|
|
15
23
|
var MARK = { expose: "+", disable: "~", hide: "-" };
|
|
16
24
|
var STATE = { expose: "callable", disable: "disabled", hide: "hidden" };
|
|
17
25
|
var NONE = "\u2014";
|
|
18
26
|
var REPORT_WIDTH = 100;
|
|
27
|
+
var LABEL_WIDTH = 12;
|
|
28
|
+
var STATUS_WIDTH = 7;
|
|
19
29
|
function wrapText(text, width) {
|
|
20
30
|
const words = text.split(/\s+/).filter(Boolean);
|
|
21
31
|
const lines = [];
|
|
@@ -47,9 +57,38 @@ function renderTable(headers, rows) {
|
|
|
47
57
|
}
|
|
48
58
|
return lines;
|
|
49
59
|
}
|
|
60
|
+
function renderTablePlain(headers, rows) {
|
|
61
|
+
return renderTable(headers, rows).join("\n");
|
|
62
|
+
}
|
|
50
63
|
function section(title, gloss, count) {
|
|
51
64
|
return `${title} \u2014 ${gloss} (${count})`;
|
|
52
65
|
}
|
|
66
|
+
function renderReportPlain(blocks) {
|
|
67
|
+
const width = Math.max(
|
|
68
|
+
LABEL_WIDTH,
|
|
69
|
+
...blocks.flatMap((block) => block.rows.map((row) => row.label.length + 2))
|
|
70
|
+
);
|
|
71
|
+
const statuses = blocks.some((block) => block.rows.some((row) => row.status));
|
|
72
|
+
const renderRow = (row) => `${row.label.padEnd(width)}${statuses ? (row.status ?? "").padEnd(STATUS_WIDTH) : ""}${row.text}`.trimEnd();
|
|
73
|
+
return blocks.filter((block) => block.title || block.rows.length > 0).map((block) => [...block.title ? [block.title] : [], ...block.rows.map(renderRow)].join("\n")).join("\n\n");
|
|
74
|
+
}
|
|
75
|
+
function renderSectionsPlain(sections) {
|
|
76
|
+
return sections.map((entry) => {
|
|
77
|
+
const lines = [
|
|
78
|
+
entry.count > 0 ? section(entry.title, entry.gloss, entry.count) : `${entry.title} \u2014 ${entry.gloss}`
|
|
79
|
+
];
|
|
80
|
+
if (entry.headers && entry.rows) lines.push(...renderTable(entry.headers, entry.rows));
|
|
81
|
+
if (entry.lines) lines.push(...entry.lines.map((line) => ` ${line}`.trimEnd()));
|
|
82
|
+
if (entry.hint) {
|
|
83
|
+
lines.push(
|
|
84
|
+
...wrapText(entry.hint, REPORT_WIDTH - 4).map(
|
|
85
|
+
(line, index) => ` ${index === 0 ? "\u2192" : " "} ${line}`
|
|
86
|
+
)
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
return lines.join("\n");
|
|
90
|
+
}).join("\n\n");
|
|
91
|
+
}
|
|
53
92
|
function renderDetailRow(row, lines) {
|
|
54
93
|
const tags = row.tags.length > 0 ? ` [${row.tags.join(", ")}]` : "";
|
|
55
94
|
lines.push(` ${MARK[row.outcome]} ${row.name}${tags}`);
|
|
@@ -87,7 +126,8 @@ function renderDetailRow(row, lines) {
|
|
|
87
126
|
}
|
|
88
127
|
}
|
|
89
128
|
function renderCountsPlain(view) {
|
|
90
|
-
|
|
129
|
+
const risk = riskClause(flatRows(view));
|
|
130
|
+
return `${view.counts.callable} callable, ${view.counts.disabled} visible-disabled, ${view.counts.hidden} hidden` + (view.rejections.length > 0 ? `, ${view.rejections.length} registration${view.rejections.length === 1 ? "" : "s"} rejected` : "") + (risk ? ` \xB7 ${risk}` : "");
|
|
91
131
|
}
|
|
92
132
|
function renderHeader(view, lines) {
|
|
93
133
|
lines.push(
|
|
@@ -158,30 +198,10 @@ function componentOf(capabilityId) {
|
|
|
158
198
|
const dot = path.lastIndexOf(".");
|
|
159
199
|
return dot === -1 ? path : path.slice(0, dot);
|
|
160
200
|
}
|
|
161
|
-
function
|
|
201
|
+
function renderCatalogDetailPlain(inventory, options = {}) {
|
|
162
202
|
const lines = [];
|
|
163
203
|
const resolved = inventory.capabilities.filter((c) => c.resolution !== "unresolved");
|
|
164
204
|
const unreadEntries = unresolved(inventory);
|
|
165
|
-
const dynamicMetadata = resolved.filter((c) => c.resolution === "partial").length;
|
|
166
|
-
const ids = authoredIds(inventory);
|
|
167
|
-
const authored = ids.size + (options.domainCapabilities ?? 0);
|
|
168
|
-
lines.push("STATIC CATALOG");
|
|
169
|
-
lines.push(
|
|
170
|
-
`STATUS ${unreadEntries.length > 0 ? "INCOMPLETE" : "COMPLETE"}${unreadEntries.length > 0 ? ` \u2014 ${unreadEntries.length} unread capability identit${unreadEntries.length === 1 ? "y" : "ies"}` : " \u2014 every capability identity resolved"}`
|
|
171
|
-
);
|
|
172
|
-
lines.push(
|
|
173
|
-
`Capabilities ${authored} authored (upper bound) \xB7 ${resolved.length} resolved call site${resolved.length === 1 ? "" : "s"}`
|
|
174
|
-
);
|
|
175
|
-
lines.push(
|
|
176
|
-
`Program ${inventory.filesAnalyzed} file${inventory.filesAnalyzed === 1 ? "" : "s"} analyzed` + (inventory.filesOutsideRoot > 0 ? ` \xB7 ${inventory.filesOutsideRoot} agent-surface implementation file${inventory.filesOutsideRoot === 1 ? "" : "s"} excluded` : "")
|
|
177
|
-
);
|
|
178
|
-
lines.push(
|
|
179
|
-
`Metadata ${dynamicMetadata} call site${dynamicMetadata === 1 ? "" : "s"} partially read` + (dynamicMetadata > 0 ? " \xB7 identity remains resolved" : "")
|
|
180
|
-
);
|
|
181
|
-
lines.push(
|
|
182
|
-
options.domainCapabilities === void 0 ? "Domain not analyzed at static depth; full depth reads the oRPC manifest" : `Domain ${options.domainCapabilities} manifest capabilit${options.domainCapabilities === 1 ? "y" : "ies"}`
|
|
183
|
-
);
|
|
184
|
-
if (!options.standalone) return lines.join("\n");
|
|
185
205
|
const components = /* @__PURE__ */ new Map();
|
|
186
206
|
for (const capability of resolved) {
|
|
187
207
|
const component = componentOf(capability.capabilityId);
|
|
@@ -192,7 +212,6 @@ function renderCatalogPlain(inventory, options = {}) {
|
|
|
192
212
|
components.set(component, current);
|
|
193
213
|
}
|
|
194
214
|
if (components.size > 0) {
|
|
195
|
-
lines.push("");
|
|
196
215
|
lines.push(`COMPONENTS (${components.size})`);
|
|
197
216
|
lines.push(
|
|
198
217
|
...renderTable(
|
|
@@ -215,7 +234,7 @@ function renderCatalogPlain(inventory, options = {}) {
|
|
|
215
234
|
const key = `${entry.origin.file}\0${entry.reason ?? "unknown"}`;
|
|
216
235
|
groups.set(key, (groups.get(key) ?? 0) + 1);
|
|
217
236
|
}
|
|
218
|
-
lines.push("");
|
|
237
|
+
if (lines.length > 0) lines.push("");
|
|
219
238
|
lines.push(`UNREAD SITES (${unreadEntries.length})`);
|
|
220
239
|
lines.push("Counts above are a floor until these sites are resolved or explicitly accepted.");
|
|
221
240
|
lines.push(
|
|
@@ -233,7 +252,7 @@ function renderCatalogPlain(inventory, options = {}) {
|
|
|
233
252
|
if (options.detail) {
|
|
234
253
|
const byId = [...resolved].sort((a, b) => a.capabilityId.localeCompare(b.capabilityId));
|
|
235
254
|
if (byId.length > 0) {
|
|
236
|
-
lines.push("");
|
|
255
|
+
if (lines.length > 0) lines.push("");
|
|
237
256
|
lines.push(`CAPABILITY DETAILS (${byId.length} call sites)`);
|
|
238
257
|
lines.push(
|
|
239
258
|
...renderTable(
|
|
@@ -250,212 +269,112 @@ function renderCatalogPlain(inventory, options = {}) {
|
|
|
250
269
|
)
|
|
251
270
|
);
|
|
252
271
|
}
|
|
253
|
-
|
|
254
|
-
|
|
272
|
+
if (unreadEntries.length > 0) {
|
|
273
|
+
if (lines.length > 0) lines.push("");
|
|
274
|
+
lines.push(renderSectionsPlain([unreadSection(unreadEntries)]));
|
|
275
|
+
}
|
|
255
276
|
} else if (unreadEntries.length > 0 || resolved.length > 0) {
|
|
256
|
-
lines.push("");
|
|
277
|
+
if (lines.length > 0) lines.push("");
|
|
257
278
|
lines.push(
|
|
258
279
|
"Details: re-run with --detail for origins, metadata diagnostics, and allowlist keys."
|
|
259
280
|
);
|
|
260
281
|
}
|
|
261
282
|
return lines.join("\n");
|
|
262
283
|
}
|
|
263
|
-
function renderUnread(entries) {
|
|
264
|
-
if (entries.length === 0) return [];
|
|
265
|
-
const lines = [];
|
|
266
|
-
lines.push(
|
|
267
|
-
section(
|
|
268
|
-
"UNREAD CALL SITES",
|
|
269
|
-
"the catalog is incomplete, so every count above is a floor",
|
|
270
|
-
entries.length
|
|
271
|
-
)
|
|
272
|
-
);
|
|
273
|
-
for (const capability of entries) {
|
|
274
|
-
lines.push(` ? ${capability.origin.file}:${capability.origin.line}`);
|
|
275
|
-
lines.push(` ${capability.note ?? "the extractor could not read this call site"}`);
|
|
276
|
-
lines.push(` allowlist key: ${unreadKey(capability)}`);
|
|
277
|
-
}
|
|
278
|
-
return lines;
|
|
279
|
-
}
|
|
280
284
|
function renderCoveragePlain(report, options = {}) {
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
lines.push(
|
|
284
|
-
section("UNREACHED", "authored, and no scenario mounts it", report.unreached.length)
|
|
285
|
-
);
|
|
286
|
-
lines.push(
|
|
287
|
-
...renderTable(
|
|
288
|
-
["CAPABILITY", "ORIGIN"],
|
|
289
|
-
report.unreached.map((entry) => ({
|
|
290
|
-
cells: [entry.capabilityId, `${entry.origin.file}:${entry.origin.line}`]
|
|
291
|
-
}))
|
|
292
|
-
)
|
|
293
|
-
);
|
|
294
|
-
lines.push("");
|
|
295
|
-
}
|
|
296
|
-
if (report.undeclared.length > 0) {
|
|
297
|
-
if (!options.compact || options.detail) {
|
|
298
|
-
lines.push(
|
|
299
|
-
section(
|
|
300
|
-
"UNDECLARED",
|
|
301
|
-
"present at runtime with no static origin \u2014 a dynamic registration, or a gap here",
|
|
302
|
-
report.undeclared.length
|
|
303
|
-
)
|
|
304
|
-
);
|
|
305
|
-
for (const id of report.undeclared) lines.push(` ${id}`);
|
|
306
|
-
} else {
|
|
307
|
-
lines.push(
|
|
308
|
-
`NOTICE \u2014 ${report.undeclared.length} runtime capabilit${report.undeclared.length === 1 ? "y has" : "ies have"} no static origin; re-run check with --detail to list them.`
|
|
309
|
-
);
|
|
310
|
-
}
|
|
311
|
-
lines.push("");
|
|
312
|
-
}
|
|
313
|
-
if (report.unmanifestedDomain.length > 0) {
|
|
314
|
-
lines.push(
|
|
315
|
-
section(
|
|
316
|
-
"UNMANIFESTED DOMAIN",
|
|
317
|
-
"mounted, but absent from the authoritative oRPC manifest",
|
|
318
|
-
report.unmanifestedDomain.length
|
|
319
|
-
)
|
|
320
|
-
);
|
|
321
|
-
for (const id of report.unmanifestedDomain) lines.push(` ${id}`);
|
|
322
|
-
lines.push("");
|
|
323
|
-
}
|
|
324
|
-
if (report.staleAllowlist.length > 0) {
|
|
325
|
-
lines.push(
|
|
326
|
-
section(
|
|
327
|
-
"STALE ALLOWLIST",
|
|
328
|
-
"a scenario reaches these now, so delete them before the list rots",
|
|
329
|
-
report.staleAllowlist.length
|
|
330
|
-
)
|
|
331
|
-
);
|
|
332
|
-
for (const id of report.staleAllowlist) lines.push(` ${id}`);
|
|
333
|
-
lines.push("");
|
|
334
|
-
}
|
|
335
|
-
if (report.staleUnreadAllowlist.length > 0) {
|
|
336
|
-
lines.push(
|
|
337
|
-
section(
|
|
338
|
-
"STALE UNREAD ALLOWLIST",
|
|
339
|
-
"the extractor reads these now, so delete them before the list rots",
|
|
340
|
-
report.staleUnreadAllowlist.length
|
|
341
|
-
)
|
|
342
|
-
);
|
|
343
|
-
for (const key of report.staleUnreadAllowlist) lines.push(` ${key}`);
|
|
344
|
-
lines.push("");
|
|
345
|
-
}
|
|
346
|
-
if (report.unresolved.length > 0) {
|
|
347
|
-
lines.push(...renderUnread(report.unresolved), "");
|
|
348
|
-
}
|
|
349
|
-
if (!options.compact) lines.push(...renderCoverageSummary(report));
|
|
350
|
-
return lines.join("\n");
|
|
285
|
+
const sections = coverageSections(report, options);
|
|
286
|
+
return sections.length > 0 ? renderSectionsPlain(sections) : "";
|
|
351
287
|
}
|
|
352
|
-
function
|
|
353
|
-
|
|
288
|
+
function renderSurfaceSummaryPlain(input) {
|
|
289
|
+
const dark = neverCallable(input.reach);
|
|
290
|
+
const mounted = input.scenarios.filter((entry) => !entry.failed).length;
|
|
291
|
+
const sections = [
|
|
292
|
+
...input.coverage ? coverageSections(input.coverage) : [],
|
|
293
|
+
...dark.length > 0 && mounted > 1 ? [neverCallableSection(dark)] : []
|
|
294
|
+
];
|
|
295
|
+
const summary = renderReportPlain([{ title: "SURFACE SUMMARY", rows: surfaceSummaryRows(input) }]);
|
|
296
|
+
return sections.length > 0 ? `${renderSectionsPlain(sections)}
|
|
297
|
+
|
|
298
|
+
${summary}` : summary;
|
|
354
299
|
}
|
|
355
300
|
function wrappedList(items) {
|
|
356
301
|
const prefix = " ";
|
|
357
302
|
return wrapText(items.join(", "), REPORT_WIDTH - prefix.length).map((line) => `${prefix}${line}`);
|
|
358
303
|
}
|
|
359
|
-
function
|
|
360
|
-
const
|
|
304
|
+
function checkMatrixRows(input) {
|
|
305
|
+
const rows = [];
|
|
361
306
|
const coverage = input.coverage;
|
|
362
307
|
if (coverage) {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
`${coverage.reached}/${coverage.authored} authored capabilities reached` + (coverage.unreached.length > 0 ? ` \xB7 ${coverage.unreached.length} unreached` : "") + (coverage.allowed.length > 0 ? ` \xB7 ${coverage.allowed.length} unreached allowlisted` : "") + (coverage.staleAllowlist.length > 0 ? ` \xB7 ${coverage.staleAllowlist.length} stale allowlist entr${coverage.staleAllowlist.length === 1 ? "y" : "ies"}` : "")
|
|
369
|
-
)
|
|
370
|
-
);
|
|
308
|
+
rows.push({
|
|
309
|
+
label: "Coverage",
|
|
310
|
+
status: coverage.unreached.length > 0 || coverage.staleAllowlist.length > 0 ? "FAIL" : coverage.allowed.length > 0 ? "WARN" : "PASS",
|
|
311
|
+
text: `${coverage.reached}/${coverage.authored} authored capabilities reached` + (coverage.unreached.length > 0 ? ` \xB7 ${coverage.unreached.length} unreached` : "") + (coverage.allowed.length > 0 ? ` \xB7 ${coverage.allowed.length} unreached allowlisted` : "") + (coverage.staleAllowlist.length > 0 ? ` \xB7 ${coverage.staleAllowlist.length} stale allowlist entr${coverage.staleAllowlist.length === 1 ? "y" : "ies"}` : "")
|
|
312
|
+
});
|
|
371
313
|
const unread = coverage.unresolved.length;
|
|
372
314
|
const accepted = coverage.allowedUnread.length;
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
"Domain",
|
|
384
|
-
coverage.unmanifestedDomain.length > 0 ? "FAIL" : coverage.domainAuthoritative ? "PASS" : "WARN",
|
|
385
|
-
coverage.unmanifestedDomain.length > 0 ? `${coverage.unmanifestedDomain.length} mounted capabilit${coverage.unmanifestedDomain.length === 1 ? "y" : "ies"} absent from manifest` : coverage.domainAuthoritative ? `${coverage.domainReached.length} manifest capabilit${coverage.domainReached.length === 1 ? "y" : "ies"} reached` : "authoritative manifest not configured"
|
|
386
|
-
)
|
|
387
|
-
);
|
|
315
|
+
rows.push({
|
|
316
|
+
label: "Catalog",
|
|
317
|
+
status: coverage.staleUnreadAllowlist.length > 0 || unread > 0 && !input.unresolvedAllowed ? "FAIL" : unread > 0 || accepted > 0 ? "WARN" : "PASS",
|
|
318
|
+
text: coverage.staleUnreadAllowlist.length > 0 ? `${coverage.staleUnreadAllowlist.length} stale unread allowlist entr${coverage.staleUnreadAllowlist.length === 1 ? "y" : "ies"}` : unread > 0 ? `${unread} unread static site${unread === 1 ? "" : "s"}${input.unresolvedAllowed ? " accepted by --allow-unresolved" : ""}` : accepted > 0 ? `${accepted} unread static site${accepted === 1 ? "" : "s"} allowlisted` : "all static sites resolved"
|
|
319
|
+
});
|
|
320
|
+
rows.push({
|
|
321
|
+
label: "Domain",
|
|
322
|
+
status: coverage.unmanifestedDomain.length > 0 ? "FAIL" : coverage.domainAuthoritative ? "PASS" : "WARN",
|
|
323
|
+
text: coverage.unmanifestedDomain.length > 0 ? `${coverage.unmanifestedDomain.length} mounted capabilit${coverage.unmanifestedDomain.length === 1 ? "y" : "ies"} absent from manifest` : coverage.domainAuthoritative ? `${coverage.domainReached.length} manifest capabilit${coverage.domainReached.length === 1 ? "y" : "ies"} reached` : "authoritative manifest not configured"
|
|
324
|
+
});
|
|
388
325
|
} else {
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
)
|
|
395
|
-
);
|
|
326
|
+
rows.push({
|
|
327
|
+
label: "Coverage",
|
|
328
|
+
status: input.status === "ERROR" ? "ERROR" : "WARN",
|
|
329
|
+
text: input.status === "ERROR" ? "no verdict; runtime analysis incomplete" : "not evaluated \u2014 statement about these scenarios only; re-run with --depth full"
|
|
330
|
+
});
|
|
396
331
|
}
|
|
397
332
|
const baselineOk = input.baselineCurrent === input.baselineTotal && input.scenarioManifestOk;
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
input.mountFailures > 0 ? `${input.mountFailures} scenario${input.mountFailures === 1 ? "" : "s"} did not mount` : input.rejected > 0 ? `${input.rejected} registration${input.rejected === 1 ? "" : "s"} rejected` : `${input.scenarios.length} scenario${input.scenarios.length === 1 ? "" : "s"} mounted`
|
|
410
|
-
)
|
|
411
|
-
);
|
|
412
|
-
lines.push("", `SCENARIOS (${input.scenarios.length})`, ...wrappedList(input.scenarios));
|
|
413
|
-
return lines.join("\n");
|
|
333
|
+
rows.push({
|
|
334
|
+
label: "Baselines",
|
|
335
|
+
status: baselineOk ? "PASS" : "FAIL",
|
|
336
|
+
text: `${input.baselineCurrent}/${input.baselineTotal} scenario baselines current` + (input.scenarioManifestOk ? "" : " \xB7 scenario manifest differs")
|
|
337
|
+
});
|
|
338
|
+
rows.push({
|
|
339
|
+
label: "Runtime",
|
|
340
|
+
status: input.mountFailures > 0 ? "ERROR" : input.rejected > 0 ? "FAIL" : "PASS",
|
|
341
|
+
text: input.mountFailures > 0 ? `${input.mountFailures} scenario${input.mountFailures === 1 ? "" : "s"} did not mount` : input.rejected > 0 ? `${input.rejected} registration${input.rejected === 1 ? "" : "s"} rejected` : `${input.scenarios.length} scenario${input.scenarios.length === 1 ? "" : "s"} mounted`
|
|
342
|
+
});
|
|
343
|
+
return rows;
|
|
414
344
|
}
|
|
415
|
-
function
|
|
416
|
-
const
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
const lines = [
|
|
423
|
-
`${report.authored} authored \xB7 ${report.reached} reached \xB7 ${report.unreached.length} unreached \xB7 ${qualifiers.join(" \xB7 ")}`
|
|
345
|
+
function renderCheckOverviewPlain(input) {
|
|
346
|
+
const blocks = [
|
|
347
|
+
{
|
|
348
|
+
title: `SURFACE CHECK ${input.status}`,
|
|
349
|
+
rows: input.context ? runContextRows(input.context) : []
|
|
350
|
+
},
|
|
351
|
+
{ rows: checkMatrixRows(input) }
|
|
424
352
|
];
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
)
|
|
439
|
-
|
|
440
|
-
if (report.allowlistOutOfScope > 0) {
|
|
441
|
-
lines.push(
|
|
442
|
-
`${report.allowlistOutOfScope} allowlist entr${report.allowlistOutOfScope === 1 ? "y" : "ies"} outside this scope were not judged either way`
|
|
443
|
-
);
|
|
444
|
-
}
|
|
445
|
-
if (report.unreached.length === 0 && report.unresolved.length === 0 && report.staleAllowlist.length === 0 && report.staleUnreadAllowlist.length === 0 && report.unmanifestedDomain.length === 0) {
|
|
446
|
-
lines.push(
|
|
447
|
-
report.allowed.length > 0 ? "no new surface coverage gaps \u2014 the allowlist still holds the known ones" : "every authored capability is reached by a scenario"
|
|
448
|
-
);
|
|
449
|
-
}
|
|
450
|
-
return lines;
|
|
353
|
+
const table = input.stats ? scenarioTable(input.stats, { baselines: true }) : void 0;
|
|
354
|
+
const scenarios = input.stats && table ? [`SCENARIOS (${input.stats.length})`, ...renderTable(table.headers, table.rows)] : [`SCENARIOS (${input.scenarios.length})`, ...wrappedList(input.scenarios)];
|
|
355
|
+
return `${renderReportPlain(blocks)}
|
|
356
|
+
|
|
357
|
+
${scenarios.join("\n")}`;
|
|
358
|
+
}
|
|
359
|
+
function renderNextStepsPlain(steps) {
|
|
360
|
+
return [
|
|
361
|
+
"NEXT STEPS",
|
|
362
|
+
...steps.flatMap(
|
|
363
|
+
(step, index) => wrapText(step, REPORT_WIDTH - 5).map(
|
|
364
|
+
(line, wrapped) => ` ${wrapped === 0 ? `${index + 1}.` : " "} ${line}`
|
|
365
|
+
)
|
|
366
|
+
)
|
|
367
|
+
].join("\n");
|
|
451
368
|
}
|
|
452
369
|
function renderNoVerdictPlain(failures) {
|
|
453
370
|
return [
|
|
454
|
-
section(
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
371
|
+
section(
|
|
372
|
+
"NO COVERAGE VERDICT",
|
|
373
|
+
"a scenario did not mount, so nothing reached anything",
|
|
374
|
+
failures.length
|
|
375
|
+
),
|
|
376
|
+
" Every capability those scenarios would have surfaced would be reported unreached,",
|
|
377
|
+
" so no verdict is printed at all. Fix the mount, or name a scenario that works."
|
|
459
378
|
].join("\n");
|
|
460
379
|
}
|
|
461
380
|
function renderFailuresPlain(failures) {
|
|
@@ -465,22 +384,22 @@ function renderFailuresPlain(failures) {
|
|
|
465
384
|
].join("\n");
|
|
466
385
|
}
|
|
467
386
|
function renderDriftPlain(scenario, entries) {
|
|
468
|
-
const lines = [
|
|
387
|
+
const lines = [`${scenario}: ${entries.length} change${entries.length === 1 ? "" : "s"}`];
|
|
469
388
|
for (const entry of entries) {
|
|
470
389
|
const where = entry.subject ? `${entry.subject} (${entry.path})` : entry.path;
|
|
471
|
-
if (entry.kind === "added") lines.push(`
|
|
472
|
-
else if (entry.kind === "removed") lines.push(`
|
|
390
|
+
if (entry.kind === "added") lines.push(` + ${where} ${formatValue(entry.after)}`);
|
|
391
|
+
else if (entry.kind === "removed") lines.push(` - ${where} ${formatValue(entry.before)}`);
|
|
473
392
|
else {
|
|
474
|
-
lines.push(`
|
|
475
|
-
lines.push(`
|
|
476
|
-
lines.push(`
|
|
393
|
+
lines.push(` ~ ${where}`);
|
|
394
|
+
lines.push(` before: ${formatValue(entry.before)}`);
|
|
395
|
+
lines.push(` after: ${formatValue(entry.after)}`);
|
|
477
396
|
}
|
|
478
397
|
}
|
|
479
|
-
return lines
|
|
398
|
+
return lines;
|
|
480
399
|
}
|
|
481
400
|
|
|
482
401
|
// src/report.ts
|
|
483
|
-
import { basename, relative
|
|
402
|
+
import { basename, relative } from "path";
|
|
484
403
|
function scenarioReport(result, options = {}) {
|
|
485
404
|
const view = buildView(result, {
|
|
486
405
|
...options.attribution ? { explain: true } : {},
|
|
@@ -512,7 +431,7 @@ function inventoryReport(inventory, domainCapabilities) {
|
|
|
512
431
|
return {
|
|
513
432
|
...inventory,
|
|
514
433
|
root: ".",
|
|
515
|
-
tsconfig:
|
|
434
|
+
tsconfig: relative(inventory.root, inventory.tsconfig) || "tsconfig.json",
|
|
516
435
|
...domainCapabilities ? { domain: { source: "manifest", capabilities: [...domainCapabilities].sort() } } : {}
|
|
517
436
|
};
|
|
518
437
|
}
|
|
@@ -526,10 +445,15 @@ function coverageReport(report) {
|
|
|
526
445
|
}
|
|
527
446
|
|
|
528
447
|
export {
|
|
448
|
+
renderTablePlain,
|
|
449
|
+
renderReportPlain,
|
|
450
|
+
renderSectionsPlain,
|
|
529
451
|
renderSurfacePlain,
|
|
530
|
-
|
|
452
|
+
renderCatalogDetailPlain,
|
|
531
453
|
renderCoveragePlain,
|
|
454
|
+
renderSurfaceSummaryPlain,
|
|
532
455
|
renderCheckOverviewPlain,
|
|
456
|
+
renderNextStepsPlain,
|
|
533
457
|
renderNoVerdictPlain,
|
|
534
458
|
renderFailuresPlain,
|
|
535
459
|
renderDriftPlain,
|
|
@@ -538,4 +462,4 @@ export {
|
|
|
538
462
|
inventoryReport,
|
|
539
463
|
coverageReport
|
|
540
464
|
};
|
|
541
|
-
//# sourceMappingURL=chunk-
|
|
465
|
+
//# sourceMappingURL=chunk-L7GHSC2Z.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/render/plain.ts","../src/report.ts"],"sourcesContent":["import type { CapabilityRow, SurfaceView } from \"./model.js\";\nimport { flatRows } from \"./model.js\";\nimport {\n coverageSections,\n neverCallable,\n neverCallableSection,\n riskClause,\n runContextRows,\n runHeaderBlocks,\n scenarioTable,\n surfaceSummaryRows,\n unreadSection,\n type FindingSection,\n type ReportBlock,\n type ReportRow,\n type RunContext,\n type ScenarioStats,\n type SurfaceSummaryInput,\n} from \"./summary.js\";\nimport type { DiffEntry } from \"../baseline.js\";\nimport { formatValue } from \"../baseline.js\";\nimport type { ScenarioFailure } from \"../analysis.js\";\nimport { unresolved, type CapabilityInventory } 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/**\n * Where a report's text column starts. Fixed rather than derived, so the\n * `Coverage`/`Baselines` matrix in `check` and the `Config`/`Depth` header\n * above it line up as one grid — a block that indents itself differently reads\n * as a different kind of thing.\n */\nconst LABEL_WIDTH = 12;\nconst STATUS_WIDTH = 7;\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/** The same grid, for a caller that owns its own heading. */\nexport function renderTablePlain(\n headers: string[],\n rows: Array<{ cells: string[]; note?: string }>,\n): string {\n return renderTable(headers, rows).join(\"\\n\");\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\n/**\n * A labelled block: an optional title, then `label STATUS text` rows.\n *\n * The label column is wide enough for the longest label in the report, never\n * narrower than `LABEL_WIDTH`, so every block in one report shares a grid.\n */\nexport function renderReportPlain(blocks: ReportBlock[]): string {\n const width = Math.max(\n LABEL_WIDTH,\n ...blocks.flatMap((block) => block.rows.map((row) => row.label.length + 2)),\n );\n const statuses = blocks.some((block) => block.rows.some((row) => row.status));\n const renderRow = (row: ReportRow): string =>\n `${row.label.padEnd(width)}${\n statuses ? (row.status ?? \"\").padEnd(STATUS_WIDTH) : \"\"\n }${row.text}`.trimEnd();\n\n return blocks\n .filter((block) => block.title || block.rows.length > 0)\n .map((block) => [...(block.title ? [block.title] : []), ...block.rows.map(renderRow)].join(\"\\n\"))\n .join(\"\\n\\n\");\n}\n\n/** Findings, in the order they were built. Tables unindented, lists indented. */\nexport function renderSectionsPlain(sections: FindingSection[]): string {\n return sections\n .map((entry) => {\n const lines = [\n entry.count > 0\n ? section(entry.title, entry.gloss, entry.count)\n : `${entry.title} — ${entry.gloss}`,\n ];\n if (entry.headers && entry.rows) lines.push(...renderTable(entry.headers, entry.rows));\n if (entry.lines) lines.push(...entry.lines.map((line) => ` ${line}`.trimEnd()));\n if (entry.hint) {\n lines.push(\n ...wrapText(entry.hint, REPORT_WIDTH - 4).map(\n (line, index) => ` ${index === 0 ? \"→\" : \" \"} ${line}`,\n ),\n );\n }\n return lines.join(\"\\n\");\n })\n .join(\"\\n\\n\");\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 *\n * The risk clause is the same argument one level up: `9 callable` says how much\n * surface there is and nothing about what it can do, and \"one of these deletes\n * a device\" is the part a reader needs before they read anything else.\n */\nexport function renderCountsPlain(view: SurfaceView): string {\n const risk = riskClause(flatRows(view));\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 (risk ? ` · ${risk}` : \"\")\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(view: SurfaceView, options: SurfaceRenderOptions = {}): 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 run header: the command, what it was pointed at, and what every number\n * below is relative to. Printed before anything is mounted, because a reader\n * watching a slow mount should already know what is being measured.\n */\nexport function renderRunHeaderPlain(\n title: string,\n context: RunContext,\n inventory?: CapabilityInventory,\n domainCapabilities?: number,\n): string {\n return renderReportPlain(runHeaderBlocks(title, context, inventory, domainCapabilities));\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 interface CatalogDetailOptions {\n /** Show the raw call-site table, origins, notes and diagnostic prose. */\n detail?: boolean;\n}\n\n/**\n * The catalog *below* its summary: which component authors what, and every call\n * site the extractor could not read.\n *\n * Only `--depth static` prints this. At `--depth full` the scenario tables name\n * every capability a scenario reached, the `UNREACHED` section names the ones it\n * did not, and the verdict carries the unread call sites — so printing it here\n * would be the same information a second time, above the answer instead of in it.\n */\nexport function renderCatalogDetailPlain(\n inventory: CapabilityInventory,\n options: CatalogDetailOptions = {},\n): string {\n const lines: string[] = [];\n const resolved = inventory.capabilities.filter((c) => c.resolution !== \"unresolved\");\n const unreadEntries = unresolved(inventory);\n\n const components = new Map<string, { ids: Set<string>; sites: number; partial: number }>();\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(`COMPONENTS (${components.size})`);\n lines.push(\n ...renderTable(\n [\"COMPONENT\", \"CAPABILITIES\", \"CALL SITES\", \"DYNAMIC META\"],\n [...components.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .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 if (lines.length > 0) 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()]\n .sort(([a], [b]) => a.localeCompare(b))\n .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 if (lines.length > 0) 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 if (unreadEntries.length > 0) {\n if (lines.length > 0) lines.push(\"\");\n lines.push(renderSectionsPlain([unreadSection(unreadEntries)]));\n }\n } else if (unreadEntries.length > 0 || resolved.length > 0) {\n if (lines.length > 0) 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\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\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 function renderCoveragePlain(\n report: CoverageReport,\n options: CoverageRenderOptions = {},\n): string {\n const sections = coverageSections(report, options);\n return sections.length > 0 ? renderSectionsPlain(sections) : \"\";\n}\n\n/** The closing block, and the findings that belong with it. */\nexport function renderSurfaceSummaryPlain(input: SurfaceSummaryInput): string {\n const dark = neverCallable(input.reach);\n // Over one scenario, \"never callable\" repeats that scenario's own table row\n // for row — see neverCallableSection().\n const mounted = input.scenarios.filter((entry) => !entry.failed).length;\n const sections = [\n ...(input.coverage ? coverageSections(input.coverage) : []),\n ...(dark.length > 0 && mounted > 1 ? [neverCallableSection(dark)] : []),\n ];\n const summary = renderReportPlain([{ title: \"SURFACE SUMMARY\", rows: surfaceSummaryRows(input) }]);\n return sections.length > 0 ? `${renderSectionsPlain(sections)}\\n\\n${summary}` : summary;\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 /** What the run was pointed at. Printed above the matrix (`AS-CLI-007`). */\n context?: RunContext;\n /** Per-scenario totals. Replaces the bare name list when available. */\n stats?: ScenarioStats[];\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/** The health matrix: one row per class of finding, whether or not it fired. */\nfunction checkMatrixRows(input: CheckOverview): ReportRow[] {\n const rows: ReportRow[] = [];\n const coverage = input.coverage;\n\n if (coverage) {\n rows.push({\n label: \"Coverage\",\n status:\n coverage.unreached.length > 0 || coverage.staleAllowlist.length > 0\n ? \"FAIL\"\n : coverage.allowed.length > 0\n ? \"WARN\"\n : \"PASS\",\n text:\n `${coverage.reached}/${coverage.authored} authored capabilities reached` +\n (coverage.unreached.length > 0 ? ` · ${coverage.unreached.length} unreached` : \"\") +\n (coverage.allowed.length > 0 ? ` · ${coverage.allowed.length} unreached allowlisted` : \"\") +\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 rows.push({\n label: \"Catalog\",\n status:\n coverage.staleUnreadAllowlist.length > 0 || (unread > 0 && !input.unresolvedAllowed)\n ? \"FAIL\"\n : unread > 0 || accepted > 0\n ? \"WARN\"\n : \"PASS\",\n text:\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 rows.push({\n label: \"Domain\",\n status:\n coverage.unmanifestedDomain.length > 0\n ? \"FAIL\"\n : coverage.domainAuthoritative\n ? \"PASS\"\n : \"WARN\",\n text:\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 } else {\n rows.push({\n label: \"Coverage\",\n status: input.status === \"ERROR\" ? \"ERROR\" : \"WARN\",\n text:\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 const baselineOk = input.baselineCurrent === input.baselineTotal && input.scenarioManifestOk;\n rows.push({\n label: \"Baselines\",\n status: baselineOk ? \"PASS\" : \"FAIL\",\n text:\n `${input.baselineCurrent}/${input.baselineTotal} scenario baselines current` +\n (input.scenarioManifestOk ? \"\" : \" · scenario manifest differs\"),\n });\n\n rows.push({\n label: \"Runtime\",\n status: input.mountFailures > 0 ? \"ERROR\" : input.rejected > 0 ? \"FAIL\" : \"PASS\",\n text:\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 return rows;\n}\n\n/** First-screen answer for `check`: verdict, context, health, then scenarios. */\nexport function renderCheckOverviewPlain(input: CheckOverview): string {\n const blocks: ReportBlock[] = [\n {\n title: `SURFACE CHECK ${input.status}`,\n rows: input.context ? runContextRows(input.context) : [],\n },\n { rows: checkMatrixRows(input) },\n ];\n\n const table = input.stats ? scenarioTable(input.stats, { baselines: true }) : undefined;\n const scenarios =\n input.stats && table\n ? [`SCENARIOS (${input.stats.length})`, ...renderTable(table.headers, table.rows)]\n : [`SCENARIOS (${input.scenarios.length})`, ...wrappedList(input.scenarios)];\n\n return `${renderReportPlain(blocks)}\\n\\n${scenarios.join(\"\\n\")}`;\n}\n\n/** The commands that clear this report, in the order worth running them. */\nexport function renderNextStepsPlain(steps: string[]): string {\n return [\n \"NEXT STEPS\",\n ...steps.flatMap((step, index) =>\n wrapText(step, REPORT_WIDTH - 5).map(\n (line, wrapped) => ` ${wrapped === 0 ? `${index + 1}.` : \" \"} ${line}`,\n ),\n ),\n ].join(\"\\n\");\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 // The failures themselves are listed directly above, by DID NOT MOUNT. This\n // says what their absence costs the rest of the report, and nothing else.\n return [\n section(\n \"NO COVERAGE VERDICT\",\n \"a scenario did not mount, so nothing reached anything\",\n failures.length,\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\n/** One scenario's drift, unindented — the section renderer owns the indent. */\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;\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"]}
|