@jevitate/cli 0.7.0 → 0.9.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/dist/ai-cli.d.ts +3 -1
- package/dist/ai-cli.js +60 -16
- package/dist/ai-cli.js.map +1 -1
- package/dist/approval-provenance.d.ts +136 -0
- package/dist/approval-provenance.js +317 -0
- package/dist/approval-provenance.js.map +1 -0
- package/dist/author-journey-cli.js +4 -2
- package/dist/author-journey-cli.js.map +1 -1
- package/dist/bin.js +30544 -20851
- package/dist/browser-cli.d.ts +10 -0
- package/dist/browser-cli.js +50 -0
- package/dist/browser-cli.js.map +1 -0
- package/dist/build-info.generated.js +2 -2
- package/dist/builtin-analyzers.d.ts +7 -0
- package/dist/builtin-analyzers.js +19 -0
- package/dist/builtin-analyzers.js.map +1 -0
- package/dist/campaign-cli.d.ts +6 -0
- package/dist/campaign-cli.js +9 -4
- package/dist/campaign-cli.js.map +1 -1
- package/dist/catalog-analysis.d.ts +70 -0
- package/dist/catalog-analysis.js +507 -0
- package/dist/catalog-analysis.js.map +1 -0
- package/dist/catalog-api.d.ts +73 -0
- package/dist/catalog-api.js +97 -0
- package/dist/catalog-api.js.map +1 -0
- package/dist/catalog-cli.d.ts +12 -0
- package/dist/catalog-cli.js +224 -0
- package/dist/catalog-cli.js.map +1 -0
- package/dist/catalog-review.d.ts +29 -0
- package/dist/catalog-review.js +290 -0
- package/dist/catalog-review.js.map +1 -0
- package/dist/catalog.d.ts +133 -0
- package/dist/catalog.js +352 -0
- package/dist/catalog.js.map +1 -0
- package/dist/change-context.d.ts +44 -0
- package/dist/change-context.js +203 -0
- package/dist/change-context.js.map +1 -0
- package/dist/check-api.d.ts +1 -1
- package/dist/check-api.js +68 -9
- package/dist/check-api.js.map +1 -1
- package/dist/check-cli.d.ts +5 -1
- package/dist/check-cli.js +64 -10
- package/dist/check-cli.js.map +1 -1
- package/dist/check-execute.d.ts +16 -1
- package/dist/check-execute.js +78 -31
- package/dist/check-execute.js.map +1 -1
- package/dist/check-plan.d.ts +14 -0
- package/dist/check-plan.js +28 -2
- package/dist/check-plan.js.map +1 -1
- package/dist/check-suite.js +6 -3
- package/dist/check-suite.js.map +1 -1
- package/dist/check-types.d.ts +51 -6
- package/dist/check-types.js +8 -0
- package/dist/check-types.js.map +1 -1
- package/dist/cli-output.js +85 -5
- package/dist/cli-output.js.map +1 -1
- package/dist/cli-shared.d.ts +22 -2
- package/dist/cli-shared.js +34 -5
- package/dist/cli-shared.js.map +1 -1
- package/dist/demo-aspect-api.d.ts +15 -0
- package/dist/demo-aspect-api.js +26 -1
- package/dist/demo-aspect-api.js.map +1 -1
- package/dist/demo-aspect-cli.js +64 -5
- package/dist/demo-aspect-cli.js.map +1 -1
- package/dist/exit-codes.d.ts +6 -3
- package/dist/exit-codes.js +13 -3
- package/dist/exit-codes.js.map +1 -1
- package/dist/explore-adversarial.d.ts +3 -1
- package/dist/explore-adversarial.js +4 -4
- package/dist/explore-adversarial.js.map +1 -1
- package/dist/explore-author.js +5 -2
- package/dist/explore-author.js.map +1 -1
- package/dist/explore-cli.js +145 -9
- package/dist/explore-cli.js.map +1 -1
- package/dist/explore-coverage.d.ts +6 -2
- package/dist/explore-coverage.js +7 -6
- package/dist/explore-coverage.js.map +1 -1
- package/dist/explore-feature.d.ts +3 -1
- package/dist/explore-feature.js +5 -5
- package/dist/explore-feature.js.map +1 -1
- package/dist/explore-goal.d.ts +37 -6
- package/dist/explore-goal.js +69 -50
- package/dist/explore-goal.js.map +1 -1
- package/dist/explore-shared.d.ts +12 -7
- package/dist/explore-shared.js +9 -1
- package/dist/explore-shared.js.map +1 -1
- package/dist/findings-filing.d.ts +6 -0
- package/dist/findings-filing.js +15 -1
- package/dist/findings-filing.js.map +1 -1
- package/dist/goal-run-flags.d.ts +2 -0
- package/dist/goal-run-flags.js +8 -1
- package/dist/goal-run-flags.js.map +1 -1
- package/dist/heal-probe-guard.d.ts +9 -0
- package/dist/heal-probe-guard.js +113 -0
- package/dist/heal-probe-guard.js.map +1 -0
- package/dist/host-health-run.d.ts +32 -1
- package/dist/host-health-run.js +38 -1
- package/dist/host-health-run.js.map +1 -1
- package/dist/http-5xx-outcome.d.ts +8 -3
- package/dist/http-5xx-outcome.js +5 -15
- package/dist/http-5xx-outcome.js.map +1 -1
- package/dist/init-cli.d.ts +7 -0
- package/dist/init-cli.js +79 -9
- package/dist/init-cli.js.map +1 -1
- package/dist/init-codeowners.d.ts +39 -0
- package/dist/init-codeowners.js +91 -0
- package/dist/init-codeowners.js.map +1 -0
- package/dist/init-keys.d.ts +3 -1
- package/dist/init-keys.js +20 -8
- package/dist/init-keys.js.map +1 -1
- package/dist/init-skills.d.ts +85 -7
- package/dist/init-skills.js +303 -36
- package/dist/init-skills.js.map +1 -1
- package/dist/jev-advisor.d.ts +72 -0
- package/dist/jev-advisor.js +172 -0
- package/dist/jev-advisor.js.map +1 -0
- package/dist/journey-api.d.ts +76 -5
- package/dist/journey-api.js +238 -29
- package/dist/journey-api.js.map +1 -1
- package/dist/journey-cli.js +257 -23
- package/dist/journey-cli.js.map +1 -1
- package/dist/journey-heal.d.ts +74 -0
- package/dist/journey-heal.js +180 -0
- package/dist/journey-heal.js.map +1 -0
- package/dist/journey-network-checks.d.ts +5 -1
- package/dist/journey-network-checks.js +15 -4
- package/dist/journey-network-checks.js.map +1 -1
- package/dist/journey-prefix.js +2 -2
- package/dist/journey-prefix.js.map +1 -1
- package/dist/journey-proposal-store.d.ts +100 -0
- package/dist/journey-proposal-store.js +342 -0
- package/dist/journey-proposal-store.js.map +1 -0
- package/dist/journey-result-record.d.ts +40 -0
- package/dist/journey-result-record.js +28 -0
- package/dist/journey-result-record.js.map +1 -0
- package/dist/journey-review-api.d.ts +19 -0
- package/dist/journey-review-api.js +53 -0
- package/dist/journey-review-api.js.map +1 -0
- package/dist/journey-review-store.d.ts +16 -0
- package/dist/journey-review-store.js +95 -0
- package/dist/journey-review-store.js.map +1 -0
- package/dist/journey-review.d.ts +54 -0
- package/dist/journey-review.js +538 -0
- package/dist/journey-review.js.map +1 -0
- package/dist/journey-verify.js +14 -1
- package/dist/journey-verify.js.map +1 -1
- package/dist/key-report.d.ts +20 -5
- package/dist/key-report.js +32 -9
- package/dist/key-report.js.map +1 -1
- package/dist/kill-signal.js +10 -2
- package/dist/kill-signal.js.map +1 -1
- package/dist/launch-armed.js +5 -1
- package/dist/launch-armed.js.map +1 -1
- package/dist/load-cli.js +4 -2
- package/dist/load-cli.js.map +1 -1
- package/dist/log-classes.d.ts +73 -0
- package/dist/log-classes.js +167 -0
- package/dist/log-classes.js.map +1 -0
- package/dist/log-correlation.d.ts +29 -10
- package/dist/log-correlation.js +44 -21
- package/dist/log-correlation.js.map +1 -1
- package/dist/login-cli.d.ts +17 -0
- package/dist/login-cli.js +161 -0
- package/dist/login-cli.js.map +1 -0
- package/dist/logs-cli.js +3 -1
- package/dist/logs-cli.js.map +1 -1
- package/dist/mcp-api.d.ts +6 -1
- package/dist/mcp-api.js +110 -16
- package/dist/mcp-api.js.map +1 -1
- package/dist/mcp-cli-runner.d.ts +2 -0
- package/dist/mcp-cli-runner.js +3 -1
- package/dist/mcp-cli-runner.js.map +1 -1
- package/dist/mcp-cli-tools.d.ts +5 -0
- package/dist/mcp-cli-tools.js +178 -23
- package/dist/mcp-cli-tools.js.map +1 -1
- package/dist/mission-cli.js +8 -4
- package/dist/mission-cli.js.map +1 -1
- package/dist/mission-journal.d.ts +4 -1
- package/dist/mission-journal.js +9 -3
- package/dist/mission-journal.js.map +1 -1
- package/dist/mission-queue-cli.js +21 -2
- package/dist/mission-queue-cli.js.map +1 -1
- package/dist/mission-queue-runner.d.ts +6 -0
- package/dist/mission-queue-runner.js +33 -3
- package/dist/mission-queue-runner.js.map +1 -1
- package/dist/multi-run-cli.d.ts +7 -1
- package/dist/multi-run-cli.js +10 -3
- package/dist/multi-run-cli.js.map +1 -1
- package/dist/multi-run.d.ts +44 -8
- package/dist/multi-run.js +118 -25
- package/dist/multi-run.js.map +1 -1
- package/dist/persona-login.d.ts +256 -0
- package/dist/persona-login.js +884 -0
- package/dist/persona-login.js.map +1 -0
- package/dist/pre-approval.d.ts +98 -0
- package/dist/pre-approval.js +175 -0
- package/dist/pre-approval.js.map +1 -0
- package/dist/program.js +12 -0
- package/dist/program.js.map +1 -1
- package/dist/project-dir.d.ts +2 -1
- package/dist/project-dir.js +3 -1
- package/dist/project-dir.js.map +1 -1
- package/dist/readiness.d.ts +29 -0
- package/dist/readiness.js +291 -0
- package/dist/readiness.js.map +1 -0
- package/dist/regression-cli.js +4 -2
- package/dist/regression-cli.js.map +1 -1
- package/dist/report-api.d.ts +25 -2
- package/dist/report-api.js +34 -5
- package/dist/report-api.js.map +1 -1
- package/dist/report-cli.js +8 -1
- package/dist/report-cli.js.map +1 -1
- package/dist/resource-preflight.js +5 -3
- package/dist/resource-preflight.js.map +1 -1
- package/dist/result-schema.d.ts +12 -0
- package/dist/result-schema.js +8 -0
- package/dist/result-schema.js.map +1 -1
- package/dist/run-index.d.ts +4 -2
- package/dist/run-index.js +3 -1
- package/dist/run-index.js.map +1 -1
- package/dist/run-key-preflight.d.ts +2 -1
- package/dist/run-key-preflight.js +3 -2
- package/dist/run-key-preflight.js.map +1 -1
- package/dist/run-metadata.d.ts +29 -0
- package/dist/run-metadata.js +48 -0
- package/dist/run-metadata.js.map +1 -0
- package/dist/run-tags-cli.d.ts +14 -0
- package/dist/run-tags-cli.js +41 -0
- package/dist/run-tags-cli.js.map +1 -0
- package/dist/self-heal-adapter.d.ts +43 -27
- package/dist/self-heal-adapter.js +196 -62
- package/dist/self-heal-adapter.js.map +1 -1
- package/dist/site-cli.d.ts +1 -1
- package/dist/site-cli.js +24 -1
- package/dist/site-cli.js.map +1 -1
- package/dist/source-cli.js +9 -5
- package/dist/source-cli.js.map +1 -1
- package/dist/suite-explore-options.d.ts +14 -0
- package/dist/suite-explore-options.js +8 -0
- package/dist/suite-explore-options.js.map +1 -1
- package/dist/sweep-api.d.ts +289 -0
- package/dist/sweep-api.js +859 -0
- package/dist/sweep-api.js.map +1 -0
- package/dist/sweep-cli.d.ts +9 -0
- package/dist/sweep-cli.js +117 -0
- package/dist/sweep-cli.js.map +1 -0
- package/dist/target-config.d.ts +5 -2
- package/dist/target-config.js +15 -0
- package/dist/target-config.js.map +1 -1
- package/dist/ux-cli.js +3 -1
- package/dist/ux-cli.js.map +1 -1
- package/dist/ux-usability.d.ts +9 -3
- package/dist/ux-usability.js +8 -5
- package/dist/ux-usability.js.map +1 -1
- package/dist/verify-fix-cli.js +4 -2
- package/dist/verify-fix-cli.js.map +1 -1
- package/package.json +9 -9
- package/skills/jevitate-ci-check/SKILL.md +9 -1
- package/skills/jevitate-demo/SKILL.md +5 -2
- package/skills/jevitate-getting-started/SKILL.md +14 -1
- package/skills/jevitate-mission-scope/SKILL.md +2 -2
- package/skills/jevitate-run-journey/SKILL.md +42 -9
- package/skills/jevitate-test-campaign/SKILL.md +26 -5
package/dist/catalog.js
ADDED
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { contentHash } from "@jevitate/domain";
|
|
5
|
+
import { CATALOG_ID_RE, CatalogApprovalSchema, FsJourneyStore, JobSchema, renderJobStory, } from "@jevitate/journey";
|
|
6
|
+
import { journeyReviewHash } from "./journey-review.js";
|
|
7
|
+
/**
|
|
8
|
+
* #433 — the catalog: personas, jobs and Journeys, with their ids, content hashes and approval
|
|
9
|
+
* state, loaded in one place (`CatalogLoader`) for every approval path, every review sheet and
|
|
10
|
+
* `catalog status` — and for the readiness (#434) and catalog-analysis (#435) analyzers.
|
|
11
|
+
*
|
|
12
|
+
* Files (in the project's `.jevitate/`):
|
|
13
|
+
* - `personas.json` — the #427 personas file, extended: an entry may carry `description`, `role`
|
|
14
|
+
* and its `approval`, beside its session settings (`storageState`, `login`). A catalog-only
|
|
15
|
+
* persona (no session yet) is allowed. The persona's id is its #427 `name` (`id` is accepted too).
|
|
16
|
+
* - `jobs.json` — job stories (`JobSchema`); `.jevitate/campaign/jobs.json` (the test-campaign
|
|
17
|
+
* skill's old place) is read when `jobs.json` does not exist.
|
|
18
|
+
*
|
|
19
|
+
* Content hashes leave the approval out, so approving does not change what was approved. A
|
|
20
|
+
* persona's hash covers what the persona IS (id, description, role, any other descriptive key),
|
|
21
|
+
* not its session settings: re-minting a session or moving a storage state is not a new persona.
|
|
22
|
+
* A missing file is an empty catalog — a project without personas/jobs works exactly as before;
|
|
23
|
+
* a file that exists but cannot be read as the catalog is refused (`CatalogInputError`), never skipped.
|
|
24
|
+
*/
|
|
25
|
+
export const PERSONAS_FILE = "personas.json";
|
|
26
|
+
export const JOBS_FILE = "jobs.json";
|
|
27
|
+
/** The test-campaign skill's jobs file before #433 — still read for compatibility. */
|
|
28
|
+
export const LEGACY_JOBS_FILE = join("campaign", "jobs.json");
|
|
29
|
+
/** A catalog file that exists but is not a valid catalog — refused (exit 64), never skipped. */
|
|
30
|
+
export class CatalogInputError extends Error {
|
|
31
|
+
code = "E_CATALOG_INPUT";
|
|
32
|
+
}
|
|
33
|
+
/** `persona|job review|approve <id>`: no such item in the catalog. */
|
|
34
|
+
export class UnknownCatalogItemError extends Error {
|
|
35
|
+
kind;
|
|
36
|
+
constructor(kind, message) {
|
|
37
|
+
super(message);
|
|
38
|
+
this.kind = kind;
|
|
39
|
+
}
|
|
40
|
+
get code() {
|
|
41
|
+
return this.kind === "persona" ? "E_UNKNOWN_PERSONA" : "E_UNKNOWN_JOB";
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function statusOf(approval, hash) {
|
|
45
|
+
if (approval === undefined)
|
|
46
|
+
return "draft";
|
|
47
|
+
return approval.contentHash === hash ? "approved" : "stale";
|
|
48
|
+
}
|
|
49
|
+
function isRecord(v) {
|
|
50
|
+
return v !== null && typeof v === "object" && !Array.isArray(v);
|
|
51
|
+
}
|
|
52
|
+
async function readJsonFile(path) {
|
|
53
|
+
const raw = await readFile(path, "utf8");
|
|
54
|
+
try {
|
|
55
|
+
return JSON.parse(raw);
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
throw new CatalogInputError(`${path} is not valid JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async function writeJsonFile(path, value) {
|
|
62
|
+
await writeFile(path, `${JSON.stringify(value, null, 2)}\n`);
|
|
63
|
+
}
|
|
64
|
+
// ── personas.json ─────────────────────────────────────────────────────────────────────────────
|
|
65
|
+
/** The session settings (#427): operational, not part of what a persona is (left out of its hash). */
|
|
66
|
+
const SESSION_KEYS = new Set(["storageState", "login"]);
|
|
67
|
+
function personaList(raw) {
|
|
68
|
+
if (Array.isArray(raw))
|
|
69
|
+
return raw;
|
|
70
|
+
if (isRecord(raw) && Array.isArray(raw.personas))
|
|
71
|
+
return raw.personas;
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
function rawPersonas(raw, path) {
|
|
75
|
+
const list = personaList(raw);
|
|
76
|
+
if (list !== null) {
|
|
77
|
+
return list.map((entry, index) => {
|
|
78
|
+
if (!isRecord(entry))
|
|
79
|
+
throw new CatalogInputError(`${path}: entry ${index} must be an object {"name": string, …}`);
|
|
80
|
+
const name = entry.name ?? entry.id;
|
|
81
|
+
if (typeof name !== "string")
|
|
82
|
+
throw new CatalogInputError(`${path}: entry ${index} needs a "name" (its persona id)`);
|
|
83
|
+
if (entry.name !== undefined && entry.id !== undefined && entry.name !== entry.id) {
|
|
84
|
+
throw new CatalogInputError(`${path}: entry ${index} has both "name" ${JSON.stringify(entry.name)} and "id" ${JSON.stringify(entry.id)} — one persona id`);
|
|
85
|
+
}
|
|
86
|
+
const { name: _n, id: _i, ...fields } = entry;
|
|
87
|
+
return { id: name, fields, slot: { form: "list", index } };
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (isRecord(raw)) {
|
|
91
|
+
return Object.entries(raw).map(([id, value]) => {
|
|
92
|
+
if (typeof value === "string")
|
|
93
|
+
return { id, fields: { storageState: value }, slot: { form: "map", key: id } };
|
|
94
|
+
if (!isRecord(value))
|
|
95
|
+
throw new CatalogInputError(`${path}: ${id} must map to a storage state path or an object`);
|
|
96
|
+
return { id, fields: { ...value }, slot: { form: "map", key: id } };
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
throw new CatalogInputError(`${path} must be an object or an array of personas`);
|
|
100
|
+
}
|
|
101
|
+
function catalogPersona(p, path) {
|
|
102
|
+
if (!CATALOG_ID_RE.test(p.id))
|
|
103
|
+
throw new CatalogInputError(`${path}: persona id ${JSON.stringify(p.id)} must be 1-64 of [A-Za-z0-9._-], starting alphanumeric`);
|
|
104
|
+
const { description, role, approval: rawApproval } = p.fields;
|
|
105
|
+
if (description !== undefined && (typeof description !== "string" || description.length > 2000)) {
|
|
106
|
+
throw new CatalogInputError(`${path}: persona ${p.id}: description must be text (at most 2000 characters)`);
|
|
107
|
+
}
|
|
108
|
+
if (role !== undefined && (typeof role !== "string" || role.length > 200))
|
|
109
|
+
throw new CatalogInputError(`${path}: persona ${p.id}: role must be text (at most 200 characters)`);
|
|
110
|
+
let approval;
|
|
111
|
+
if (rawApproval !== undefined) {
|
|
112
|
+
const parsed = CatalogApprovalSchema.safeParse(rawApproval);
|
|
113
|
+
if (!parsed.success)
|
|
114
|
+
throw new CatalogInputError(`${path}: persona ${p.id}: approval is not a valid approval record (${parsed.error.issues.map((i) => i.message).join("; ")})`);
|
|
115
|
+
approval = parsed.data;
|
|
116
|
+
}
|
|
117
|
+
const hash = personaContentHash(p.id, p.fields);
|
|
118
|
+
return {
|
|
119
|
+
id: p.id,
|
|
120
|
+
...(typeof description === "string" ? { description } : {}),
|
|
121
|
+
...(typeof role === "string" ? { role } : {}),
|
|
122
|
+
hasStorageState: typeof p.fields.storageState === "string",
|
|
123
|
+
hasLogin: p.fields.login !== undefined,
|
|
124
|
+
...(approval === undefined ? {} : { approval }),
|
|
125
|
+
contentHash: hash,
|
|
126
|
+
status: statusOf(approval, hash),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/** #433: a persona's content hash — its id and descriptive keys, without its approval or session settings. */
|
|
130
|
+
export function personaContentHash(id, fields) {
|
|
131
|
+
const described = { id };
|
|
132
|
+
for (const [k, v] of Object.entries(fields))
|
|
133
|
+
if (k !== "approval" && !SESSION_KEYS.has(k))
|
|
134
|
+
described[k] = v;
|
|
135
|
+
return contentHash(described);
|
|
136
|
+
}
|
|
137
|
+
// ── jobs.json ─────────────────────────────────────────────────────────────────────────────────
|
|
138
|
+
function jobList(raw, path) {
|
|
139
|
+
if (Array.isArray(raw))
|
|
140
|
+
return raw;
|
|
141
|
+
if (isRecord(raw) && Array.isArray(raw.jobs))
|
|
142
|
+
return raw.jobs;
|
|
143
|
+
throw new CatalogInputError(`${path} must be an array of jobs (or {"jobs": [...]})`);
|
|
144
|
+
}
|
|
145
|
+
function catalogJob(entry, index, path) {
|
|
146
|
+
const where = isRecord(entry) && typeof entry.id === "string" ? `job ${JSON.stringify(entry.id)}` : `entry ${index}`;
|
|
147
|
+
const parsed = JobSchema.safeParse(entry);
|
|
148
|
+
if (!parsed.success) {
|
|
149
|
+
throw new CatalogInputError(`${path}: ${where}: ${parsed.error.issues.map((i) => (i.path.length === 0 ? i.message : `${i.path.join(".")}: ${i.message}`)).join("; ")}`);
|
|
150
|
+
}
|
|
151
|
+
const job = parsed.data;
|
|
152
|
+
const hash = jobContentHash(job);
|
|
153
|
+
return {
|
|
154
|
+
id: job.id,
|
|
155
|
+
job,
|
|
156
|
+
story: renderJobStory(job),
|
|
157
|
+
personas: [...new Set([...(job.personas ?? []), ...(job.persona === undefined ? [] : [job.persona])])],
|
|
158
|
+
...(job.approval === undefined ? {} : { approval: job.approval }),
|
|
159
|
+
contentHash: hash,
|
|
160
|
+
status: statusOf(job.approval, hash),
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/** #433: a job's content hash — the job without its approval. */
|
|
164
|
+
export function jobContentHash(job) {
|
|
165
|
+
const { approval: _a, ...rest } = job;
|
|
166
|
+
return contentHash(rest);
|
|
167
|
+
}
|
|
168
|
+
// ── Journeys ──────────────────────────────────────────────────────────────────────────────────
|
|
169
|
+
export function catalogJourney(journey) {
|
|
170
|
+
const m = journey.metadata;
|
|
171
|
+
const hash = journeyReviewHash(journey);
|
|
172
|
+
return {
|
|
173
|
+
id: m.id,
|
|
174
|
+
name: m.name,
|
|
175
|
+
promoted: m.promoted,
|
|
176
|
+
journey,
|
|
177
|
+
...(m.job === undefined ? {} : { job: m.job }),
|
|
178
|
+
...(m.persona === undefined ? {} : { personaText: m.persona }),
|
|
179
|
+
...(m.approval === undefined ? {} : { approval: m.approval }),
|
|
180
|
+
contentHash: hash,
|
|
181
|
+
changedSinceApproval: m.promoted && m.approval !== undefined && m.approval.contentHash !== hash,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* #433: loads personas + jobs + Journeys with their ids, content hashes and approval state. Shared
|
|
186
|
+
* by every approval path (`persona|job approve`, `journey promote`, `demo approve`), the review
|
|
187
|
+
* sheets and `catalog status` — and exported for the #434 / #435 analyzers.
|
|
188
|
+
*/
|
|
189
|
+
export class CatalogLoader {
|
|
190
|
+
opts;
|
|
191
|
+
constructor(opts) {
|
|
192
|
+
this.opts = opts;
|
|
193
|
+
}
|
|
194
|
+
/** The personas file path (whether or not it exists), or null without a catalog dir. */
|
|
195
|
+
personasPath() {
|
|
196
|
+
return this.opts.catalogDir === null ? null : join(this.opts.catalogDir, PERSONAS_FILE);
|
|
197
|
+
}
|
|
198
|
+
/** The jobs file in use: `jobs.json`, else the legacy `campaign/jobs.json`; null when neither exists. */
|
|
199
|
+
jobsPath() {
|
|
200
|
+
if (this.opts.catalogDir === null)
|
|
201
|
+
return null;
|
|
202
|
+
const main = join(this.opts.catalogDir, JOBS_FILE);
|
|
203
|
+
const legacy = join(this.opts.catalogDir, LEGACY_JOBS_FILE);
|
|
204
|
+
if (existsSync(main) && existsSync(legacy)) {
|
|
205
|
+
throw new CatalogInputError(`both ${main} and ${legacy} exist — merge the jobs into ${main} and remove ${legacy} (one jobs file, so nothing diverges silently)`);
|
|
206
|
+
}
|
|
207
|
+
if (existsSync(main))
|
|
208
|
+
return main;
|
|
209
|
+
return existsSync(legacy) ? legacy : null;
|
|
210
|
+
}
|
|
211
|
+
async loadPersonas() {
|
|
212
|
+
const path = this.personasPath();
|
|
213
|
+
if (path === null || !existsSync(path))
|
|
214
|
+
return { file: null, personas: [] };
|
|
215
|
+
const personas = rawPersonas(await readJsonFile(path), path).map((p) => catalogPersona(p, path));
|
|
216
|
+
const seen = new Set();
|
|
217
|
+
for (const p of personas) {
|
|
218
|
+
if (seen.has(p.id))
|
|
219
|
+
throw new CatalogInputError(`${path}: persona ${p.id} is declared twice`);
|
|
220
|
+
seen.add(p.id);
|
|
221
|
+
}
|
|
222
|
+
return { file: path, personas };
|
|
223
|
+
}
|
|
224
|
+
async loadJobs() {
|
|
225
|
+
const path = this.jobsPath();
|
|
226
|
+
if (path === null)
|
|
227
|
+
return { file: null, jobs: [] };
|
|
228
|
+
const jobs = jobList(await readJsonFile(path), path).map((e, i) => catalogJob(e, i, path));
|
|
229
|
+
const seen = new Set();
|
|
230
|
+
for (const j of jobs) {
|
|
231
|
+
if (seen.has(j.id))
|
|
232
|
+
throw new CatalogInputError(`${path}: job ${j.id} is declared twice`);
|
|
233
|
+
seen.add(j.id);
|
|
234
|
+
}
|
|
235
|
+
return { file: path, jobs };
|
|
236
|
+
}
|
|
237
|
+
async loadJourneys() {
|
|
238
|
+
const store = new FsJourneyStore(this.opts.journeysDir);
|
|
239
|
+
const out = [];
|
|
240
|
+
for (const meta of await store.list()) {
|
|
241
|
+
const journey = await store.get(meta.id);
|
|
242
|
+
if (journey !== null)
|
|
243
|
+
out.push(catalogJourney(journey));
|
|
244
|
+
}
|
|
245
|
+
return out.sort((a, b) => a.id.localeCompare(b.id));
|
|
246
|
+
}
|
|
247
|
+
async load() {
|
|
248
|
+
const [{ file: personasFile, personas }, { file: jobsFile, jobs }, journeys] = await Promise.all([this.loadPersonas(), this.loadJobs(), this.loadJourneys()]);
|
|
249
|
+
return { dir: this.opts.catalogDir, personasFile, jobsFile, personas, jobs, journeys, journeysDir: this.opts.journeysDir };
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
export function findPersona(catalog, id) {
|
|
253
|
+
return catalog.personas.find((p) => p.id === id);
|
|
254
|
+
}
|
|
255
|
+
export function findJob(catalog, id) {
|
|
256
|
+
return catalog.jobs.find((j) => j.id === id);
|
|
257
|
+
}
|
|
258
|
+
export function requirePersona(catalog, id) {
|
|
259
|
+
const p = findPersona(catalog, id);
|
|
260
|
+
if (p !== undefined)
|
|
261
|
+
return p;
|
|
262
|
+
const where = catalog.dir === null ? "no .jevitate/ project was found (run inside a project, or pass --dir)" : `${join(catalog.dir, PERSONAS_FILE)} declares ${catalog.personas.length === 0 ? "no personas" : `${catalog.personas.map((x) => x.id).join(", ")}`}`;
|
|
263
|
+
throw new UnknownCatalogItemError("persona", `unknown persona '${id}' — ${where}`);
|
|
264
|
+
}
|
|
265
|
+
export function requireJob(catalog, id) {
|
|
266
|
+
const j = findJob(catalog, id);
|
|
267
|
+
if (j !== undefined)
|
|
268
|
+
return j;
|
|
269
|
+
const where = catalog.dir === null ? "no .jevitate/ project was found (run inside a project, or pass --dir)" : catalog.jobsFile === null ? `there is no ${join(catalog.dir, JOBS_FILE)}` : `${catalog.jobsFile} declares ${catalog.jobs.map((x) => x.id).join(", ")}`;
|
|
270
|
+
throw new UnknownCatalogItemError("job", `unknown job '${id}' — ${where}`);
|
|
271
|
+
}
|
|
272
|
+
/** The Journeys whose catalog persona link is this persona. */
|
|
273
|
+
export function journeysForPersona(catalog, personaId) {
|
|
274
|
+
return catalog.journeys.filter((j) => personaLinkId(catalog, j) === personaId);
|
|
275
|
+
}
|
|
276
|
+
export function journeysForJob(catalog, jobId) {
|
|
277
|
+
return catalog.journeys.filter((j) => j.job === jobId);
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* The persona id a Journey links: `metadata.persona` when it names a catalog persona; when the
|
|
281
|
+
* Journey links a job, its persona is ALWAYS read as an id (an unknown one is a dangling link).
|
|
282
|
+
* Otherwise `metadata.persona` is free text and links nothing.
|
|
283
|
+
*/
|
|
284
|
+
export function personaLinkId(catalog, j) {
|
|
285
|
+
const text = j.personaText?.trim();
|
|
286
|
+
if (text === undefined || text === "")
|
|
287
|
+
return undefined;
|
|
288
|
+
if (findPersona(catalog, text) !== undefined)
|
|
289
|
+
return text;
|
|
290
|
+
return j.job !== undefined ? text : undefined;
|
|
291
|
+
}
|
|
292
|
+
/** #433: a Journey's links, their approval state, what is unvetted and why it needs re-review. */
|
|
293
|
+
export function journeyLinks(catalog, j) {
|
|
294
|
+
const job = j.job === undefined ? undefined : findJob(catalog, j.job);
|
|
295
|
+
const jobLink = j.job === undefined ? undefined : { id: j.job, status: (job?.status ?? "unknown"), ...(job === undefined ? {} : { story: job.story }) };
|
|
296
|
+
const personaId = personaLinkId(catalog, j);
|
|
297
|
+
const personaLink = personaId === undefined ? undefined : { id: personaId, status: (findPersona(catalog, personaId)?.status ?? "unknown") };
|
|
298
|
+
const unvetted = [
|
|
299
|
+
...(jobLink !== undefined && jobLink.status !== "approved" ? [`job:${jobLink.id} (${jobLink.status})`] : []),
|
|
300
|
+
...(personaLink !== undefined && personaLink.status !== "approved" ? [`persona:${personaLink.id} (${personaLink.status})`] : []),
|
|
301
|
+
];
|
|
302
|
+
const needsReReview = [];
|
|
303
|
+
if (j.promoted) {
|
|
304
|
+
if (j.changedSinceApproval)
|
|
305
|
+
needsReReview.push("the Journey changed since its approval");
|
|
306
|
+
if (jobLink?.status === "stale")
|
|
307
|
+
needsReReview.push(`its job '${jobLink.id}' changed since that job's approval`);
|
|
308
|
+
if (personaLink?.status === "stale")
|
|
309
|
+
needsReReview.push(`its persona '${personaLink.id}' changed since that persona's approval`);
|
|
310
|
+
}
|
|
311
|
+
return {
|
|
312
|
+
linked: jobLink !== undefined || personaLink !== undefined,
|
|
313
|
+
...(jobLink === undefined ? {} : { job: jobLink }),
|
|
314
|
+
...(personaLink === undefined ? {} : { persona: personaLink }),
|
|
315
|
+
unvetted,
|
|
316
|
+
needsReReview,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
// ── Writing an approval back ──────────────────────────────────────────────────────────────────
|
|
320
|
+
/** #433: records a persona's approval in personas.json, on the same entry (a bare path entry becomes `{storageState, approval}`). */
|
|
321
|
+
export async function writePersonaApproval(file, id, approval) {
|
|
322
|
+
const raw = await readJsonFile(file);
|
|
323
|
+
const entry = rawPersonas(raw, file).find((p) => p.id === id);
|
|
324
|
+
if (entry === undefined)
|
|
325
|
+
throw new UnknownCatalogItemError("persona", `unknown persona '${id}' in ${file}`);
|
|
326
|
+
const record = CatalogApprovalSchema.parse(approval);
|
|
327
|
+
let next;
|
|
328
|
+
if (entry.slot.form === "list") {
|
|
329
|
+
const list = [...(personaList(raw) ?? [])];
|
|
330
|
+
list[entry.slot.index] = { ...list[entry.slot.index], approval: record };
|
|
331
|
+
next = Array.isArray(raw) ? list : { ...raw, personas: list };
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
const map = raw;
|
|
335
|
+
const value = map[entry.slot.key];
|
|
336
|
+
next = { ...map, [entry.slot.key]: typeof value === "string" ? { storageState: value, approval: record } : { ...value, approval: record } };
|
|
337
|
+
}
|
|
338
|
+
await writeJsonFile(file, next);
|
|
339
|
+
}
|
|
340
|
+
/** #433: records a job's approval in its jobs file. */
|
|
341
|
+
export async function writeJobApproval(file, id, approval) {
|
|
342
|
+
const raw = await readJsonFile(file);
|
|
343
|
+
const list = [...jobList(raw, file)];
|
|
344
|
+
const index = list.findIndex((e) => isRecord(e) && e.id === id);
|
|
345
|
+
if (index === -1)
|
|
346
|
+
throw new UnknownCatalogItemError("job", `unknown job '${id}' in ${file}`);
|
|
347
|
+
list[index] = { ...list[index], approval: CatalogApprovalSchema.parse(approval) };
|
|
348
|
+
// Re-validated before writing: an approval is never written into a job the schema refuses.
|
|
349
|
+
catalogJob(list[index], index, file);
|
|
350
|
+
await writeJsonFile(file, Array.isArray(raw) ? list : { ...raw, jobs: list });
|
|
351
|
+
}
|
|
352
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #453 change-aware self-heal: read a git range read-only and build a `ChangeScope`.
|
|
3
|
+
* The only IO is `git rev-parse` / `git merge-base` / `git diff`, always via an argv array, never a
|
|
4
|
+
* shell, and only resolved 40-hex SHAs ever reach `diff`. Raw diff text leaves only as `ChangeEvidence`.
|
|
5
|
+
*/
|
|
6
|
+
import { type ChangeScope } from "@jevitate/runtime";
|
|
7
|
+
/** The caller supplied a syntactically invalid range or note set. */
|
|
8
|
+
export declare class ChangesArgsError extends Error {
|
|
9
|
+
readonly code: "E_CHANGES_ARGS";
|
|
10
|
+
constructor(message: string);
|
|
11
|
+
}
|
|
12
|
+
/** Git could not resolve the range, or the diff is too large to surface. */
|
|
13
|
+
export declare class ChangesInputError extends Error {
|
|
14
|
+
readonly code: "E_CHANGES_INPUT";
|
|
15
|
+
constructor(message: string);
|
|
16
|
+
}
|
|
17
|
+
/** Runs one read-only git command. Injected in tests; never uses a shell. */
|
|
18
|
+
export type GitExec = (args: string[], opts: {
|
|
19
|
+
cwd: string;
|
|
20
|
+
env: NodeJS.ProcessEnv;
|
|
21
|
+
}) => Promise<{
|
|
22
|
+
stdout: string;
|
|
23
|
+
}>;
|
|
24
|
+
/** The production git runner: argv only, no shell, optional locks and prompts disabled. */
|
|
25
|
+
export declare const execGitReadOnly: GitExec;
|
|
26
|
+
/** Parse `a..b`, `a...b` (symmetric) or a single `X` (meaning `X..HEAD`) into its resolved ends. */
|
|
27
|
+
export declare function parseChangeRange(s: string): {
|
|
28
|
+
from: string;
|
|
29
|
+
to: string;
|
|
30
|
+
symmetric: boolean;
|
|
31
|
+
};
|
|
32
|
+
/** Validate human change notes: at most 20, each 1-2000 chars, no NUL. Returns a copy. */
|
|
33
|
+
export declare function validateChangeNotes(notes: readonly string[]): string[];
|
|
34
|
+
/** Read a git range (and/or notes) and build the `ChangeScope` the healer consumes. */
|
|
35
|
+
export declare function readChangeScope(o: {
|
|
36
|
+
cwd: string;
|
|
37
|
+
range?: string;
|
|
38
|
+
notes: readonly string[];
|
|
39
|
+
exec?: GitExec;
|
|
40
|
+
limits?: {
|
|
41
|
+
maxFiles?: number;
|
|
42
|
+
maxBytes?: number;
|
|
43
|
+
};
|
|
44
|
+
}): Promise<ChangeScope>;
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #453 change-aware self-heal: read a git range read-only and build a `ChangeScope`.
|
|
3
|
+
* The only IO is `git rev-parse` / `git merge-base` / `git diff`, always via an argv array, never a
|
|
4
|
+
* shell, and only resolved 40-hex SHAs ever reach `diff`. Raw diff text leaves only as `ChangeEvidence`.
|
|
5
|
+
*/
|
|
6
|
+
import { execFile } from "node:child_process";
|
|
7
|
+
import { promisify } from "node:util";
|
|
8
|
+
import { extractChangeEvidence, isSkippedChangePath } from "@jevitate/runtime";
|
|
9
|
+
const execFileAsync = promisify(execFile);
|
|
10
|
+
const GIT_MAX_BUFFER = 8 * 1024 * 1024;
|
|
11
|
+
const DEFAULT_MAX_FILES = 400;
|
|
12
|
+
const DEFAULT_MAX_BYTES = 4_000_000;
|
|
13
|
+
const MAX_NOTES = 20;
|
|
14
|
+
const MAX_NOTE_LENGTH = 2000;
|
|
15
|
+
const SHA_RE = /^[0-9a-f]{40}$/;
|
|
16
|
+
// The whole range must be ref-safe characters; the separator, if any, is exactly `..` or `...`.
|
|
17
|
+
const RANGE_RE = /^([A-Za-z0-9._\/~^@{}-]{1,200})(?:(\.\.\.?)([A-Za-z0-9._\/~^@{}-]{1,200}))?$/;
|
|
18
|
+
/** The caller supplied a syntactically invalid range or note set. */
|
|
19
|
+
export class ChangesArgsError extends Error {
|
|
20
|
+
code = "E_CHANGES_ARGS";
|
|
21
|
+
constructor(message) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = "ChangesArgsError";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** Git could not resolve the range, or the diff is too large to surface. */
|
|
27
|
+
export class ChangesInputError extends Error {
|
|
28
|
+
code = "E_CHANGES_INPUT";
|
|
29
|
+
constructor(message) {
|
|
30
|
+
super(message);
|
|
31
|
+
this.name = "ChangesInputError";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** The production git runner: argv only, no shell, optional locks and prompts disabled. */
|
|
35
|
+
export const execGitReadOnly = async (args, opts) => {
|
|
36
|
+
const result = await execFileAsync("git", args, {
|
|
37
|
+
cwd: opts.cwd,
|
|
38
|
+
env: { ...opts.env, GIT_OPTIONAL_LOCKS: "0", GIT_TERMINAL_PROMPT: "0" },
|
|
39
|
+
maxBuffer: GIT_MAX_BUFFER,
|
|
40
|
+
});
|
|
41
|
+
return { stdout: result.stdout };
|
|
42
|
+
};
|
|
43
|
+
/** Parse `a..b`, `a...b` (symmetric) or a single `X` (meaning `X..HEAD`) into its resolved ends. */
|
|
44
|
+
export function parseChangeRange(s) {
|
|
45
|
+
if (typeof s !== "string" || !RANGE_RE.test(s))
|
|
46
|
+
throw new ChangesArgsError(`invalid change range: ${JSON.stringify(s)}`);
|
|
47
|
+
const triple = s.indexOf("...");
|
|
48
|
+
const double = triple >= 0 ? -1 : s.indexOf("..");
|
|
49
|
+
let from;
|
|
50
|
+
let to;
|
|
51
|
+
let symmetric;
|
|
52
|
+
if (triple >= 0) {
|
|
53
|
+
from = s.slice(0, triple);
|
|
54
|
+
to = s.slice(triple + 3);
|
|
55
|
+
symmetric = true;
|
|
56
|
+
}
|
|
57
|
+
else if (double >= 0) {
|
|
58
|
+
from = s.slice(0, double);
|
|
59
|
+
to = s.slice(double + 2);
|
|
60
|
+
symmetric = false;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
from = s;
|
|
64
|
+
to = "HEAD";
|
|
65
|
+
symmetric = false;
|
|
66
|
+
}
|
|
67
|
+
for (const side of [from, to]) {
|
|
68
|
+
if (side === "" || side.startsWith("-") || side.includes("..") || side.includes("@{-")) {
|
|
69
|
+
throw new ChangesArgsError(`unsafe change range: ${JSON.stringify(s)}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return { from, to, symmetric };
|
|
73
|
+
}
|
|
74
|
+
/** Validate human change notes: at most 20, each 1-2000 chars, no NUL. Returns a copy. */
|
|
75
|
+
export function validateChangeNotes(notes) {
|
|
76
|
+
if (notes.length > MAX_NOTES)
|
|
77
|
+
throw new ChangesArgsError(`at most ${MAX_NOTES} change notes are allowed`);
|
|
78
|
+
for (const note of notes) {
|
|
79
|
+
if (note.length < 1 || note.length > MAX_NOTE_LENGTH || note.includes("\u0000")) {
|
|
80
|
+
throw new ChangesArgsError(`each change note must be 1-${MAX_NOTE_LENGTH} characters and contain no NUL`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return [...notes];
|
|
84
|
+
}
|
|
85
|
+
/** Read a git range (and/or notes) and build the `ChangeScope` the healer consumes. */
|
|
86
|
+
export async function readChangeScope(o) {
|
|
87
|
+
const exec = o.exec ?? execGitReadOnly;
|
|
88
|
+
const notes = validateChangeNotes(o.notes);
|
|
89
|
+
const maxFiles = o.limits?.maxFiles ?? DEFAULT_MAX_FILES;
|
|
90
|
+
const maxBytes = o.limits?.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
91
|
+
if (o.range === undefined) {
|
|
92
|
+
return { evidence: extractChangeEvidence("", notes), scanned: { files: 0, hunks: 0, skipped: [] } };
|
|
93
|
+
}
|
|
94
|
+
const { from, to, symmetric } = parseChangeRange(o.range);
|
|
95
|
+
const fromSha = await resolveCommit(exec, o.cwd, from);
|
|
96
|
+
const toSha = await resolveCommit(exec, o.cwd, to);
|
|
97
|
+
const baseSha = symmetric ? await mergeBase(exec, o.cwd, fromSha, toSha) : fromSha;
|
|
98
|
+
const headSha = toSha;
|
|
99
|
+
assertSha(baseSha);
|
|
100
|
+
assertSha(headSha);
|
|
101
|
+
const diffArgs = [
|
|
102
|
+
"-c",
|
|
103
|
+
"core.fsmonitor=",
|
|
104
|
+
"-c",
|
|
105
|
+
"diff.external=",
|
|
106
|
+
"diff",
|
|
107
|
+
"--no-ext-diff",
|
|
108
|
+
"--no-textconv",
|
|
109
|
+
"--no-color",
|
|
110
|
+
"-M",
|
|
111
|
+
"--unified=0",
|
|
112
|
+
`${baseSha}..${headSha}`,
|
|
113
|
+
"--",
|
|
114
|
+
];
|
|
115
|
+
let stdout;
|
|
116
|
+
try {
|
|
117
|
+
({ stdout } = await exec(diffArgs, { cwd: o.cwd, env: process.env }));
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
throw new ChangesInputError(`git diff failed: ${messageOf(error)}`);
|
|
121
|
+
}
|
|
122
|
+
if (Buffer.byteLength(stdout, "utf8") > maxBytes) {
|
|
123
|
+
throw new ChangesInputError(`change diff exceeds ${maxBytes} bytes`);
|
|
124
|
+
}
|
|
125
|
+
const files = countDiffSections(stdout);
|
|
126
|
+
if (files > maxFiles) {
|
|
127
|
+
throw new ChangesInputError(`change diff touches ${files} files (max ${maxFiles})`);
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
range: o.range,
|
|
131
|
+
baseSha,
|
|
132
|
+
headSha,
|
|
133
|
+
evidence: extractChangeEvidence(stdout, notes),
|
|
134
|
+
scanned: { files, hunks: countHunks(stdout), skipped: skippedPaths(stdout) },
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
async function resolveCommit(exec, cwd, rev) {
|
|
138
|
+
const args = ["rev-parse", "--verify", "--quiet", "--end-of-options", `${rev}^{commit}`];
|
|
139
|
+
let stdout;
|
|
140
|
+
try {
|
|
141
|
+
({ stdout } = await exec(args, { cwd, env: process.env }));
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
throw new ChangesInputError(`cannot resolve change revision ${JSON.stringify(rev)}: ${messageOf(error)}`);
|
|
145
|
+
}
|
|
146
|
+
const sha = stdout.trim();
|
|
147
|
+
if (!SHA_RE.test(sha))
|
|
148
|
+
throw new ChangesInputError(`cannot resolve change revision ${JSON.stringify(rev)}`);
|
|
149
|
+
return sha;
|
|
150
|
+
}
|
|
151
|
+
async function mergeBase(exec, cwd, shaA, shaB) {
|
|
152
|
+
let stdout;
|
|
153
|
+
try {
|
|
154
|
+
({ stdout } = await exec(["merge-base", shaA, shaB], { cwd, env: process.env }));
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
throw new ChangesInputError(`cannot find merge base: ${messageOf(error)}`);
|
|
158
|
+
}
|
|
159
|
+
const sha = stdout.trim();
|
|
160
|
+
if (!SHA_RE.test(sha))
|
|
161
|
+
throw new ChangesInputError(`cannot find merge base for ${shaA}...${shaB}`);
|
|
162
|
+
return sha;
|
|
163
|
+
}
|
|
164
|
+
function assertSha(sha) {
|
|
165
|
+
if (!SHA_RE.test(sha))
|
|
166
|
+
throw new ChangesInputError(`resolved revision is not a commit SHA: ${JSON.stringify(sha)}`);
|
|
167
|
+
}
|
|
168
|
+
function countDiffSections(diff) {
|
|
169
|
+
let count = 0;
|
|
170
|
+
for (const line of diff.split(/\r?\n/))
|
|
171
|
+
if (line.startsWith("diff --git "))
|
|
172
|
+
count++;
|
|
173
|
+
return count;
|
|
174
|
+
}
|
|
175
|
+
function countHunks(diff) {
|
|
176
|
+
let count = 0;
|
|
177
|
+
for (const line of diff.split(/\r?\n/))
|
|
178
|
+
if (line.startsWith("@@ "))
|
|
179
|
+
count++;
|
|
180
|
+
return count;
|
|
181
|
+
}
|
|
182
|
+
function skippedPaths(diff) {
|
|
183
|
+
const paths = [];
|
|
184
|
+
for (const line of diff.split(/\r?\n/)) {
|
|
185
|
+
const header = /^diff --git a\/(.*) b\/(.*)$/.exec(line);
|
|
186
|
+
if (!header)
|
|
187
|
+
continue;
|
|
188
|
+
const newPath = unquotePath(header[2]);
|
|
189
|
+
if (isSkippedChangePath(newPath))
|
|
190
|
+
paths.push(newPath);
|
|
191
|
+
}
|
|
192
|
+
return paths;
|
|
193
|
+
}
|
|
194
|
+
function unquotePath(value) {
|
|
195
|
+
const trimmed = value.trim();
|
|
196
|
+
if (trimmed.length >= 2 && trimmed.startsWith('"') && trimmed.endsWith('"'))
|
|
197
|
+
return trimmed.slice(1, -1);
|
|
198
|
+
return trimmed;
|
|
199
|
+
}
|
|
200
|
+
function messageOf(error) {
|
|
201
|
+
return error instanceof Error ? error.message : String(error);
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=change-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change-context.js","sourceRoot":"","sources":["../src/change-context.ts"],"names":[],"mappings":"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"}
|
package/dist/check-api.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type CheckResult, type RunCheckOptions } from "./check-types.js";
|
|
2
2
|
export { affectedBy } from "./check-plan.js";
|
|
3
3
|
export { BudgetMeter } from "./check-budget.js";
|
|
4
|
-
export { type BudgetReport, CheckAiSetupError, type CheckFinding, type CheckGateways, type CheckItemReport, CheckPreflightError, type CheckResult, type CheckRunners, type ItemKind, type RunCheckOptions } from "./check-types.js";
|
|
4
|
+
export { type BudgetReport, CheckAiSetupError, CheckArgsError, type CheckFinding, type CheckGateways, type CheckItemReport, CheckPreflightError, type CheckResult, type CheckRunners, type ItemKind, type RunCheckOptions } from "./check-types.js";
|
|
5
5
|
export declare function runCheck(opts: RunCheckOptions): Promise<CheckResult>;
|