@intentset/cli 0.1.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.
Files changed (116) hide show
  1. package/dist/commands/architecture.d.ts +6 -0
  2. package/dist/commands/architecture.d.ts.map +1 -0
  3. package/dist/commands/architecture.js +65 -0
  4. package/dist/commands/architecture.js.map +1 -0
  5. package/dist/commands/context.d.ts +4 -0
  6. package/dist/commands/context.d.ts.map +1 -0
  7. package/dist/commands/context.js +124 -0
  8. package/dist/commands/context.js.map +1 -0
  9. package/dist/commands/evidence.d.ts +29 -0
  10. package/dist/commands/evidence.d.ts.map +1 -0
  11. package/dist/commands/evidence.js +157 -0
  12. package/dist/commands/evidence.js.map +1 -0
  13. package/dist/commands/graph.d.ts +18 -0
  14. package/dist/commands/graph.d.ts.map +1 -0
  15. package/dist/commands/graph.js +77 -0
  16. package/dist/commands/graph.js.map +1 -0
  17. package/dist/commands/impact.d.ts +20 -0
  18. package/dist/commands/impact.d.ts.map +1 -0
  19. package/dist/commands/impact.js +92 -0
  20. package/dist/commands/impact.js.map +1 -0
  21. package/dist/commands/init.d.ts +18 -0
  22. package/dist/commands/init.d.ts.map +1 -0
  23. package/dist/commands/init.js +122 -0
  24. package/dist/commands/init.js.map +1 -0
  25. package/dist/commands/mcp.d.ts +24 -0
  26. package/dist/commands/mcp.d.ts.map +1 -0
  27. package/dist/commands/mcp.js +122 -0
  28. package/dist/commands/mcp.js.map +1 -0
  29. package/dist/commands/publish.d.ts +19 -0
  30. package/dist/commands/publish.d.ts.map +1 -0
  31. package/dist/commands/publish.js +98 -0
  32. package/dist/commands/publish.js.map +1 -0
  33. package/dist/commands/review.d.ts +29 -0
  34. package/dist/commands/review.d.ts.map +1 -0
  35. package/dist/commands/review.js +147 -0
  36. package/dist/commands/review.js.map +1 -0
  37. package/dist/commands/serve.d.ts +14 -0
  38. package/dist/commands/serve.d.ts.map +1 -0
  39. package/dist/commands/serve.js +246 -0
  40. package/dist/commands/serve.js.map +1 -0
  41. package/dist/commands/shared.d.ts +19 -0
  42. package/dist/commands/shared.d.ts.map +1 -0
  43. package/dist/commands/shared.js +43 -0
  44. package/dist/commands/shared.js.map +1 -0
  45. package/dist/commands/validate.d.ts +11 -0
  46. package/dist/commands/validate.d.ts.map +1 -0
  47. package/dist/commands/validate.js +38 -0
  48. package/dist/commands/validate.js.map +1 -0
  49. package/dist/git.d.ts +25 -0
  50. package/dist/git.d.ts.map +1 -0
  51. package/dist/git.js +63 -0
  52. package/dist/git.js.map +1 -0
  53. package/dist/glob.d.ts +16 -0
  54. package/dist/glob.d.ts.map +1 -0
  55. package/dist/glob.js +60 -0
  56. package/dist/glob.js.map +1 -0
  57. package/dist/index.d.ts +9 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +8 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/intentset.d.ts +3 -0
  62. package/dist/intentset.d.ts.map +1 -0
  63. package/dist/intentset.js +15 -0
  64. package/dist/intentset.js.map +1 -0
  65. package/dist/main.d.ts +5 -0
  66. package/dist/main.d.ts.map +1 -0
  67. package/dist/main.js +406 -0
  68. package/dist/main.js.map +1 -0
  69. package/dist/output.d.ts +38 -0
  70. package/dist/output.d.ts.map +1 -0
  71. package/dist/output.js +53 -0
  72. package/dist/output.js.map +1 -0
  73. package/dist/outputs.d.ts +17 -0
  74. package/dist/outputs.d.ts.map +1 -0
  75. package/dist/outputs.js +70 -0
  76. package/dist/outputs.js.map +1 -0
  77. package/dist/reports.d.ts +16 -0
  78. package/dist/reports.d.ts.map +1 -0
  79. package/dist/reports.js +89 -0
  80. package/dist/reports.js.map +1 -0
  81. package/dist/repository.d.ts +56 -0
  82. package/dist/repository.d.ts.map +1 -0
  83. package/dist/repository.js +191 -0
  84. package/dist/repository.js.map +1 -0
  85. package/dist/session.d.ts +61 -0
  86. package/dist/session.d.ts.map +1 -0
  87. package/dist/session.js +202 -0
  88. package/dist/session.js.map +1 -0
  89. package/dist/tree.d.ts +15 -0
  90. package/dist/tree.d.ts.map +1 -0
  91. package/dist/tree.js +56 -0
  92. package/dist/tree.js.map +1 -0
  93. package/package.json +46 -0
  94. package/src/commands/architecture.ts +77 -0
  95. package/src/commands/context.ts +142 -0
  96. package/src/commands/evidence.ts +180 -0
  97. package/src/commands/graph.ts +89 -0
  98. package/src/commands/impact.ts +97 -0
  99. package/src/commands/init.ts +138 -0
  100. package/src/commands/mcp.ts +143 -0
  101. package/src/commands/publish.ts +119 -0
  102. package/src/commands/review.ts +155 -0
  103. package/src/commands/serve.ts +261 -0
  104. package/src/commands/shared.ts +46 -0
  105. package/src/commands/validate.ts +39 -0
  106. package/src/git.ts +81 -0
  107. package/src/glob.ts +58 -0
  108. package/src/index.ts +8 -0
  109. package/src/intentset.ts +15 -0
  110. package/src/main.ts +408 -0
  111. package/src/output.ts +78 -0
  112. package/src/outputs.ts +65 -0
  113. package/src/reports.ts +103 -0
  114. package/src/repository.ts +220 -0
  115. package/src/session.ts +276 -0
  116. package/src/tree.ts +64 -0
@@ -0,0 +1,6 @@
1
+ import { type Io } from "../output.ts";
2
+ import type { Session } from "../session.ts";
3
+ export declare function architectureCommand(session: Session, options: {
4
+ writeBaseline?: string;
5
+ }, asJson: boolean, io: Io): number;
6
+ //# sourceMappingURL=architecture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"architecture.d.ts","sourceRoot":"","sources":["../../src/commands/architecture.ts"],"names":[],"mappings":"AAWA,OAAO,EAA2B,KAAK,EAAE,EAAc,MAAM,cAAc,CAAC;AAG5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,EACnC,MAAM,EAAE,OAAO,EACf,EAAE,EAAE,EAAE,GACL,MAAM,CAuDR"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * `intentset architecture check` (VSA §2, the profile's boundaries): claims,
3
+ * ownership, the import graph, layers, regions, resources, exceptions and,
4
+ * in migration mode, the baseline, over every file the configuration does
5
+ * not ignore. Diagnostics like validate's, then the summary with what was not
6
+ * checked and what is left to review. `--write-baseline` writes the one file
7
+ * it names. Nothing else is written.
8
+ */
9
+ import { writeFileSync } from "node:fs";
10
+ import { resolve } from "node:path";
11
+ import { writeBaseline } from "@intentset/architecture";
12
+ import { count, formatDiagnostic, json, TOOL } from "../output.js";
13
+ import { outputProblem } from "../outputs.js";
14
+ import { architectureLines } from "../reports.js";
15
+ export function architectureCommand(session, options, asJson, io) {
16
+ const architecture = session.architecture;
17
+ if (architecture === undefined)
18
+ throw new Error("architecture check opened a session below L2");
19
+ const diagnostics = architecture.diagnostics;
20
+ const errors = diagnostics.filter((d) => d.severity === "error").length;
21
+ const warnings = diagnostics.length - errors;
22
+ const outside = session.errors - errors;
23
+ if (options.writeBaseline !== undefined) {
24
+ const target = resolve(io.cwd, options.writeBaseline);
25
+ const problem = outputProblem(session.repo, target);
26
+ if (problem !== null) {
27
+ io.stderr(`intentset architecture check: --write-baseline ${options.writeBaseline} ${problem}; not written.\n`);
28
+ return 2;
29
+ }
30
+ const entries = writeBaseline(diagnostics);
31
+ try {
32
+ writeFileSync(target, `${JSON.stringify(entries, null, 2)}\n`);
33
+ }
34
+ catch (error) {
35
+ io.stderr(`intentset architecture check: could not write ${options.writeBaseline}: ${error.message}\n`);
36
+ return 2;
37
+ }
38
+ io.stderr(`intentset architecture check: wrote ${count(entries.length, "baseline entry", "baseline entries")} to ${options.writeBaseline}\n`);
39
+ }
40
+ if (asJson) {
41
+ io.stdout(json({
42
+ tool: TOOL,
43
+ level: session.level,
44
+ snapshot: session.snapshot,
45
+ summary: architecture.summary,
46
+ skipped: session.tree?.skipped ?? [],
47
+ errors,
48
+ warnings,
49
+ diagnostics,
50
+ validation: { errorsOutsideArchitecture: outside },
51
+ }));
52
+ }
53
+ else {
54
+ for (const d of diagnostics)
55
+ io.stdout(formatDiagnostic(d));
56
+ const lines = [`${count(errors, "error")}, ${count(warnings, "warning")} from the architecture check`];
57
+ if (outside > 0) {
58
+ lines.push(`Validation has ${count(outside, "other error")}, so the graph this checked may be incomplete; run \`intentset validate --level ${session.level}\`.`);
59
+ }
60
+ lines.push(...architectureLines(architecture, session.tree?.skipped ?? []));
61
+ io.stdout(`${lines.join("\n")}\n`);
62
+ }
63
+ return session.errors > 0 ? 1 : 0;
64
+ }
65
+ //# sourceMappingURL=architecture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"architecture.js","sourceRoot":"","sources":["../../src/commands/architecture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type Io } from "../output.ts";
2
+ import type { Session } from "../session.ts";
3
+ export declare function contextCommand(session: Session, id: string, includeRestricted: boolean, asJson: boolean, io: Io): number;
4
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/commands/context.ts"],"names":[],"mappings":"AAqBA,OAAO,EAA2B,KAAK,EAAE,EAA4B,MAAM,cAAc,CAAC;AAC1F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAiB7C,wBAAgB,cAAc,CAC5B,OAAO,EAAE,OAAO,EAChB,EAAE,EAAE,MAAM,EACV,iBAAiB,EAAE,OAAO,EAC1B,MAAM,EAAE,OAAO,EACf,EAAE,EAAE,EAAE,GACL,MAAM,CA2ER"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * `intentset context <ID>` (Core §10): the bounded context an engineer or an
3
+ * agent loads before changing implementation, from core's `contextFor`: for
4
+ * a behavior, its owning slice, rules, scenarios, verifications, the slice's
5
+ * contracts, the decisions, the knowledge explaining it and its navigation
6
+ * parents; for a rule, capability or slice the bundles of the behaviors it
7
+ * reaches; for anything else its direct neighbours. Each artifact comes with
8
+ * its source path and body, and the whole names its snapshot.
9
+ *
10
+ * `restricted` artifacts are withheld unless asked for, and the report says
11
+ * how many, so a short context never reads as a complete one. Never writes.
12
+ */
13
+ import { compareStrings, contextFor, } from "@intentset/core";
14
+ import { count, formatDiagnostic, json, snapshotLine, TOOL } from "../output.js";
15
+ import { unresolved, validationLine, validationSummary } from "./shared.js";
16
+ const HEADINGS = {
17
+ start: "Start",
18
+ owner: "Owning slice",
19
+ behavior: "Behaviors",
20
+ rule: "Rules",
21
+ scenario: "Scenarios",
22
+ verification: "Verification definitions",
23
+ contract: "Contracts",
24
+ decision: "Decisions",
25
+ knowledge: "Knowledge",
26
+ ancestor: "Navigation ancestors",
27
+ neighbour: "Neighbours",
28
+ };
29
+ export function contextCommand(session, id, includeRestricted, asJson, io) {
30
+ const { graph } = session.result;
31
+ const bundle = contextFor(graph, id, { includeRestricted });
32
+ if (bundle === null) {
33
+ const diagnostic = unresolved(id, session);
34
+ if (asJson) {
35
+ io.stdout(json({
36
+ tool: TOOL,
37
+ snapshot: session.snapshot,
38
+ validation: validationSummary(session, session.level),
39
+ start: null,
40
+ diagnostics: [diagnostic],
41
+ }));
42
+ }
43
+ else {
44
+ io.stderr(formatDiagnostic(diagnostic));
45
+ }
46
+ return 1;
47
+ }
48
+ const visible = new Set(bundle.artifacts.map((a) => a.id));
49
+ const full = (a) => graph.artifacts.get(a.id);
50
+ if (asJson) {
51
+ io.stdout(json({
52
+ tool: TOOL,
53
+ snapshot: session.snapshot,
54
+ validation: validationSummary(session, session.level),
55
+ start: id,
56
+ included: bundle.artifacts.length,
57
+ withheld: bundle.withheld,
58
+ restrictedIncluded: includeRestricted,
59
+ artifacts: bundle.artifacts.map((a) => ({
60
+ ...a,
61
+ sourceHash: full(a).sourceHash,
62
+ links: links(graph, full(a), visible),
63
+ body: full(a).body,
64
+ })),
65
+ diagnostics: [],
66
+ }));
67
+ return session.result.ok ? 0 : 1;
68
+ }
69
+ const start = graph.artifacts.get(id);
70
+ const out = [
71
+ `# Context for ${id}`,
72
+ "",
73
+ `Bounded engineering context (Core §10) for ${start.meta.type} ${id}, "${start.meta.title}".`,
74
+ "",
75
+ `- ${snapshotLine(session.snapshot)}`,
76
+ `- ${validationLine(session, session.level)}`,
77
+ `- Included: ${count(bundle.artifacts.length, "artifact")}. ` +
78
+ (includeRestricted
79
+ ? "Restricted artifacts are included, as asked."
80
+ : `Withheld: ${bundle.withheld} restricted${bundle.withheld === 0 ? "" : "; pass --include-restricted to include them"}.`),
81
+ "- Paths are relative to the repository root. The files are authoritative; this is a derived view of them.",
82
+ "",
83
+ ];
84
+ let role = null;
85
+ for (const a of bundle.artifacts) {
86
+ if (a.role !== role) {
87
+ role = a.role;
88
+ out.push(`## ${HEADINGS[role]}`, "");
89
+ }
90
+ out.push(`### ${a.id}: ${a.title}`, "");
91
+ out.push(`- ID: ${a.id}`, `- Type: ${a.type}`, `- Status: ${a.status}`, `- Path: ${a.path}`);
92
+ const linked = links(graph, full(a), visible);
93
+ const kinds = Object.keys(linked).sort(compareStrings);
94
+ if (kinds.length > 0)
95
+ out.push(`- Links: ${kinds.map((k) => `${k} ${linked[k]?.join(", ")}`).join("; ")}`);
96
+ out.push("", ...fenced(full(a).body), "");
97
+ }
98
+ io.stdout(`${out.join("\n").trimEnd()}\n`);
99
+ return session.result.ok ? 0 : 1;
100
+ }
101
+ /** Authored links from `artifact` to artifacts in the context, so nothing withheld is named. */
102
+ function links(graph, artifact, visible) {
103
+ const out = {};
104
+ for (const edge of graph.out.get(artifact.meta.id) ?? []) {
105
+ if (!visible.has(edge.to))
106
+ continue;
107
+ const list = out[edge.kind];
108
+ if (list === undefined)
109
+ out[edge.kind] = [edge.to];
110
+ else if (!list.includes(edge.to))
111
+ list.push(edge.to);
112
+ }
113
+ for (const list of Object.values(out))
114
+ list?.sort(compareStrings);
115
+ return out;
116
+ }
117
+ /** The body verbatim, in a tilde fence longer than any tilde run inside it, so nothing in it can close the fence. */
118
+ function fenced(body) {
119
+ const text = body.replace(/^\s*\n/, "").trimEnd();
120
+ const longest = Math.max(0, ...[...text.matchAll(/~+/g)].map((m) => m[0].length));
121
+ const fence = "~".repeat(Math.max(4, longest + 1));
122
+ return [`${fence}markdown`, text, fence];
123
+ }
124
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/commands/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { type ParsedRun } from "@intentset/verification";
2
+ import { type Io } from "../output.ts";
3
+ import type { Session } from "../session.ts";
4
+ export declare const REPORTERS: {
5
+ readonly vitest: {
6
+ readonly tool: "vitest";
7
+ readonly parse: (text: string) => ParsedRun;
8
+ };
9
+ readonly "node-tap": {
10
+ readonly tool: "node:test";
11
+ readonly parse: (text: string) => ParsedRun;
12
+ };
13
+ };
14
+ export interface EvidenceImportOptions {
15
+ from?: string;
16
+ report?: string;
17
+ out?: string;
18
+ product?: string;
19
+ release?: string;
20
+ environment?: string;
21
+ startedAt?: string;
22
+ finishedAt?: string;
23
+ uriBase?: string;
24
+ toolVersion?: string;
25
+ }
26
+ /** Problems that need no repository, so a typo costs nothing. */
27
+ export declare function evidenceUsageProblem(options: EvidenceImportOptions): string | null;
28
+ export declare function evidenceImportCommand(session: Session, options: EvidenceImportOptions, io: Io): number;
29
+ //# sourceMappingURL=evidence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../../src/commands/evidence.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,KAAK,SAAS,EAA+D,MAAM,yBAAyB,CAAC;AACtH,OAAO,EAAS,KAAK,EAAE,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,eAAO,MAAM,SAAS;aACpB,MAAM;iBAAI,IAAI,EAAE,QAAQ;iBAAE,KAAK,SAAS,MAAM;;aAC9C,UAAU;iBAAI,IAAI,EAAE,WAAW;iBAAE,KAAK,SAAS,MAAM;;CAC7C,CAAC;AAEX,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAID,iEAAiE;AACjE,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,CAyBlF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,EAAE,EAAE,EAAE,GAAG,MAAM,CAiHtG"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * `intentset evidence import` (Core §8): a test runner's report turned into
3
+ * run records bound to this repository's snapshot. A verification's
4
+ * `selector` is matched against each test's full title, and every
5
+ * verification whose selector no test matched is listed, since it gets no
6
+ * record from this run and reads as missing. Evidence must name the commit
7
+ * it ran at, so an unknown commit refuses. Writes the one file `--out` names,
8
+ * and never over an existing one: earlier records are history.
9
+ */
10
+ import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
11
+ import { dirname, resolve } from "node:path";
12
+ import { pathToFileURL } from "node:url";
13
+ import { compareStrings } from "@intentset/core";
14
+ import { isUtcTimestamp, parseNodeTap, parseVitestJson, toRunRecords } from "@intentset/verification";
15
+ import { count } from "../output.js";
16
+ import { outputProblem } from "../outputs.js";
17
+ export const REPORTERS = {
18
+ vitest: { tool: "vitest", parse: (text) => parseVitestJson(JSON.parse(text)) },
19
+ "node-tap": { tool: "node:test", parse: (text) => parseNodeTap(text) },
20
+ };
21
+ const URI = /^[A-Za-z][A-Za-z0-9+.-]*:\S+$/;
22
+ /** Problems that need no repository, so a typo costs nothing. */
23
+ export function evidenceUsageProblem(options) {
24
+ if (options.from === undefined || !Object.hasOwn(REPORTERS, options.from)) {
25
+ return `--from ${options.from ?? "(missing)"}: the reporters are ${Object.keys(REPORTERS).join(" and ")}`;
26
+ }
27
+ if (options.report === undefined)
28
+ return "a report file is required: evidence import --from <reporter> <report>";
29
+ for (const [flag, value] of [
30
+ ["--out", options.out],
31
+ ["--product", options.product],
32
+ ["--release", options.release],
33
+ ]) {
34
+ if (value === undefined || value === "")
35
+ return `${flag} is required`;
36
+ }
37
+ for (const [flag, value] of [
38
+ ["--started-at", options.startedAt],
39
+ ["--finished-at", options.finishedAt],
40
+ ]) {
41
+ if (value !== undefined && !isUtcTimestamp(value)) {
42
+ return `${flag} ${value}: give a UTC time such as 2026-10-02T12:00:00Z`;
43
+ }
44
+ }
45
+ if (options.uriBase !== undefined && !URI.test(options.uriBase)) {
46
+ return `--uri-base ${options.uriBase}: give a URI with a scheme, such as https://ci.example/runs/42`;
47
+ }
48
+ if (options.environment !== undefined && options.environment.trim() === "")
49
+ return "--environment is empty";
50
+ return null;
51
+ }
52
+ export function evidenceImportCommand(session, options, io) {
53
+ const fail = (message) => {
54
+ io.stderr(`intentset evidence import: ${message}\n`);
55
+ return 2;
56
+ };
57
+ const { repo, snapshot, result } = session;
58
+ const graph = result.graph;
59
+ const reporter = REPORTERS[options.from];
60
+ const product = options.product;
61
+ const release = options.release;
62
+ if (snapshot.commit === null) {
63
+ return fail(`evidence must name the commit it ran at, and none could be read: ${snapshot.commitUnavailable}`);
64
+ }
65
+ if (snapshot.uncommitted === true) {
66
+ return fail(`tracked files differ from commit ${snapshot.commit}, so records bound to it would name a commit the run did not test; commit first (Core §8).`);
67
+ }
68
+ if (graph.artifacts.get(product)?.meta.type !== "product") {
69
+ return fail(`--product ${product} is not a product in this graph.`);
70
+ }
71
+ if (repo.registries.releases.length > 0 && !repo.registries.releases.includes(release)) {
72
+ return fail(`--release ${release} is not a release in the registries; labels match exactly (Core §7).`);
73
+ }
74
+ const reportFile = resolve(io.cwd, options.report);
75
+ let parsed;
76
+ let modified;
77
+ try {
78
+ modified = statSync(reportFile).mtime.toISOString();
79
+ parsed = reporter.parse(readFileSync(reportFile, "utf8"));
80
+ }
81
+ catch (error) {
82
+ return fail(`could not read ${options.report} as ${options.from} output: ${error.message}`);
83
+ }
84
+ const target = resolve(io.cwd, options.out);
85
+ const problem = outputProblem(repo, target);
86
+ if (problem !== null)
87
+ return fail(`--out ${options.out} ${problem}; nothing was written.`);
88
+ if (existsSync(target)) {
89
+ return fail(`--out ${options.out} exists; run records are history, so import into a new file.`);
90
+ }
91
+ // Selector -> verification, from the automated verifications that are not retired, first ID winning a shared selector.
92
+ const verifications = new Map();
93
+ const shared = [];
94
+ for (const id of [...graph.artifacts.keys()].sort(compareStrings)) {
95
+ const meta = graph.artifacts.get(id)?.meta;
96
+ if (meta?.type !== "verification" || meta.status === "retired" || meta.verification?.method !== "automated")
97
+ continue;
98
+ const selector = meta.verification.selector;
99
+ if (verifications.has(selector))
100
+ shared.push(`${selector} (${verifications.get(selector)} and ${id})`);
101
+ else
102
+ verifications.set(selector, id);
103
+ }
104
+ const startedAt = options.startedAt ?? modified;
105
+ const finishedAt = options.finishedAt ?? modified;
106
+ let converted;
107
+ try {
108
+ converted = toRunRecords(parsed, {
109
+ verifications,
110
+ commit: snapshot.commit,
111
+ graphHash: snapshot.graphHash,
112
+ environment: options.environment ?? "local",
113
+ scope: { product, release },
114
+ tool: { name: reporter.tool, version: options.toolVersion ?? "unknown" },
115
+ startedAt,
116
+ finishedAt,
117
+ uriBase: options.uriBase ?? pathToFileURL(reportFile).href,
118
+ });
119
+ }
120
+ catch (error) {
121
+ return fail(error.message);
122
+ }
123
+ try {
124
+ mkdirSync(dirname(target), { recursive: true });
125
+ writeFileSync(target, `${JSON.stringify(converted.records, null, 2)}\n`, { flag: "wx" });
126
+ }
127
+ catch (error) {
128
+ return fail(`could not write ${options.out}: ${error.message}`);
129
+ }
130
+ const lines = [
131
+ `Imported ${count(converted.records.length, "run record")} from ${options.report} (${options.from}, ${count(parsed.tests.length, "test")}) into ${options.out}`,
132
+ ` bound to commit ${snapshot.commit}, graph ${snapshot.graphHash}, for ${product} ${release}, environment ${options.environment ?? "local"}`,
133
+ ];
134
+ if (options.startedAt === undefined || options.finishedAt === undefined) {
135
+ lines.push(` timestamps: the report file's modification time, ${modified}, stands in for the run's ` +
136
+ `${options.startedAt === undefined && options.finishedAt === undefined ? "start and finish" : options.startedAt === undefined ? "start" : "finish"}; ` +
137
+ "pass --started-at and --finished-at to record the run's own");
138
+ }
139
+ for (const record of converted.records) {
140
+ lines.push(` ${record.verificationId} ${record.result} ${record.rationale ?? ""}`.trimEnd());
141
+ }
142
+ lines.push(`Unmatched selectors (${converted.unmatched.length}): ${converted.unmatched.length === 0 ? "none" : "no test title carries them, so their verifications get no record from this run and read as missing"}`, ...converted.unmatched.map((selector) => ` - ${selector} (${verifications.get(selector)})`));
143
+ if (shared.length > 0) {
144
+ lines.push(`Selectors shared by two verifications, matched to the first only (${shared.length}):`);
145
+ lines.push(...shared.map((item) => ` - ${item}`));
146
+ }
147
+ if (parsed.problems.length > 0) {
148
+ lines.push(`Problems in the report that no test title carries (${parsed.problems.length}):`);
149
+ lines.push(...parsed.problems.map((item) => ` - ${item}`));
150
+ }
151
+ if (!result.ok) {
152
+ lines.push(`Validation has ${count(session.errors, "error")}; the records are bound to that graph. Run \`intentset validate\`.`);
153
+ }
154
+ io.stdout(`${lines.join("\n")}\n`);
155
+ return result.ok ? 0 : 1;
156
+ }
157
+ //# sourceMappingURL=evidence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence.js","sourceRoot":"","sources":["../../src/commands/evidence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { Io } from "../output.ts";
2
+ import type { Session } from "../session.ts";
3
+ export interface GraphOptions {
4
+ format?: string;
5
+ includeBodies: boolean;
6
+ release?: string;
7
+ out?: string;
8
+ generatedAt?: string;
9
+ }
10
+ /** Check the options that need no repository, so a typo costs nothing. Returns a message, or null. */
11
+ export declare function graphUsageProblem(options: GraphOptions): string | null;
12
+ /** `<product>:<label>`, split at the first colon; the label is opaque and matched exactly (Core §7). */
13
+ export declare function parseRelease(text: string): {
14
+ product: string;
15
+ label: string;
16
+ } | null;
17
+ export declare function graphCommand(session: Session, options: GraphOptions, io: Io): number;
18
+ //# sourceMappingURL=graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/commands/graph.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAKD,sGAAsG;AACtG,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAWtE;AAED,wGAAwG;AACxG,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAOpF;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,EAAE,GAAG,MAAM,CAuCpF"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * `intentset graph --format json` (Core §12): the `intentset/export/0.1`
3
+ * envelope over the validated repository. Printed to stdout, or written to
4
+ * the one file `--out` names, which may not be any file the repository reads.
5
+ * A failing validation still exports, with `validation.status: "fail"`, and
6
+ * exits 1.
7
+ */
8
+ import { writeFileSync } from "node:fs";
9
+ import { resolve } from "node:path";
10
+ import { ID_PATTERN, exportGraph } from "@intentset/core";
11
+ import { outputProblem } from "../outputs.js";
12
+ /** The export schema's generatedAt pattern. */
13
+ const ISO_8601 = /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(?:\.[0-9]+)?(?:Z|[+-][0-9]{2}:[0-9]{2})$/;
14
+ /** Check the options that need no repository, so a typo costs nothing. Returns a message, or null. */
15
+ export function graphUsageProblem(options) {
16
+ if (options.format !== undefined && options.format !== "json") {
17
+ return `--format ${options.format}: the only format is json`;
18
+ }
19
+ if (options.release !== undefined && parseRelease(options.release) === null) {
20
+ return `--release ${options.release}: write it as <product ID>:<label>, such as PRD-LANTERN:pilot-1`;
21
+ }
22
+ if (options.generatedAt !== undefined && !ISO_8601.test(options.generatedAt)) {
23
+ return `--generated-at ${options.generatedAt}: give an ISO 8601 time such as 2026-10-02T12:00:00Z`;
24
+ }
25
+ return null;
26
+ }
27
+ /** `<product>:<label>`, split at the first colon; the label is opaque and matched exactly (Core §7). */
28
+ export function parseRelease(text) {
29
+ const colon = text.indexOf(":");
30
+ if (colon === -1)
31
+ return null;
32
+ const product = text.slice(0, colon);
33
+ const label = text.slice(colon + 1);
34
+ if (!ID_PATTERN.test(product) || label === "")
35
+ return null;
36
+ return { product, label };
37
+ }
38
+ export function graphCommand(session, options, io) {
39
+ const { repo, result, snapshot } = session;
40
+ const release = options.release === undefined ? null : parseRelease(options.release);
41
+ if (release !== null && result.graph.artifacts.get(release.product)?.meta.type !== "product") {
42
+ io.stderr(`intentset graph: --release names ${release.product}, which is not a product in this graph.\n`);
43
+ return 2;
44
+ }
45
+ const envelope = exportGraph(result, repo.registries, {
46
+ repository: repo.config.repository,
47
+ commit: snapshot.commit,
48
+ ...(snapshot.commitUnavailable === undefined ? {} : { commitUnavailable: snapshot.commitUnavailable }),
49
+ scope: repo.config.scope,
50
+ level: session.level,
51
+ release,
52
+ ...(options.generatedAt === undefined ? {} : { generatedAt: options.generatedAt }),
53
+ includeBodies: options.includeBodies,
54
+ });
55
+ const text = `${JSON.stringify(envelope, null, 2)}\n`;
56
+ if (options.out === undefined) {
57
+ io.stdout(text);
58
+ }
59
+ else {
60
+ const target = resolve(io.cwd, options.out);
61
+ const problem = outputProblem(repo, target);
62
+ if (problem !== null) {
63
+ io.stderr(`intentset graph: --out ${options.out} ${problem}; tools never rewrite those.\n`);
64
+ return 2;
65
+ }
66
+ try {
67
+ writeFileSync(target, text);
68
+ }
69
+ catch (error) {
70
+ io.stderr(`intentset graph: could not write ${options.out}: ${error.message}\n`);
71
+ return 2;
72
+ }
73
+ io.stderr(`intentset graph: wrote ${options.out} (${envelope.artifacts.length} artifacts, ${envelope.validation.status})\n`);
74
+ }
75
+ return result.ok ? 0 : 1;
76
+ }
77
+ //# sourceMappingURL=graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/commands/graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * `intentset impact <ID>` (Core §10): what depends on an artifact. Direct
3
+ * dependents apart from candidates further downstream, each with the path
4
+ * that reached it and a reason per step; the start's own rules, contracts and
5
+ * decisions as review context; navigation ancestors. Every report names its
6
+ * snapshot and says that reachability is not proof. Never writes.
7
+ */
8
+ import { type ImpactHit } from "@intentset/core";
9
+ import { type Io } from "../output.ts";
10
+ import type { Session } from "../session.ts";
11
+ export declare const REACHABILITY_NOTE = "Reachability through authored links marks an artifact for review; it is not proof that runtime behavior changed (Core \u00A710).";
12
+ export declare function impactCommand(session: Session, id: string, asJson: boolean, io: Io): number;
13
+ /**
14
+ * A hit's path as authored edges, written in the direction they were authored.
15
+ * A reverse step (`kind←`) is an edge from the step to the node before it, so
16
+ * a chain reads from the hit back to the start: `C --dependsOn--> B --implements--> A`.
17
+ * A context step (`kind→`) is an edge from the start to the hit.
18
+ */
19
+ export declare function pathText(start: string, hit: ImpactHit): string;
20
+ //# sourceMappingURL=impact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impact.d.ts","sourceRoot":"","sources":["../../src/commands/impact.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,KAAK,SAAS,EAA6B,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAoB,KAAK,EAAE,EAA4B,MAAM,cAAc,CAAC;AACnF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAG7C,eAAO,MAAM,iBAAiB,qIACiG,CAAC;AAEhI,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,GAAG,MAAM,CA0C3F;AA2BD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,GAAG,MAAM,CAM9D"}