@appport/assessment 0.0.0-stage → 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.
@@ -0,0 +1,260 @@
1
+ /**
2
+ * The `appport.application-assessment/1` artifact: its shape, its content digest and its verifier
3
+ * (spec/assessment-1.md §3, §6–§8).
4
+ *
5
+ * An assessment describes what a static reading of a repository found. It is not a capability contract, a fulfillment
6
+ * claim, a registry entry or an authorization grant, and nothing in it is verified behavior: `scope` states this, and
7
+ * the verifier rejects an artifact that claims otherwise.
8
+ */
9
+ import { canonicalize, digestOf, isDigest, sha256 } from "@appport/protocol";
10
+ import { lstatSync } from "node:fs";
11
+ import { gitIdentity, isInside, readRepositoryFile, repositoryRoot } from "./files.js";
12
+ export const ASSESSMENT_FORMAT = "appport.application-assessment/1";
13
+ export const SCANNER_VERSION = "appport.assessment-scanner/1";
14
+ /**
15
+ * Scanner 2 adds HTTP-route candidates read from JavaScript and TypeScript (`js.ts`), and needs a format that can say so: `/2`
16
+ * is `/1` plus an `http` operation, an `http-route` entry point and the `js-static` collection method. Scanner 1 is unchanged
17
+ * and still writes `/1`, byte for byte, so every existing assessment (and every extraction that records one's digest) reproduces.
18
+ */
19
+ export const ASSESSMENT_FORMAT_2 = "appport.application-assessment/2";
20
+ export const SCANNER_VERSION_2 = "appport.assessment-scanner/2";
21
+ export const ASSESSMENT_FORMATS = [ASSESSMENT_FORMAT, ASSESSMENT_FORMAT_2];
22
+ /** Which scanner each format is written by; a reader refuses a mismatch. */
23
+ export const SCANNER_OF_FORMAT = { [ASSESSMENT_FORMAT]: SCANNER_VERSION, [ASSESSMENT_FORMAT_2]: SCANNER_VERSION_2 };
24
+ export const TOOL_NAME = "@appport/assessment";
25
+ export const TOOL_VERSION = "0.1.0";
26
+ /**
27
+ * - `observed`: a statement about what the repository text contains at a location (a declaration, a call, a literal).
28
+ * It can be checked by reading the cited lines.
29
+ * - `inferred`: a conclusion drawn from observed evidence by a stated rule (a handler implements an RPC because name and
30
+ * request type match). It cites its basis and may be wrong.
31
+ * - `unknown`: something the assessment looked for and could not determine. It is never evidence that a thing is absent.
32
+ */
33
+ export const EVIDENCE_CLASSES = ["observed", "inferred", "unknown"];
34
+ export const COLLECTION_METHODS = ["scanner", "manifest-parse", "proto-static", "go-static", "path-convention", "git-metadata", "derivation", "js-static"];
35
+ /** Methods only `/2` may use. */
36
+ export const FORMAT_2_METHODS = ["js-static"];
37
+ export const READINESS_CLASSES = ["exposure-candidate", "investigate", "insufficient-evidence"];
38
+ export const CRITERIA = ["entry-point", "implementation", "io-schema", "validation", "authorization", "tests", "reachability-complete", "small-surface"];
39
+ export const CONCERNS = ["outbound-http", "async-work", "writes-state", "unresolved-interface"];
40
+ /** Concerns that prevent `exposure-candidate`; the rest only order candidates. */
41
+ export const BLOCKING_CONCERNS = ["outbound-http", "async-work", "unresolved-interface"];
42
+ /** The evidence id rule: a hash of everything in the record except the id itself. */
43
+ export function evidenceId(record) {
44
+ return `ev-${sha256(canonicalize(record)).slice(0, 16)}`;
45
+ }
46
+ /** The content digest: `digestOf` (RFC 8785, sha256) over the artifact without `digest` and the volatile `assessment`. */
47
+ export function assessmentDigest(artifact) {
48
+ const { digest: _digest, assessment: _volatile, ...content } = artifact;
49
+ return digestOf(content);
50
+ }
51
+ const TOP_LEVEL = ["format", "assessment", "tool", "target", "configuration", "coverage", "evidence", "inventory", "candidates", "recommendation", "findings", "limitations", "questions", "scope", "digest"];
52
+ const EVIDENCE_MEMBERS = ["id", "class", "kind", "location", "subject", "observation", "method", "basis", "limitations"];
53
+ const CANDIDATE_MEMBERS = ["id", "name", "description", "operation", "entryPoints", "implementation", "inputs", "outputs", "dependencies", "sideEffects", "authorization", "validation", "tests", "evidence", "confidence", "readiness", "unknowns", "exposure"];
54
+ const isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
55
+ /** Every evidence reference outside the evidence list: string arrays under a member named `evidence`. */
56
+ function evidenceReferences(value, pointer, out) {
57
+ if (Array.isArray(value))
58
+ value.forEach((v, k) => evidenceReferences(v, `${pointer}/${k}`, out));
59
+ else if (isObject(value))
60
+ for (const [key, v] of Object.entries(value)) {
61
+ if (key === "evidence" && Array.isArray(v))
62
+ v.forEach((id, k) => out.push({ id, pointer: `${pointer}/evidence/${k}` }));
63
+ else
64
+ evidenceReferences(v, `${pointer}/${key}`, out);
65
+ }
66
+ }
67
+ /**
68
+ * Verifies an assessment artifact's integrity and honesty. Without `repository` it checks structure, references,
69
+ * evidence classes and the digest. With `repository` it also checks every observed location against the files: the
70
+ * path exists inside the root, the lines exist, and the subject occurs in them.
71
+ */
72
+ export function verifyAssessment(value, options = {}) {
73
+ const findings = [];
74
+ const add = (code, path, message) => findings.push({ code, path, message });
75
+ if (!isObject(value)) {
76
+ add("ASSESSMENT_MALFORMED", "", "an assessment is a JSON object");
77
+ return { ok: false, findings };
78
+ }
79
+ if (!ASSESSMENT_FORMATS.includes(value.format))
80
+ add("ASSESSMENT_FORMAT", "/format", `unsupported format ${JSON.stringify(value.format)}; this reader implements ${ASSESSMENT_FORMATS.join(" and ")}`);
81
+ for (const key of Object.keys(value))
82
+ if (!TOP_LEVEL.includes(key))
83
+ add("ASSESSMENT_MEMBER", `/${key}`, `undocumented member "${key}"`);
84
+ for (const key of TOP_LEVEL)
85
+ if (!(key in value))
86
+ add("ASSESSMENT_MEMBER", `/${key}`, `missing member "${key}"`);
87
+ if (findings.length)
88
+ return { ok: false, findings };
89
+ const configuredScanner = isObject(value.configuration) ? value.configuration.scanner : undefined;
90
+ if (configuredScanner !== SCANNER_OF_FORMAT[value.format])
91
+ add("ASSESSMENT_SCANNER", "/configuration/scanner", `${String(value.format)} is written by ${SCANNER_OF_FORMAT[value.format]}, not ${JSON.stringify(configuredScanner)}`);
92
+ const evidence = value.evidence;
93
+ const candidates = value.candidates;
94
+ if (!Array.isArray(evidence) || !Array.isArray(candidates)) {
95
+ add("ASSESSMENT_MALFORMED", "/evidence", "evidence and candidates are arrays");
96
+ return { ok: false, findings };
97
+ }
98
+ // Evidence records.
99
+ const byId = new Map();
100
+ evidence.forEach((record, k) => {
101
+ const at = `/evidence/${k}`;
102
+ if (!isObject(record))
103
+ return add("EVIDENCE_MALFORMED", at, "an evidence record is an object");
104
+ for (const key of Object.keys(record))
105
+ if (!EVIDENCE_MEMBERS.includes(key))
106
+ add("EVIDENCE_MEMBER", `${at}/${key}`, `undocumented member "${key}"`);
107
+ const id = record.id;
108
+ if (typeof id !== "string")
109
+ return add("EVIDENCE_MALFORMED", `${at}/id`, "id is a string");
110
+ if (byId.has(id))
111
+ add("EVIDENCE_DUPLICATE", `${at}/id`, `duplicate evidence id ${id}`);
112
+ byId.set(id, record);
113
+ const { id: _id, ...content } = record;
114
+ if (evidenceId(content) !== id)
115
+ add("EVIDENCE_ID", `${at}/id`, `${id} is not the content id of this record`);
116
+ if (!EVIDENCE_CLASSES.includes(record.class))
117
+ add("EVIDENCE_CLASS", `${at}/class`, `unknown evidence class ${JSON.stringify(record.class)}`);
118
+ if (!COLLECTION_METHODS.includes(record.method) || (value.format === ASSESSMENT_FORMAT && FORMAT_2_METHODS.includes(record.method)))
119
+ add("EVIDENCE_METHOD", `${at}/method`, `unknown collection method ${JSON.stringify(record.method)} for ${String(value.format)}`);
120
+ if (typeof record.kind !== "string" || typeof record.observation !== "string")
121
+ add("EVIDENCE_MALFORMED", at, "kind and observation are strings");
122
+ const location = record.location;
123
+ if (location !== undefined) {
124
+ if (!isObject(location) ||
125
+ typeof location.path !== "string" ||
126
+ location.path.startsWith("/") ||
127
+ location.path.split("/").includes("..") ||
128
+ !Number.isInteger(location.startLine) ||
129
+ !Number.isInteger(location.endLine) ||
130
+ location.startLine < 1 ||
131
+ location.endLine < location.startLine)
132
+ add("EVIDENCE_LOCATION", `${at}/location`, "a location is a repository-relative path and a line range starting at 1");
133
+ }
134
+ if (record.class === "observed" && location === undefined && record.method !== "scanner")
135
+ add("EVIDENCE_LOCATION", at, "observed evidence cites a location");
136
+ });
137
+ evidence.forEach((record, k) => {
138
+ if (!isObject(record))
139
+ return;
140
+ const at = `/evidence/${k}`;
141
+ const basis = record.basis;
142
+ if (record.class === "inferred") {
143
+ if (!Array.isArray(basis) || basis.length === 0)
144
+ return add("EVIDENCE_BASIS", `${at}/basis`, "inferred evidence cites its basis");
145
+ if (!basis.some((b) => byId.get(b)?.class === "observed"))
146
+ add("EVIDENCE_BASIS", `${at}/basis`, "inferred evidence cites at least one observed record");
147
+ }
148
+ if (Array.isArray(basis))
149
+ basis.forEach((b, j) => {
150
+ const target = byId.get(b);
151
+ if (!target)
152
+ add("EVIDENCE_REFERENCE", `${at}/basis/${j}`, `unknown evidence ${JSON.stringify(b)}`);
153
+ else if (target.class === "unknown")
154
+ add("EVIDENCE_BASIS", `${at}/basis/${j}`, "an unknown cannot be the basis of anything");
155
+ });
156
+ else if (basis !== undefined)
157
+ add("EVIDENCE_MALFORMED", `${at}/basis`, "basis is an array");
158
+ });
159
+ // References from everywhere else.
160
+ const references = [];
161
+ for (const key of TOP_LEVEL.filter((k) => k !== "evidence"))
162
+ evidenceReferences(value[key], `/${key}`, references);
163
+ for (const { id, pointer } of references)
164
+ if (typeof id !== "string" || !byId.has(id))
165
+ add("EVIDENCE_REFERENCE", pointer, `unknown evidence ${JSON.stringify(id)}`);
166
+ // Candidates and their readiness.
167
+ const candidateIds = new Set();
168
+ candidates.forEach((candidate, k) => {
169
+ const at = `/candidates/${k}`;
170
+ if (!isObject(candidate))
171
+ return add("CANDIDATE_MALFORMED", at, "a candidate is an object");
172
+ for (const key of Object.keys(candidate))
173
+ if (!CANDIDATE_MEMBERS.includes(key))
174
+ add("CANDIDATE_MEMBER", `${at}/${key}`, `undocumented member "${key}"`);
175
+ if (typeof candidate.id !== "string" || candidateIds.has(candidate.id))
176
+ add("CANDIDATE_ID", `${at}/id`, "candidate ids are unique strings");
177
+ else
178
+ candidateIds.add(candidate.id);
179
+ const operation = candidate.operation;
180
+ if (!isObject(operation) || !(operation.kind === "rpc" || (operation.kind === "http" && value.format === ASSESSMENT_FORMAT_2)))
181
+ add("CANDIDATE_OPERATION", `${at}/operation/kind`, `an operation is an rpc${value.format === ASSESSMENT_FORMAT_2 ? " or an http route" : " (http routes are appport.application-assessment/2)"}`);
182
+ const readiness = candidate.readiness;
183
+ if (!isObject(readiness) || !READINESS_CLASSES.includes(readiness.class))
184
+ add("READINESS_CLASS", `${at}/readiness/class`, `readiness is one of ${READINESS_CLASSES.join(", ")}; an assessment never establishes that a capability is verified`);
185
+ const exposure = candidate.exposure;
186
+ if (!isObject(exposure) || exposure.status !== "proposed" || exposure.authoritative !== false)
187
+ add("EXPOSURE_CLAIM", `${at}/exposure`, "an exposure is a non-authoritative proposal");
188
+ });
189
+ // A verified claim anywhere: a string "verified" as any readiness, status, link or confidence.
190
+ const claims = [];
191
+ const scan = (v, pointer) => {
192
+ if (Array.isArray(v))
193
+ v.forEach((x, k) => scan(x, `${pointer}/${k}`));
194
+ else if (isObject(v))
195
+ for (const [key, x] of Object.entries(v))
196
+ (["class", "status", "confidence", "readiness", "link"].includes(key) && x === "verified" ? claims.push(`${pointer}/${key}`) : scan(x, `${pointer}/${key}`));
197
+ };
198
+ scan(candidates, "/candidates");
199
+ scan(value.recommendation, "/recommendation");
200
+ for (const pointer of claims)
201
+ add("VERIFIED_CLAIM", pointer, "an assessment never establishes verified behavior");
202
+ const scope = value.scope;
203
+ if (!isObject(scope) || scope.grantsAuthority !== false || scope.verifiesBehavior !== false || scope.modifiesTarget !== false || Object.keys(scope).length !== 3)
204
+ add("SCOPE_CLAIM", "/scope", "an assessment grants no authority, verifies no behavior and modifies no target");
205
+ const recommendation = value.recommendation;
206
+ if (recommendation !== null) {
207
+ const candidate = isObject(recommendation) ? candidates.find((c) => isObject(c) && c.id === recommendation.candidate) : undefined;
208
+ if (!candidate)
209
+ add("RECOMMENDATION", "/recommendation/candidate", "the recommendation names a candidate in this assessment");
210
+ else if (candidate.readiness?.class !== "exposure-candidate")
211
+ add("RECOMMENDATION", "/recommendation", "only an exposure candidate is recommended");
212
+ }
213
+ if (Array.isArray(value.questions))
214
+ value.questions.forEach((q, k) => {
215
+ if (isObject(q) && q.candidate !== undefined && !candidateIds.has(q.candidate))
216
+ add("QUESTION_REFERENCE", `/questions/${k}/candidate`, "a question names a candidate in this assessment");
217
+ });
218
+ if (!isDigest(value.digest))
219
+ add("DIGEST_FORMAT", "/digest", "digest is sha256:<64 hex>");
220
+ else if (assessmentDigest(value) !== value.digest)
221
+ add("DIGEST_MISMATCH", "/digest", "the content does not match its digest");
222
+ if (options.repository !== undefined)
223
+ verifyLocations(value, options.repository, add);
224
+ return { ok: findings.length === 0, findings };
225
+ }
226
+ function verifyLocations(value, repository, add) {
227
+ const root = repositoryRoot(repository);
228
+ const target = value.target;
229
+ const identity = gitIdentity(root);
230
+ if (target?.revision !== undefined && identity.revision !== target.revision)
231
+ add("REVISION_MISMATCH", "/target/revision", `the repository is at ${identity.revision ?? "an unknown revision"}, the assessment at ${String(target.revision)}`);
232
+ const cache = new Map();
233
+ const lines = (path) => {
234
+ if (!cache.has(path)) {
235
+ try {
236
+ const absolute = `${root}/${path}`;
237
+ cache.set(path, isInside(root, absolute) && lstatSync(absolute).isFile() ? readRepositoryFile(root, path).split("\n") : null);
238
+ }
239
+ catch {
240
+ cache.set(path, null);
241
+ }
242
+ }
243
+ return cache.get(path);
244
+ };
245
+ value.evidence.forEach((record, k) => {
246
+ const location = record.location;
247
+ if (record.class !== "observed" || !location)
248
+ return;
249
+ const at = `/evidence/${k}/location`;
250
+ const file = lines(location.path);
251
+ if (!file)
252
+ return add("LOCATION_MISSING", at, `${location.path} is not a readable file in the repository`);
253
+ if (location.endLine > file.length)
254
+ return add("LOCATION_RANGE", at, `${location.path} has ${file.length} lines; the evidence cites ${location.startLine}-${location.endLine}`);
255
+ const subject = record.subject;
256
+ if (typeof subject === "string" && !file.slice(location.startLine - 1, location.endLine).join("\n").includes(subject))
257
+ add("LOCATION_SUBJECT", at, `${JSON.stringify(subject)} does not occur in ${location.path}:${location.startLine}-${location.endLine}`);
258
+ });
259
+ }
260
+ //# sourceMappingURL=artifact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact.js","sourceRoot":"","sources":["../src/artifact.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ export interface CliIO {
3
+ out: (text: string) => void;
4
+ err: (text: string) => void;
5
+ }
6
+ /** Runs the CLI. Returns the exit status; never calls `process.exit`. */
7
+ export declare function main(argv: string[], io?: CliIO): number;
8
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAwBA,MAAM,WAAW,KAAK;IACpB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAwCD,yEAAyE;AACzE,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAE,KAAkG,GAAG,MAAM,CAuEnJ"}
package/dist/cli.js ADDED
@@ -0,0 +1,162 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `appworks assess <repo> --output <file> [--scanner 1|2] [--force] [--strict]`
4
+ * `appworks verify <file> [--repo <repo>]`
5
+ *
6
+ * Exit status (spec/assessment-1.md §10):
7
+ * 0 assess: an assessment was written (complete or partial; the summary says which). verify: the artifact is valid.
8
+ * 1 a fatal error: the repository cannot be read, the output cannot be written, or (verify) the artifact is invalid.
9
+ * 2 invalid arguments, or an output path that would overwrite a file without --force or lies inside the repository.
10
+ * 3 assess --strict: an assessment was written, but it is partial.
11
+ */
12
+ import { lstatSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
13
+ import { basename, dirname, resolve } from "node:path";
14
+ import { fileURLToPath } from "node:url";
15
+ import { assessRepository } from "./analyze.js";
16
+ import { TOOL_NAME, TOOL_VERSION, verifyAssessment } from "./artifact.js";
17
+ import { RepositoryError, isInside, repositoryRoot } from "./files.js";
18
+ const USAGE = `usage:
19
+ appworks assess <repo> --output <file> [--scanner 1|2] [--force] [--strict]
20
+ --scanner 2 also reads HTTP routes registered in JavaScript and TypeScript and writes appport.application-assessment/2 (default 1)
21
+ appworks verify <file> [--repo <repo>]
22
+ appworks --version`;
23
+ class UsageError extends Error {
24
+ }
25
+ function parse(args, flags, valued) {
26
+ const positional = [];
27
+ const options = {};
28
+ for (let k = 0; k < args.length; k++) {
29
+ const a = args[k];
30
+ if (a.startsWith("--")) {
31
+ const name = a.slice(2);
32
+ if (flags.includes(name))
33
+ options[name] = true;
34
+ else if (valued.includes(name)) {
35
+ const v = args[++k];
36
+ if (v === undefined || v.startsWith("--"))
37
+ throw new UsageError(`--${name} needs a value`);
38
+ options[name] = v;
39
+ }
40
+ else
41
+ throw new UsageError(`unknown option ${a}`);
42
+ }
43
+ else
44
+ positional.push(a);
45
+ }
46
+ return { positional, options };
47
+ }
48
+ function summary(a, output) {
49
+ const by = (cls) => a.candidates.filter((c) => c.readiness.class === cls).length;
50
+ const rec = a.recommendation ? a.candidates.find((c) => c.id === a.recommendation.candidate) : undefined;
51
+ return [
52
+ `${a.coverage.partial ? "Partial assessment" : "Assessment"} of ${a.target.name}${a.target.revision ? ` at ${a.target.revision.slice(0, 12)}` : ""}`,
53
+ ` files: ${a.coverage.filesAnalyzed} analyzed of ${a.coverage.filesSeen}; ${a.coverage.skipped.length} skipped; ${a.coverage.malformed.length} malformed`,
54
+ ...(a.coverage.partial ? [` partial: ${a.coverage.partialReasons.join(", ")}`] : []),
55
+ ` candidates: ${a.candidates.length} (${by("exposure-candidate")} exposure candidates, ${by("investigate")} to investigate, ${by("insufficient-evidence")} with insufficient evidence)`,
56
+ rec
57
+ ? ` recommended: ${rec.name}${rec.exposure.capability ? ` as proposed ${rec.exposure.capability.name}@1 (${rec.exposure.effectBasis.effect})` : ""}; ${a.recommendation.beforeExposure.length} items to resolve before exposure`
58
+ : " recommended: none",
59
+ ` evidence: ${a.evidence.length} records; ${a.findings.length} findings; ${a.questions.length} questions`,
60
+ ` nothing was verified, executed or granted; the target was not modified`,
61
+ ` digest: ${a.digest}`,
62
+ ` written: ${output}`
63
+ ].join("\n");
64
+ }
65
+ /** Runs the CLI. Returns the exit status; never calls `process.exit`. */
66
+ export function main(argv, io = { out: (t) => process.stdout.write(`${t}\n`), err: (t) => process.stderr.write(`${t}\n`) }) {
67
+ const [command, ...rest] = argv;
68
+ try {
69
+ if (command === "--version") {
70
+ io.out(`${TOOL_NAME} ${TOOL_VERSION}`);
71
+ return 0;
72
+ }
73
+ if (command === "assess") {
74
+ const { positional, options } = parse(rest, ["force", "strict"], ["output", "scanner"]);
75
+ if (options.scanner !== undefined && options.scanner !== "1" && options.scanner !== "2")
76
+ throw new UsageError("--scanner is 1 or 2");
77
+ if (positional.length !== 1)
78
+ throw new UsageError("assess takes exactly one repository path");
79
+ if (typeof options.output !== "string")
80
+ throw new UsageError("assess requires --output <file>");
81
+ let root;
82
+ try {
83
+ root = repositoryRoot(positional[0]);
84
+ }
85
+ catch (error) {
86
+ throw error instanceof RepositoryError ? new UsageError(error.message) : error;
87
+ }
88
+ const output = resolve(options.output);
89
+ let parent;
90
+ try {
91
+ parent = realpathSync(dirname(output));
92
+ }
93
+ catch {
94
+ throw new UsageError(`the output directory ${dirname(output)} does not exist`);
95
+ }
96
+ if (isInside(root, resolve(parent, basename(output))))
97
+ throw new UsageError("the output must not be written inside the assessed repository");
98
+ let exists = false;
99
+ try {
100
+ const stat = lstatSync(output);
101
+ exists = true;
102
+ if (!stat.isFile())
103
+ throw new UsageError(`${output} exists and is not a regular file`);
104
+ }
105
+ catch (error) {
106
+ if (error instanceof UsageError)
107
+ throw error;
108
+ }
109
+ if (exists && !options.force)
110
+ throw new UsageError(`${output} exists; pass --force to replace it`);
111
+ const artifact = assessRepository(root, { scanner: options.scanner === "2" ? 2 : 1 });
112
+ writeFileSync(output, `${JSON.stringify(artifact, null, 2)}\n`, { flag: options.force ? "w" : "wx" });
113
+ io.out(summary(artifact, output));
114
+ return options.strict && artifact.coverage.partial ? 3 : 0;
115
+ }
116
+ if (command === "verify") {
117
+ const { positional, options } = parse(rest, [], ["repo"]);
118
+ if (positional.length !== 1)
119
+ throw new UsageError("verify takes exactly one artifact path");
120
+ let value;
121
+ try {
122
+ value = JSON.parse(readFileSync(positional[0], "utf8"));
123
+ }
124
+ catch (error) {
125
+ io.err(`cannot read ${positional[0]}: ${error.message}`);
126
+ return 1;
127
+ }
128
+ const result = verifyAssessment(value, typeof options.repo === "string" ? { repository: options.repo } : {});
129
+ if (result.ok) {
130
+ io.out(`valid ${value.format} ${value.digest}`);
131
+ return 0;
132
+ }
133
+ for (const f of result.findings)
134
+ io.err(`${f.code} ${f.path}: ${f.message}`);
135
+ return 1;
136
+ }
137
+ throw new UsageError(command ? `unknown command ${command}` : "no command");
138
+ }
139
+ catch (error) {
140
+ if (error instanceof UsageError) {
141
+ io.err(`${error.message}\n${USAGE}`);
142
+ return 2;
143
+ }
144
+ if (error instanceof RepositoryError) {
145
+ io.err(error.message);
146
+ return 1;
147
+ }
148
+ io.err(`assessment failed: ${error.message}`);
149
+ return 1;
150
+ }
151
+ }
152
+ const invoked = process.argv[1] ? (() => {
153
+ try {
154
+ return realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url));
155
+ }
156
+ catch {
157
+ return false;
158
+ }
159
+ })() : false;
160
+ if (invoked)
161
+ process.exitCode = main(process.argv.slice(2));
162
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /** Directories never descended into: dependencies, vendored code, build output and VCS metadata. */
2
+ export declare const DEFAULT_EXCLUDED_DIRECTORIES: readonly [".git", ".hg", ".svn", "node_modules", "vendor", "dist", "build", "out", "target", ".next", ".turbo", "coverage", "__pycache__", ".venv"];
3
+ /** Files larger than this are not read. */
4
+ export declare const DEFAULT_MAX_FILE_BYTES = 1048576;
5
+ export type SkipReason = "symlink" | "excluded-directory" | "ignored" | "generated" | "too-large" | "unreadable" | "binary" | "special-file";
6
+ export interface RepositoryFile {
7
+ /** Repository-relative, `/`-separated. */
8
+ path: string;
9
+ size: number;
10
+ }
11
+ export interface Walk {
12
+ files: RepositoryFile[];
13
+ /** Directories and files not read, with the reason. Excluded directories are listed once, not file by file. */
14
+ skipped: Array<{
15
+ path: string;
16
+ reason: SkipReason;
17
+ }>;
18
+ /** Root `.gitignore` patterns this walker could not interpret; they were not applied. */
19
+ unsupportedIgnorePatterns: string[];
20
+ }
21
+ export declare class RepositoryError extends Error {
22
+ constructor(message: string);
23
+ }
24
+ /** Resolves and checks the repository root. */
25
+ export declare function repositoryRoot(path: string): string;
26
+ /** True when `absolute` lies inside `root` (or is it). */
27
+ export declare function isInside(root: string, absolute: string): boolean;
28
+ /**
29
+ * A minimal `.gitignore` interpreter for the root file: blank lines and comments, `dir/` patterns, `*`/`?` globs, and
30
+ * leading-`/` anchoring. Negation (`!`), `**` and character classes are not interpreted; such patterns are returned as
31
+ * unsupported and not applied, so a file they would exclude is scanned and the limitation is reported.
32
+ */
33
+ export declare function parseIgnore(text: string): {
34
+ matchers: Array<(path: string, isDirectory: boolean) => boolean>;
35
+ unsupported: string[];
36
+ };
37
+ /** Walks the repository deterministically. */
38
+ export declare function walkRepository(root: string, options?: {
39
+ maxFileBytes?: number;
40
+ excludedDirectories?: readonly string[];
41
+ }): Walk;
42
+ /**
43
+ * Reads a repository file as UTF-8, refusing anything that is not a regular file inside the root at the moment it is
44
+ * opened (the descriptor is checked, so a file replaced by a link after the walk is not followed).
45
+ */
46
+ export declare function readRepositoryFile(root: string, path: string): string;
47
+ /** The repository's identity from `.git` files, if present. Never runs git; credentials in remote URLs are removed. */
48
+ export declare function gitIdentity(root: string): {
49
+ repository?: string;
50
+ revision?: string;
51
+ ref?: string;
52
+ };
53
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAcA,oGAAoG;AACpG,eAAO,MAAM,4BAA4B,YAAI,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,OAAO,CAAU,CAAC;AAChM,2CAA2C;AAC3C,eAAO,MAAM,sBAAsB,UAAY,CAAC;AAEhD,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,oBAAoB,GAAG,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,YAAY,GAAG,QAAQ,GAAG,cAAc,CAAC;AAE7I,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,IAAI;IACnB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,+GAA+G;IAC/G,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;IACrD,yFAAyF;IACzF,yBAAyB,EAAE,MAAM,EAAE,CAAC;CACrC;AAED,qBAAa,eAAgB,SAAQ,KAAK;IACxC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAID,+CAA+C;AAC/C,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASnD;AAED,0DAA0D;AAC1D,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGhE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAA;CAAE,CAmBrI;AAcD,8CAA8C;AAC9C,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAO,GAAG,IAAI,CAqEnI;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAWrE;AAED,uHAAuH;AACvH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CA+BlG"}