@intentset/cli 0.6.1 → 0.7.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 +35 -0
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js +18 -10
- package/dist/agents.js.map +1 -1
- package/dist/commands/evidence-stale.d.ts +19 -0
- package/dist/commands/evidence-stale.d.ts.map +1 -0
- package/dist/commands/evidence-stale.js +118 -0
- package/dist/commands/evidence-stale.js.map +1 -0
- package/dist/commands/evidence.d.ts +7 -0
- package/dist/commands/evidence.d.ts.map +1 -1
- package/dist/commands/evidence.js +19 -2
- package/dist/commands/evidence.js.map +1 -1
- package/dist/commands/graph.js +1 -1
- package/dist/commands/guide.d.ts +5 -0
- package/dist/commands/guide.d.ts.map +1 -0
- package/dist/commands/guide.js +16 -0
- package/dist/commands/guide.js.map +1 -0
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +11 -3
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/migrate.d.ts +23 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +125 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/git.d.ts +13 -0
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +26 -0
- package/dist/git.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +146 -44
- package/dist/main.js.map +1 -1
- package/dist/reports.d.ts.map +1 -1
- package/dist/reports.js +26 -3
- package/dist/reports.js.map +1 -1
- package/dist/session.d.ts +8 -2
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +18 -1
- package/dist/session.js.map +1 -1
- package/dist/subject.d.ts +16 -0
- package/dist/subject.d.ts.map +1 -0
- package/dist/subject.js +44 -0
- package/dist/subject.js.map +1 -0
- package/package.json +18 -10
- package/src/agents.ts +18 -10
- package/src/commands/evidence-stale.ts +151 -0
- package/src/commands/evidence.ts +30 -3
- package/src/commands/graph.ts +1 -1
- package/src/commands/guide.ts +17 -0
- package/src/commands/init.ts +12 -3
- package/src/commands/migrate.ts +136 -0
- package/src/git.ts +25 -0
- package/src/index.ts +3 -1
- package/src/main.ts +150 -44
- package/src/reports.ts +27 -3
- package/src/session.ts +26 -1
- package/src/subject.ts +61 -0
package/dist/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAGL,iBAAiB,EAEjB,aAAa,GACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAEL,cAAc,
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { EvidenceBinding, Graph } from "@intentset/core";
|
|
2
|
+
import { type BindingDecision, type Subject, type SubjectSource } from "@intentset/verification";
|
|
3
|
+
import type { Repository } from "./repository.ts";
|
|
4
|
+
import type { Tree } from "./tree.ts";
|
|
5
|
+
/** The binding in force: the option, else the configuration, else the default (Core §8). */
|
|
6
|
+
export declare function bindingFor(repo: Repository, graph: Graph, given: EvidenceBinding | undefined): BindingDecision;
|
|
7
|
+
/** The architecture's resolution over the tree, reading file contents from disk. */
|
|
8
|
+
export declare function sourceFor(repo: Repository, graph: Graph, tree: Tree): SubjectSource;
|
|
9
|
+
export interface Subjects {
|
|
10
|
+
subjects: Map<string, Subject>;
|
|
11
|
+
source: SubjectSource;
|
|
12
|
+
/** Files changed since a commit, asked of git once per commit. */
|
|
13
|
+
changedSince: (commit: string) => string[] | null;
|
|
14
|
+
}
|
|
15
|
+
export declare function subjectsOf(repo: Repository, graph: Graph, tree: Tree): Subjects;
|
|
16
|
+
//# sourceMappingURL=subject.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subject.d.ts","sourceRoot":"","sources":["../src/subject.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EACL,KAAK,eAAe,EAGpB,KAAK,OAAO,EACZ,KAAK,aAAa,EAEnB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,4FAA4F;AAC5F,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,GAAG,SAAS,GAAG,eAAe,CAE9G;AAED,oFAAoF;AACpF,wBAAgB,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,GAAG,aAAa,CAWnF;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,aAAa,CAAC;IACtB,kEAAkE;IAClE,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,EAAE,GAAG,IAAI,CAAC;CACnD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,GAAG,QAAQ,CAW/E"}
|
package/dist/subject.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evidence binding in the CLI (Core §8): which binding is in force for a
|
|
3
|
+
* session, and the subjects it judges by. The file reads are the repository's
|
|
4
|
+
* own working tree, so a subject hashes what is on disk, uncommitted edits
|
|
5
|
+
* included; `evidence import` refuses an uncommitted tree for the commit it
|
|
6
|
+
* records, not for the subject.
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { subjectSource } from "@intentset/architecture";
|
|
11
|
+
import { hasSliceClaims, resolveBinding, subjectsFor, } from "@intentset/verification";
|
|
12
|
+
import { changedSince } from "./git.js";
|
|
13
|
+
/** The binding in force: the option, else the configuration, else the default (Core §8). */
|
|
14
|
+
export function bindingFor(repo, graph, given) {
|
|
15
|
+
return resolveBinding(given ?? repo.config.evidence.binding, hasSliceClaims(graph));
|
|
16
|
+
}
|
|
17
|
+
/** The architecture's resolution over the tree, reading file contents from disk. */
|
|
18
|
+
export function sourceFor(repo, graph, tree) {
|
|
19
|
+
return subjectSource(graph, repo.registries, tree, {
|
|
20
|
+
globalInputs: repo.config.evidence.globalInputs,
|
|
21
|
+
readFile: (path) => {
|
|
22
|
+
try {
|
|
23
|
+
return readFileSync(join(repo.root, path));
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
export function subjectsOf(repo, graph, tree) {
|
|
32
|
+
const source = sourceFor(repo, graph, tree);
|
|
33
|
+
const asked = new Map();
|
|
34
|
+
return {
|
|
35
|
+
subjects: subjectsFor(graph, source),
|
|
36
|
+
source,
|
|
37
|
+
changedSince: (commit) => {
|
|
38
|
+
if (!asked.has(commit))
|
|
39
|
+
asked.set(commit, changedSince(repo.root, commit));
|
|
40
|
+
return asked.get(commit) ?? null;
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=subject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subject.js","sourceRoot":"","sources":["../src/subject.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,EAEL,cAAc,EACd,cAAc,EAGd,WAAW,GACZ,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAIxC,4FAA4F;AAC5F,MAAM,UAAU,UAAU,CAAC,IAAgB,EAAE,KAAY,EAAE,KAAkC;IAC3F,OAAO,cAAc,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;AACtF,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,SAAS,CAAC,IAAgB,EAAE,KAAY,EAAE,IAAU;IAClE,OAAO,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE;QACjD,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY;QAC/C,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;YACjB,IAAI,CAAC;gBACH,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;YAC7C,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AASD,MAAM,UAAU,UAAU,CAAC,IAAgB,EAAE,KAAY,EAAE,IAAU;IACnE,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,IAAI,GAAG,EAA2B,CAAC;IACjD,OAAO;QACL,QAAQ,EAAE,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC;QACpC,MAAM;QACN,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE;YACvB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;gBAAE,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;YAC3E,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;QACnC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentset/cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "The intentset command: validate, graph, architecture check, evidence, impact, review, publish, serve, context, mcp.",
|
|
3
|
+
"version": "0.7.0",
|
|
4
|
+
"description": "The intentset command: validate, graph, architecture check, evidence, impact, review, publish, serve, context, mcp, guide.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"intentset",
|
|
7
|
+
"cli",
|
|
8
|
+
"requirements",
|
|
9
|
+
"traceability",
|
|
10
|
+
"product-model",
|
|
11
|
+
"ai-agents"
|
|
12
|
+
],
|
|
5
13
|
"license": "MIT",
|
|
6
14
|
"type": "module",
|
|
7
15
|
"engines": {
|
|
@@ -31,14 +39,14 @@
|
|
|
31
39
|
"intentset": "./dist/intentset.js"
|
|
32
40
|
},
|
|
33
41
|
"dependencies": {
|
|
34
|
-
"@intentset/core": "^0.
|
|
35
|
-
"@intentset/markset-adapter": "^0.
|
|
36
|
-
"@intentset/architecture": "^0.
|
|
37
|
-
"@intentset/verification": "^0.
|
|
38
|
-
"@intentset/publisher": "^0.
|
|
39
|
-
"@intentset/atlas": "^0.
|
|
40
|
-
"@intentset/mcp": "^0.
|
|
41
|
-
"@intentset/conformance-suite": "^0.
|
|
42
|
+
"@intentset/core": "^0.7.0",
|
|
43
|
+
"@intentset/markset-adapter": "^0.7.0",
|
|
44
|
+
"@intentset/architecture": "^0.7.0",
|
|
45
|
+
"@intentset/verification": "^0.7.0",
|
|
46
|
+
"@intentset/publisher": "^0.7.0",
|
|
47
|
+
"@intentset/atlas": "^0.7.0",
|
|
48
|
+
"@intentset/mcp": "^0.7.0",
|
|
49
|
+
"@intentset/conformance-suite": "^0.7.0"
|
|
42
50
|
},
|
|
43
51
|
"devDependencies": {
|
|
44
52
|
"@modelcontextprotocol/sdk": "^1.32.0"
|
package/src/agents.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* the trailer can never disagree with the toolchain that wrote it.
|
|
10
10
|
*/
|
|
11
11
|
import { ARTIFACT_TYPES, REQUIRED_SECTIONS } from "@intentset/core";
|
|
12
|
+
import { MARKSET_GUIDE_URL } from "@intentset/markset-adapter";
|
|
12
13
|
import { UNCHANGED_TRAILER } from "./git.ts";
|
|
13
14
|
import { TOOL } from "./output.ts";
|
|
14
15
|
|
|
@@ -40,6 +41,7 @@ export function detectPackageManager(files: {
|
|
|
40
41
|
|
|
41
42
|
export function agentGuide(scope: readonly string[], manager: PackageManager = "npm"): string {
|
|
42
43
|
const run = manager === "pnpm" ? "pnpm exec intentset" : "npx intentset";
|
|
44
|
+
const markset = manager === "pnpm" ? "pnpm dlx @markset-lang/cli guide" : "npx @markset-lang/cli guide";
|
|
43
45
|
const isolated =
|
|
44
46
|
manager === "pnpm"
|
|
45
47
|
? "pnpm dlx --package=@intentset/cli --package=typescript@7 intentset ..."
|
|
@@ -57,7 +59,7 @@ promises, which code delivers it and how it is checked. You keep them true as pa
|
|
|
57
59
|
code, so that people can review what the product does without reading every line of what changed.
|
|
58
60
|
|
|
59
61
|
Written by \`intentset init\` (${TOOL.name} ${TOOL.version}). To refresh it, delete it and run
|
|
60
|
-
\`${run} init --agents
|
|
62
|
+
\`${run} init --agents\`; \`${run} guide\` prints it without writing a file.
|
|
61
63
|
|
|
62
64
|
## Before you change code
|
|
63
65
|
|
|
@@ -96,7 +98,9 @@ ${UNCHANGED_TRAILER}: SLICE-...
|
|
|
96
98
|
\`\`\`
|
|
97
99
|
|
|
98
100
|
\`intentset review\` lists every slice whose code changed while its records did not, and this trailer is how a
|
|
99
|
-
commit answers it. Use it only when no behavior changed: a reviewer reads it as your claim.
|
|
101
|
+
commit answers it. Use it only when no behavior changed: a reviewer reads it as your claim. Git reads trailers only
|
|
102
|
+
from a message's last paragraph, so put it there, beside any other trailer such as \`Co-Authored-By\`; in a paragraph
|
|
103
|
+
of its own above them, it is not read.
|
|
100
104
|
|
|
101
105
|
## Never
|
|
102
106
|
|
|
@@ -108,7 +112,7 @@ commit answers it. Use it only when no behavior changed: a reviewer reads it as
|
|
|
108
112
|
\`.intentset/registries.yaml\`. Ask instead.
|
|
109
113
|
- Treat a passing check as the outcome achieved. Verification says the behavior was built as described; a measure
|
|
110
114
|
says whether building it produced the outcome, and only evidence read in its window answers that.
|
|
111
|
-
- Commit run evidence (\`.intentset/evidence/\`) or an export. They describe one
|
|
115
|
+
- Commit run evidence (\`.intentset/evidence/\`) or an export. They describe one run and go stale as the code it checks changes.
|
|
112
116
|
- Edit generated output: an export, the Atlas, published pages.
|
|
113
117
|
|
|
114
118
|
## Before you finish
|
|
@@ -125,19 +129,23 @@ or with the trailer. The architecture check needs TypeScript 7; on an earlier Ty
|
|
|
125
129
|
|
|
126
130
|
## Record format
|
|
127
131
|
|
|
128
|
-
A record is Markdown with YAML frontmatter under \`intentset
|
|
129
|
-
|
|
132
|
+
A record is a Markset document: Markdown with YAML frontmatter under \`intentset:\` beside \`markset: 0\`, and its
|
|
133
|
+
level-one heading repeats its title. Plain Markdown is valid Markset. For the rest of Markset's syntax, the cards,
|
|
134
|
+
callouts, tables and other constructs a record may use and the codes \`validate\` reports for them, read Markset's
|
|
135
|
+
guide at ${MARKSET_GUIDE_URL}, or print it with \`${markset}\`.
|
|
136
|
+
|
|
137
|
+
An existing record of the same type in this repository is the best template; a new behavior looks like this, one
|
|
130
138
|
recognizable promise including how it fails:
|
|
131
139
|
|
|
132
140
|
\`\`\`markdown
|
|
133
141
|
---
|
|
134
142
|
markset: 0
|
|
135
143
|
intentset:
|
|
136
|
-
spec: '0.
|
|
137
|
-
profile: intentset/behavior/0.
|
|
144
|
+
spec: '0.2'
|
|
145
|
+
profile: intentset/behavior/0.2
|
|
138
146
|
id: BEH-AREA-NAME
|
|
139
147
|
type: behavior
|
|
140
|
-
title: The promise in a few words, such as Schedule
|
|
148
|
+
title: The promise in a few words, such as Schedule a student assessment
|
|
141
149
|
status: draft
|
|
142
150
|
owner: <an owner from the registry>
|
|
143
151
|
visibility: internal
|
|
@@ -153,7 +161,7 @@ intentset:
|
|
|
153
161
|
flags: []
|
|
154
162
|
---
|
|
155
163
|
|
|
156
|
-
# The promise in a few words, such as Schedule
|
|
164
|
+
# The promise in a few words, such as Schedule a student assessment
|
|
157
165
|
|
|
158
166
|
## Behavior
|
|
159
167
|
Who acts, and what the system does.
|
|
@@ -202,6 +210,6 @@ Each type requires these level-two sections:
|
|
|
202
210
|
|---|---|
|
|
203
211
|
${sections.join("\n")}
|
|
204
212
|
|
|
205
|
-
The specifications are at https://intentset.org/specifications
|
|
213
|
+
The specifications are at [intentset.org/specifications](https://intentset.org/specifications/).
|
|
206
214
|
`;
|
|
207
215
|
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `intentset evidence stale` (ADR 0013, "Slow suites"): the automated
|
|
3
|
+
* verifications whose evidence at this snapshot is not a current pass, as a
|
|
4
|
+
* table, as JSON, or as the arguments a test runner takes to run just those
|
|
5
|
+
* tests. Subject binding says exactly which records went stale, so a slow suite
|
|
6
|
+
* runs what a change could have moved and not everything. A person's review is
|
|
7
|
+
* not something a runner re-runs, so manual verifications are listed apart.
|
|
8
|
+
* Never writes. Exit 0 whatever it finds, 1 with --check when an automated
|
|
9
|
+
* verification needs a run, 2 for an invocation or tool failure.
|
|
10
|
+
*/
|
|
11
|
+
import { compareStrings } from "@intentset/core";
|
|
12
|
+
import {
|
|
13
|
+
RUNNER_FORMATS,
|
|
14
|
+
type RunnerFormat,
|
|
15
|
+
runnerArguments,
|
|
16
|
+
type StaleEntry,
|
|
17
|
+
type StaleReport,
|
|
18
|
+
staleReport,
|
|
19
|
+
staleSummary,
|
|
20
|
+
} from "@intentset/verification";
|
|
21
|
+
import { count, type Io, json, snapshotLine } from "../output.ts";
|
|
22
|
+
import type { Session } from "../session.ts";
|
|
23
|
+
import { parseRelease } from "./graph.ts";
|
|
24
|
+
|
|
25
|
+
export const STALE_FORMATS = ["list", "json", ...RUNNER_FORMATS] as const;
|
|
26
|
+
export type StaleFormat = (typeof STALE_FORMATS)[number];
|
|
27
|
+
|
|
28
|
+
export interface EvidenceStaleOptions {
|
|
29
|
+
/** `<product>:<label>`, the scope evidence is assessed for. */
|
|
30
|
+
release?: string;
|
|
31
|
+
format?: string;
|
|
32
|
+
check: boolean;
|
|
33
|
+
json: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Problems that need no repository, so a typo costs nothing. Returns the format on success. */
|
|
37
|
+
export function evidenceStaleUsageProblem(
|
|
38
|
+
options: EvidenceStaleOptions,
|
|
39
|
+
): { problem: string } | { format: StaleFormat } {
|
|
40
|
+
const format = options.format ?? (options.json ? "json" : "list");
|
|
41
|
+
if (!(STALE_FORMATS as readonly string[]).includes(format)) {
|
|
42
|
+
return { problem: `--format ${format}: the formats are ${STALE_FORMATS.join(", ")}` };
|
|
43
|
+
}
|
|
44
|
+
if (options.json && format !== "json") {
|
|
45
|
+
return { problem: `--json is --format json; it does not combine with --format ${format}` };
|
|
46
|
+
}
|
|
47
|
+
if (options.release !== undefined && parseRelease(options.release) === null) {
|
|
48
|
+
return {
|
|
49
|
+
problem: `--release ${options.release}: give a product and a release label as <product>:<label>, such as PRD-LANTERN:pilot-1`,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return { format: format as StaleFormat };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function evidenceStaleCommand(
|
|
56
|
+
session: Session,
|
|
57
|
+
format: StaleFormat,
|
|
58
|
+
options: EvidenceStaleOptions,
|
|
59
|
+
io: Io,
|
|
60
|
+
): number {
|
|
61
|
+
const evidence = session.evidence;
|
|
62
|
+
if (evidence === undefined) {
|
|
63
|
+
io.stderr("intentset evidence stale: run records were not read; evidence is judged at L3 and above.\n");
|
|
64
|
+
return 2;
|
|
65
|
+
}
|
|
66
|
+
const release = options.release === undefined ? null : parseRelease(options.release);
|
|
67
|
+
if (release !== null && session.result.graph.artifacts.get(release.product)?.meta.type !== "product") {
|
|
68
|
+
io.stderr(`intentset evidence stale: --release names ${release.product}, which is not a product in this graph.\n`);
|
|
69
|
+
return 2;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const report = staleReport(session.result.graph, evidence.check.classification);
|
|
73
|
+
const summary = staleSummary(report.counts);
|
|
74
|
+
|
|
75
|
+
if (format === "json") {
|
|
76
|
+
io.stdout(
|
|
77
|
+
json({
|
|
78
|
+
snapshot: session.snapshot,
|
|
79
|
+
binding: evidence.binding.binding,
|
|
80
|
+
needRun: report.needRun,
|
|
81
|
+
manual: report.manual,
|
|
82
|
+
counts: report.counts,
|
|
83
|
+
}),
|
|
84
|
+
);
|
|
85
|
+
} else if (format === "list") {
|
|
86
|
+
io.stdout(renderList(session, report, summary));
|
|
87
|
+
} else {
|
|
88
|
+
// One line to paste or capture; the reading goes to stderr so `$(...)` holds only the arguments.
|
|
89
|
+
io.stdout(`${runnerArguments(format as RunnerFormat, report.needRun)}\n`);
|
|
90
|
+
io.stderr(`${summary}\n`);
|
|
91
|
+
}
|
|
92
|
+
for (const line of cautions(session)) io.stderr(`${line}\n`);
|
|
93
|
+
return options.check && report.counts.needRun > 0 ? 1 : 0;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** What a reader should know before trusting a short list, said on stderr so it never lands in a captured line. */
|
|
97
|
+
function cautions(session: Session): string[] {
|
|
98
|
+
const lines: string[] = [];
|
|
99
|
+
if (session.evidence !== undefined && session.evidence.records === 0) {
|
|
100
|
+
lines.push(
|
|
101
|
+
"intentset evidence stale: no run records were read, so every automated verification reads as missing; give --evidence <file>, or import a run into .intentset/evidence/.",
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
const other = session.diagnostics.filter((d) => d.severity === "error" && d.origin !== "evidence").length;
|
|
105
|
+
if (other > 0) {
|
|
106
|
+
lines.push(
|
|
107
|
+
`intentset evidence stale: the graph has ${count(other, "validation error")}, so it may be incomplete; run \`intentset validate\`.`,
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
return lines;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function renderList(session: Session, report: StaleReport, summary: string): string {
|
|
114
|
+
const evidence = session.evidence;
|
|
115
|
+
const lines = [snapshotLine(session.snapshot)];
|
|
116
|
+
if (evidence !== undefined) {
|
|
117
|
+
const why =
|
|
118
|
+
evidence.binding.reason === "default"
|
|
119
|
+
? " (the default, since slices claim files)"
|
|
120
|
+
: evidence.binding.reason === "no-slices"
|
|
121
|
+
? ", because no slice claims files"
|
|
122
|
+
: ", as configured";
|
|
123
|
+
lines.push(`Binding: ${evidence.binding.binding}${why}`);
|
|
124
|
+
}
|
|
125
|
+
lines.push("");
|
|
126
|
+
|
|
127
|
+
const byFile = new Map<string, StaleEntry[]>();
|
|
128
|
+
for (const entry of report.needRun) byFile.set(entry.locator, [...(byFile.get(entry.locator) ?? []), entry]);
|
|
129
|
+
if (byFile.size === 0) lines.push("Nothing automated needs a run.", "");
|
|
130
|
+
for (const file of [...byFile.keys()].sort(compareStrings)) {
|
|
131
|
+
lines.push(file);
|
|
132
|
+
const entries = byFile.get(file) as StaleEntry[];
|
|
133
|
+
const width = Math.max(...entries.map((entry) => entry.status.length));
|
|
134
|
+
for (const entry of entries) {
|
|
135
|
+
lines.push(` ${entry.status.padEnd(width)} ${entry.selector} ${entry.verification}`);
|
|
136
|
+
if (entry.note !== undefined) lines.push(` ${entry.note}`);
|
|
137
|
+
}
|
|
138
|
+
lines.push("");
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (report.manual.length > 0) {
|
|
142
|
+
lines.push(`Manual, not re-run by a runner (${report.manual.length}):`);
|
|
143
|
+
for (const entry of report.manual) {
|
|
144
|
+
lines.push(` ${entry.verification} ${entry.status} ${entry.locator}`);
|
|
145
|
+
if (entry.note !== undefined) lines.push(` ${entry.note}`);
|
|
146
|
+
}
|
|
147
|
+
lines.push("");
|
|
148
|
+
}
|
|
149
|
+
lines.push(summary);
|
|
150
|
+
return `${lines.join("\n")}\n`;
|
|
151
|
+
}
|
package/src/commands/evidence.ts
CHANGED
|
@@ -10,14 +10,24 @@
|
|
|
10
10
|
import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
11
11
|
import { dirname, resolve } from "node:path";
|
|
12
12
|
import { pathToFileURL } from "node:url";
|
|
13
|
-
import { compareStrings } from "@intentset/core";
|
|
14
|
-
import {
|
|
13
|
+
import { compareStrings, type EvidenceBinding } from "@intentset/core";
|
|
14
|
+
import {
|
|
15
|
+
type ParsedRun,
|
|
16
|
+
isUtcTimestamp,
|
|
17
|
+
parseNodeTap,
|
|
18
|
+
parsePlaywrightJson,
|
|
19
|
+
parseVitestJson,
|
|
20
|
+
toRunRecords,
|
|
21
|
+
} from "@intentset/verification";
|
|
15
22
|
import { count, type Io } from "../output.ts";
|
|
16
23
|
import { outputProblem } from "../outputs.ts";
|
|
17
24
|
import type { Session } from "../session.ts";
|
|
25
|
+
import { bindingFor, subjectsOf } from "../subject.ts";
|
|
26
|
+
import { readTree } from "../tree.ts";
|
|
18
27
|
|
|
19
28
|
export const REPORTERS = {
|
|
20
29
|
vitest: { tool: "vitest", parse: (text: string) => parseVitestJson(JSON.parse(text)) },
|
|
30
|
+
playwright: { tool: "playwright", parse: (text: string) => parsePlaywrightJson(JSON.parse(text)) },
|
|
21
31
|
"node-tap": { tool: "node:test", parse: (text: string) => parseNodeTap(text) },
|
|
22
32
|
} as const;
|
|
23
33
|
|
|
@@ -32,6 +42,8 @@ export interface EvidenceImportOptions {
|
|
|
32
42
|
finishedAt?: string;
|
|
33
43
|
uriBase?: string;
|
|
34
44
|
toolVersion?: string;
|
|
45
|
+
/** Overrides evidence.binding of the configuration (Core §8). */
|
|
46
|
+
binding?: EvidenceBinding;
|
|
35
47
|
}
|
|
36
48
|
|
|
37
49
|
const URI = /^[A-Za-z][A-Za-z0-9+.-]*:\S+$/;
|
|
@@ -39,7 +51,7 @@ const URI = /^[A-Za-z][A-Za-z0-9+.-]*:\S+$/;
|
|
|
39
51
|
/** Problems that need no repository, so a typo costs nothing. */
|
|
40
52
|
export function evidenceUsageProblem(options: EvidenceImportOptions): string | null {
|
|
41
53
|
if (options.from === undefined || !Object.hasOwn(REPORTERS, options.from)) {
|
|
42
|
-
return `--from ${options.from ?? "(missing)"}: the reporters are ${Object.keys(REPORTERS).join("
|
|
54
|
+
return `--from ${options.from ?? "(missing)"}: the reporters are ${Object.keys(REPORTERS).join(", ")}`;
|
|
43
55
|
}
|
|
44
56
|
if (options.report === undefined) return "a report file is required: evidence import --from <reporter> <report>";
|
|
45
57
|
for (const [flag, value] of [
|
|
@@ -119,6 +131,15 @@ export function evidenceImportCommand(session: Session, options: EvidenceImportO
|
|
|
119
131
|
else verifications.set(selector, id);
|
|
120
132
|
}
|
|
121
133
|
|
|
134
|
+
// Core §8: where subject binding is in force each record carries its verification's subject hash; otherwise the
|
|
135
|
+
// records are what they always were. The commit and graph hash go in either way, as provenance.
|
|
136
|
+
const decision = bindingFor(repo, graph, options.binding);
|
|
137
|
+
let subjectHashes: Map<string, string> | undefined;
|
|
138
|
+
if (decision.binding === "subject") {
|
|
139
|
+
const { subjects } = subjectsOf(repo, graph, readTree(repo.root, repo.config));
|
|
140
|
+
subjectHashes = new Map([...subjects].map(([id, subject]) => [id, subject.hash]));
|
|
141
|
+
}
|
|
142
|
+
|
|
122
143
|
const startedAt = options.startedAt ?? modified;
|
|
123
144
|
const finishedAt = options.finishedAt ?? modified;
|
|
124
145
|
let converted: ReturnType<typeof toRunRecords>;
|
|
@@ -133,6 +154,7 @@ export function evidenceImportCommand(session: Session, options: EvidenceImportO
|
|
|
133
154
|
startedAt,
|
|
134
155
|
finishedAt,
|
|
135
156
|
uriBase: options.uriBase ?? pathToFileURL(reportFile).href,
|
|
157
|
+
...(subjectHashes === undefined ? {} : { subjects: subjectHashes }),
|
|
136
158
|
});
|
|
137
159
|
} catch (error) {
|
|
138
160
|
return fail((error as Error).message);
|
|
@@ -147,6 +169,11 @@ export function evidenceImportCommand(session: Session, options: EvidenceImportO
|
|
|
147
169
|
const lines = [
|
|
148
170
|
`Imported ${count(converted.records.length, "run record")} from ${options.report} (${options.from}, ${count(parsed.tests.length, "test")}) into ${options.out}`,
|
|
149
171
|
` bound to commit ${snapshot.commit}, graph ${snapshot.graphHash}, for ${product} ${release}, environment ${options.environment ?? "local"}`,
|
|
172
|
+
decision.binding === "subject"
|
|
173
|
+
? ` binding: subject (${decision.reason === "default" ? "the default, since slices claim files" : "as configured"}); each record carries the hash of its verification's subject, and stays current while that is unchanged. The commit above is provenance.`
|
|
174
|
+
: decision.reason === "no-slices"
|
|
175
|
+
? " binding: commit; no slice claims files, so there is no subject to bind to (EVID004). Each record is current only at that commit and graph hash."
|
|
176
|
+
: " binding: commit, as configured. Each record is current only at that commit and graph hash.",
|
|
150
177
|
];
|
|
151
178
|
if (options.startedAt === undefined || options.finishedAt === undefined) {
|
|
152
179
|
lines.push(
|
package/src/commands/graph.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `intentset graph --format json` (spec/export.md, Core §12): the
|
|
3
|
-
* `intentset/export/0.
|
|
3
|
+
* `intentset/export/0.4` envelope over the validated repository, with the
|
|
4
4
|
* report sections `--report` asks for. Printed to stdout, or written to the
|
|
5
5
|
* one file `--out` names, which may not be any file the repository reads.
|
|
6
6
|
* A failing validation still exports, with `validation.status: "fail"`, and
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `intentset guide`: print the agent guide for the repository, the text
|
|
3
|
+
* `init` writes to `.intentset/agents.md`, without writing anything. An agent
|
|
4
|
+
* loads the guide this way when the repository has none yet, or to read the
|
|
5
|
+
* one the installed toolchain would write now. The scope is the one the
|
|
6
|
+
* repository's config names, or init's default where there is no config.
|
|
7
|
+
*/
|
|
8
|
+
import { resolve } from "node:path";
|
|
9
|
+
import type { Io } from "../output.ts";
|
|
10
|
+
import { findRoot } from "../repository.ts";
|
|
11
|
+
import { guideFor } from "./init.ts";
|
|
12
|
+
|
|
13
|
+
export function guideCommand(options: { root?: string }, io: Io): number {
|
|
14
|
+
const root = findRoot(io.cwd, options.root) ?? resolve(io.cwd, options.root ?? ".");
|
|
15
|
+
io.stdout(guideFor(root));
|
|
16
|
+
return 0;
|
|
17
|
+
}
|
package/src/commands/init.ts
CHANGED
|
@@ -129,15 +129,24 @@ export async function initCommand(options: InitOptions, io: Io): Promise<number>
|
|
|
129
129
|
return 0;
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
/**
|
|
133
|
-
|
|
132
|
+
/**
|
|
133
|
+
* The agent guide for the repository at root: for the scope its config names,
|
|
134
|
+
* or the default with no readable config, and run through its package manager.
|
|
135
|
+
* What `init --agents` writes and `intentset guide` prints.
|
|
136
|
+
*/
|
|
137
|
+
export function guideFor(root: string): string {
|
|
134
138
|
let scope = [DEFAULT_INIT_SCOPE];
|
|
135
139
|
const configFile = join(root, CONFIG_PATH);
|
|
136
140
|
if (existsSync(configFile)) {
|
|
137
141
|
const { config, diagnostics } = readConfig(readFileSync(configFile, "utf8"), CONFIG_PATH);
|
|
138
142
|
if (diagnostics.length === 0 && config.scope.length > 0) scope = config.scope;
|
|
139
143
|
}
|
|
140
|
-
|
|
144
|
+
return agentGuide(scope, managerAt(root));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** `init --agents`: the guide alone. */
|
|
148
|
+
function writeGuideOnly(root: string, io: Io): number {
|
|
149
|
+
if (!create(root, new Map([[AGENT_GUIDE_PATH, guideFor(root)]]), io)) return 2;
|
|
141
150
|
pointers(io);
|
|
142
151
|
return 0;
|
|
143
152
|
}
|