@devenius/junamis-skills 0.0.0-stage → 1.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.
- package/CHANGELOG.md +150 -0
- package/LICENSE +21 -0
- package/README.md +231 -2
- package/SECURITY.md +81 -0
- package/bin/junamis-skills.js +7 -0
- package/dist/cli.d.ts +59 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +564 -0
- package/dist/cli.js.map +1 -0
- package/dist/color.d.ts +40 -0
- package/dist/color.d.ts.map +1 -0
- package/dist/color.js +55 -0
- package/dist/color.js.map +1 -0
- package/dist/design/atomic.d.ts +4 -0
- package/dist/design/atomic.d.ts.map +1 -0
- package/dist/design/atomic.js +14 -0
- package/dist/design/atomic.js.map +1 -0
- package/dist/design/bootstrap.d.ts +23 -0
- package/dist/design/bootstrap.d.ts.map +1 -0
- package/dist/design/bootstrap.js +411 -0
- package/dist/design/bootstrap.js.map +1 -0
- package/dist/design/cli.d.ts +86 -0
- package/dist/design/cli.d.ts.map +1 -0
- package/dist/design/cli.js +425 -0
- package/dist/design/cli.js.map +1 -0
- package/dist/design/delta.d.ts +45 -0
- package/dist/design/delta.d.ts.map +1 -0
- package/dist/design/delta.js +557 -0
- package/dist/design/delta.js.map +1 -0
- package/dist/design/drift.d.ts +26 -0
- package/dist/design/drift.d.ts.map +1 -0
- package/dist/design/drift.js +341 -0
- package/dist/design/drift.js.map +1 -0
- package/dist/design/errors.d.ts +25 -0
- package/dist/design/errors.d.ts.map +1 -0
- package/dist/design/errors.js +30 -0
- package/dist/design/errors.js.map +1 -0
- package/dist/design/events.d.ts +18 -0
- package/dist/design/events.d.ts.map +1 -0
- package/dist/design/events.js +44 -0
- package/dist/design/events.js.map +1 -0
- package/dist/design/fingerprint.d.ts +10 -0
- package/dist/design/fingerprint.d.ts.map +1 -0
- package/dist/design/fingerprint.js +66 -0
- package/dist/design/fingerprint.js.map +1 -0
- package/dist/design/index-gen.d.ts +16 -0
- package/dist/design/index-gen.d.ts.map +1 -0
- package/dist/design/index-gen.js +94 -0
- package/dist/design/index-gen.js.map +1 -0
- package/dist/design/schema.d.ts +54 -0
- package/dist/design/schema.d.ts.map +1 -0
- package/dist/design/schema.js +408 -0
- package/dist/design/schema.js.map +1 -0
- package/dist/design/yaml.d.ts +12 -0
- package/dist/design/yaml.d.ts.map +1 -0
- package/dist/design/yaml.js +264 -0
- package/dist/design/yaml.js.map +1 -0
- package/dist/external.d.ts +61 -0
- package/dist/external.d.ts.map +1 -0
- package/dist/external.js +426 -0
- package/dist/external.js.map +1 -0
- package/dist/guide.d.ts +17 -0
- package/dist/guide.d.ts.map +1 -0
- package/dist/guide.js +219 -0
- package/dist/guide.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/install-external.d.ts +3 -0
- package/dist/install-external.d.ts.map +1 -0
- package/dist/install-external.js +37 -0
- package/dist/install-external.js.map +1 -0
- package/dist/library-install.d.ts +39 -0
- package/dist/library-install.d.ts.map +1 -0
- package/dist/library-install.js +663 -0
- package/dist/library-install.js.map +1 -0
- package/dist/orchestrator/boot.d.ts +3 -0
- package/dist/orchestrator/boot.d.ts.map +1 -0
- package/dist/orchestrator/boot.js +515 -0
- package/dist/orchestrator/boot.js.map +1 -0
- package/dist/orchestrator/cli.d.ts +37 -0
- package/dist/orchestrator/cli.d.ts.map +1 -0
- package/dist/orchestrator/cli.js +563 -0
- package/dist/orchestrator/cli.js.map +1 -0
- package/dist/orchestrator/commands.d.ts +46 -0
- package/dist/orchestrator/commands.d.ts.map +1 -0
- package/dist/orchestrator/commands.js +752 -0
- package/dist/orchestrator/commands.js.map +1 -0
- package/dist/orchestrator/compaction.d.ts +21 -0
- package/dist/orchestrator/compaction.d.ts.map +1 -0
- package/dist/orchestrator/compaction.js +93 -0
- package/dist/orchestrator/compaction.js.map +1 -0
- package/dist/orchestrator/drift.d.ts +11 -0
- package/dist/orchestrator/drift.d.ts.map +1 -0
- package/dist/orchestrator/drift.js +181 -0
- package/dist/orchestrator/drift.js.map +1 -0
- package/dist/orchestrator/errors.d.ts +52 -0
- package/dist/orchestrator/errors.d.ts.map +1 -0
- package/dist/orchestrator/errors.js +96 -0
- package/dist/orchestrator/errors.js.map +1 -0
- package/dist/orchestrator/frontmatter.d.ts +6 -0
- package/dist/orchestrator/frontmatter.d.ts.map +1 -0
- package/dist/orchestrator/frontmatter.js +50 -0
- package/dist/orchestrator/frontmatter.js.map +1 -0
- package/dist/orchestrator/fsx.d.ts +45 -0
- package/dist/orchestrator/fsx.d.ts.map +1 -0
- package/dist/orchestrator/fsx.js +295 -0
- package/dist/orchestrator/fsx.js.map +1 -0
- package/dist/orchestrator/handoff.d.ts +8 -0
- package/dist/orchestrator/handoff.d.ts.map +1 -0
- package/dist/orchestrator/handoff.js +246 -0
- package/dist/orchestrator/handoff.js.map +1 -0
- package/dist/orchestrator/hash.d.ts +10 -0
- package/dist/orchestrator/hash.d.ts.map +1 -0
- package/dist/orchestrator/hash.js +65 -0
- package/dist/orchestrator/hash.js.map +1 -0
- package/dist/orchestrator/journal.d.ts +35 -0
- package/dist/orchestrator/journal.d.ts.map +1 -0
- package/dist/orchestrator/journal.js +163 -0
- package/dist/orchestrator/journal.js.map +1 -0
- package/dist/orchestrator/lease.d.ts +31 -0
- package/dist/orchestrator/lease.d.ts.map +1 -0
- package/dist/orchestrator/lease.js +175 -0
- package/dist/orchestrator/lease.js.map +1 -0
- package/dist/orchestrator/plan.d.ts +27 -0
- package/dist/orchestrator/plan.d.ts.map +1 -0
- package/dist/orchestrator/plan.js +240 -0
- package/dist/orchestrator/plan.js.map +1 -0
- package/dist/orchestrator/report.d.ts +49 -0
- package/dist/orchestrator/report.d.ts.map +1 -0
- package/dist/orchestrator/report.js +244 -0
- package/dist/orchestrator/report.js.map +1 -0
- package/dist/orchestrator/state.d.ts +43 -0
- package/dist/orchestrator/state.d.ts.map +1 -0
- package/dist/orchestrator/state.js +369 -0
- package/dist/orchestrator/state.js.map +1 -0
- package/dist/orchestrator/store.d.ts +42 -0
- package/dist/orchestrator/store.d.ts.map +1 -0
- package/dist/orchestrator/store.js +202 -0
- package/dist/orchestrator/store.js.map +1 -0
- package/dist/orchestrator/test-hooks.d.ts +5 -0
- package/dist/orchestrator/test-hooks.d.ts.map +1 -0
- package/dist/orchestrator/test-hooks.js +31 -0
- package/dist/orchestrator/test-hooks.js.map +1 -0
- package/dist/orchestrator/time.d.ts +11 -0
- package/dist/orchestrator/time.d.ts.map +1 -0
- package/dist/orchestrator/time.js +38 -0
- package/dist/orchestrator/time.js.map +1 -0
- package/dist/paths.d.ts +9 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +42 -0
- package/dist/paths.js.map +1 -0
- package/dist/pinned-source.d.ts +13 -0
- package/dist/pinned-source.d.ts.map +1 -0
- package/dist/pinned-source.js +238 -0
- package/dist/pinned-source.js.map +1 -0
- package/dist/reconcile/cli.d.ts +17 -0
- package/dist/reconcile/cli.d.ts.map +1 -0
- package/dist/reconcile/cli.js +171 -0
- package/dist/reconcile/cli.js.map +1 -0
- package/dist/reconcile/detectors.d.ts +29 -0
- package/dist/reconcile/detectors.d.ts.map +1 -0
- package/dist/reconcile/detectors.js +294 -0
- package/dist/reconcile/detectors.js.map +1 -0
- package/dist/reconcile/manifest.d.ts +11 -0
- package/dist/reconcile/manifest.d.ts.map +1 -0
- package/dist/reconcile/manifest.js +118 -0
- package/dist/reconcile/manifest.js.map +1 -0
- package/dist/reconcile/queue.d.ts +3 -0
- package/dist/reconcile/queue.d.ts.map +1 -0
- package/dist/reconcile/queue.js +723 -0
- package/dist/reconcile/queue.js.map +1 -0
- package/dist/reconcile/score.d.ts +19 -0
- package/dist/reconcile/score.d.ts.map +1 -0
- package/dist/reconcile/score.js +58 -0
- package/dist/reconcile/score.js.map +1 -0
- package/dist/scripts/check-opencode-config.d.ts +12 -0
- package/dist/scripts/check-opencode-config.d.ts.map +1 -0
- package/dist/scripts/check-opencode-config.js +216 -0
- package/dist/scripts/check-opencode-config.js.map +1 -0
- package/dist/scripts/check-pack.d.ts +3 -0
- package/dist/scripts/check-pack.d.ts.map +1 -0
- package/dist/scripts/check-pack.js +74 -0
- package/dist/scripts/check-pack.js.map +1 -0
- package/dist/scripts/check-pins.d.ts +9 -0
- package/dist/scripts/check-pins.d.ts.map +1 -0
- package/dist/scripts/check-pins.js +65 -0
- package/dist/scripts/check-pins.js.map +1 -0
- package/dist/scripts/check-security.d.ts +3 -0
- package/dist/scripts/check-security.d.ts.map +1 -0
- package/dist/scripts/check-security.js +47 -0
- package/dist/scripts/check-security.js.map +1 -0
- package/dist/scripts/check-skills-lock.d.ts +7 -0
- package/dist/scripts/check-skills-lock.d.ts.map +1 -0
- package/dist/scripts/check-skills-lock.js +36 -0
- package/dist/scripts/check-skills-lock.js.map +1 -0
- package/dist/scripts/check-skills-sync.d.ts +7 -0
- package/dist/scripts/check-skills-sync.d.ts.map +1 -0
- package/dist/scripts/check-skills-sync.js +146 -0
- package/dist/scripts/check-skills-sync.js.map +1 -0
- package/dist/scripts/check-yaml.d.ts +3 -0
- package/dist/scripts/check-yaml.d.ts.map +1 -0
- package/dist/scripts/check-yaml.js +41 -0
- package/dist/scripts/check-yaml.js.map +1 -0
- package/dist/scripts/publish-npm.d.ts +3 -0
- package/dist/scripts/publish-npm.d.ts.map +1 -0
- package/dist/scripts/publish-npm.js +67 -0
- package/dist/scripts/publish-npm.js.map +1 -0
- package/dist/scripts/release-check.d.ts +3 -0
- package/dist/scripts/release-check.d.ts.map +1 -0
- package/dist/scripts/release-check.js +97 -0
- package/dist/scripts/release-check.js.map +1 -0
- package/dist/scripts/support.d.ts +41 -0
- package/dist/scripts/support.d.ts.map +1 -0
- package/dist/scripts/support.js +78 -0
- package/dist/scripts/support.js.map +1 -0
- package/dist/targets/claude.d.ts +4 -0
- package/dist/targets/claude.d.ts.map +1 -0
- package/dist/targets/claude.js +42 -0
- package/dist/targets/claude.js.map +1 -0
- package/dist/targets/cline.d.ts +4 -0
- package/dist/targets/cline.d.ts.map +1 -0
- package/dist/targets/cline.js +39 -0
- package/dist/targets/cline.js.map +1 -0
- package/dist/targets/cursor.d.ts +4 -0
- package/dist/targets/cursor.d.ts.map +1 -0
- package/dist/targets/cursor.js +40 -0
- package/dist/targets/cursor.js.map +1 -0
- package/dist/targets/index.d.ts +4 -0
- package/dist/targets/index.d.ts.map +1 -0
- package/dist/targets/index.js +11 -0
- package/dist/targets/index.js.map +1 -0
- package/dist/targets/opencode.d.ts +4 -0
- package/dist/targets/opencode.d.ts.map +1 -0
- package/dist/targets/opencode.js +48 -0
- package/dist/targets/opencode.js.map +1 -0
- package/dist/targets/windsurf.d.ts +4 -0
- package/dist/targets/windsurf.d.ts.map +1 -0
- package/dist/targets/windsurf.js +41 -0
- package/dist/targets/windsurf.js.map +1 -0
- package/dist/types/common.d.ts +193 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +6 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/design.d.ts +185 -0
- package/dist/types/design.d.ts.map +1 -0
- package/dist/types/design.js +3 -0
- package/dist/types/design.js.map +1 -0
- package/dist/types/guards.d.ts +13 -0
- package/dist/types/guards.d.ts.map +1 -0
- package/dist/types/guards.js +64 -0
- package/dist/types/guards.js.map +1 -0
- package/dist/types/handoff.d.ts +29 -0
- package/dist/types/handoff.d.ts.map +1 -0
- package/dist/types/handoff.js +3 -0
- package/dist/types/handoff.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +11 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/orchestrator.d.ts +414 -0
- package/dist/types/orchestrator.d.ts.map +1 -0
- package/dist/types/orchestrator.js +4 -0
- package/dist/types/orchestrator.js.map +1 -0
- package/dist/types/reconcile.d.ts +160 -0
- package/dist/types/reconcile.d.ts.map +1 -0
- package/dist/types/reconcile.js +3 -0
- package/dist/types/reconcile.js.map +1 -0
- package/docs/RECONCILE.md +505 -0
- package/docs/design/_schema.md +506 -0
- package/junamis-skills.yml +328 -0
- package/library/EXTERNAL.md +35 -0
- package/library/HANDOFF.md +93 -0
- package/library/RESUME.md +429 -0
- package/library/SAFETY.md +83 -0
- package/library/agents/context-keeper.md +41 -0
- package/library/agents/frontend.md +43 -0
- package/library/agents/maintainer.md +44 -0
- package/library/agents/nestjs.md +40 -0
- package/library/agents/nextjs.md +40 -0
- package/library/agents/operator.md +42 -0
- package/library/agents/orchestrator.md +313 -0
- package/library/agents/researcher.md +40 -0
- package/library/agents/reviewer.md +40 -0
- package/library/skills/db-migrate/SKILL.md +50 -0
- package/library/skills/decision-record/SKILL.md +74 -0
- package/library/skills/dependency-upgrade/SKILL.md +57 -0
- package/library/skills/deploy-verify/SKILL.md +51 -0
- package/library/skills/document/SKILL.md +51 -0
- package/library/skills/env-doctor/SKILL.md +65 -0
- package/library/skills/frontend/SKILL.md +63 -0
- package/library/skills/handoff/SKILL.md +79 -0
- package/library/skills/incident-response/SKILL.md +69 -0
- package/library/skills/nestjs/SKILL.md +49 -0
- package/library/skills/nextjs/SKILL.md +48 -0
- package/library/skills/perf-budget/SKILL.md +62 -0
- package/library/skills/refactor-safely/SKILL.md +48 -0
- package/library/skills/release-prep/SKILL.md +75 -0
- package/library/skills/research/SKILL.md +66 -0
- package/library/skills/rollback/SKILL.md +49 -0
- package/library/skills/route/SKILL.md +107 -0
- package/library/skills/route-external/SKILL.md +67 -0
- package/library/skills/security-audit/SKILL.md +64 -0
- package/library/skills/skill-author/SKILL.md +49 -0
- package/opencode.json +5906 -0
- package/package.json +88 -4
- package/scripts/design-registry.mjs +7 -0
- package/scripts/orchestrator-state.mjs +7 -0
- package/scripts/reconcile.mjs +7 -0
- package/skills-lock.json +197 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
// Design drift detectors.
|
|
2
|
+
//
|
|
3
|
+
// Code drift compares files matched by code_paths against the surface's
|
|
4
|
+
// last_reviewed_commit, or against last_reviewed by mtime when git is
|
|
5
|
+
// unavailable. Dependency drift compares the dependent surface's current
|
|
6
|
+
// version with the version recorded in its change log at or before this
|
|
7
|
+
// surface's last_reviewed. Coverage reports overlapping claims and unclaimed
|
|
8
|
+
// source files; overlap is always reported, and the bootstrap flag gates the
|
|
9
|
+
// failure until a human or architect flips it.
|
|
10
|
+
import { spawnSync } from "node:child_process";
|
|
11
|
+
import { join, relative } from "node:path";
|
|
12
|
+
import { listDir, readJsonFile, statSafe, toPosixPath } from "../orchestrator/fsx.js";
|
|
13
|
+
import { ValidationError } from "./errors.js";
|
|
14
|
+
import { loadSurfaces } from "./schema.js";
|
|
15
|
+
import { isRecord } from "../types/guards.js";
|
|
16
|
+
const EXCLUDED_DIRS = new Set([
|
|
17
|
+
"node_modules",
|
|
18
|
+
".git",
|
|
19
|
+
".orchestrator",
|
|
20
|
+
".junamis",
|
|
21
|
+
".config",
|
|
22
|
+
"docs",
|
|
23
|
+
"test",
|
|
24
|
+
"tests",
|
|
25
|
+
"coverage",
|
|
26
|
+
"dist",
|
|
27
|
+
"build",
|
|
28
|
+
"out",
|
|
29
|
+
]);
|
|
30
|
+
const CODE_EXTENSIONS = new Set([
|
|
31
|
+
".js",
|
|
32
|
+
".mjs",
|
|
33
|
+
".cjs",
|
|
34
|
+
".jsx",
|
|
35
|
+
".ts",
|
|
36
|
+
".tsx",
|
|
37
|
+
".vue",
|
|
38
|
+
".svelte",
|
|
39
|
+
".py",
|
|
40
|
+
".go",
|
|
41
|
+
".rs",
|
|
42
|
+
".java",
|
|
43
|
+
".kt",
|
|
44
|
+
".rb",
|
|
45
|
+
".php",
|
|
46
|
+
".cs",
|
|
47
|
+
".swift",
|
|
48
|
+
".css",
|
|
49
|
+
".scss",
|
|
50
|
+
".sass",
|
|
51
|
+
".less",
|
|
52
|
+
".html",
|
|
53
|
+
".sh",
|
|
54
|
+
".bash",
|
|
55
|
+
]);
|
|
56
|
+
function escapeRegExp(char) {
|
|
57
|
+
return /[.*+?^${}()|[\]\\]/.test(char) ? `\\${char}` : char;
|
|
58
|
+
}
|
|
59
|
+
export function globToRegExp(pattern) {
|
|
60
|
+
const normalized = String(pattern).replace(/\\/g, "/").replace(/^\.\//, "");
|
|
61
|
+
const source = normalized.endsWith("/") ? `${normalized}**` : normalized;
|
|
62
|
+
let out = "^";
|
|
63
|
+
for (let i = 0; i < source.length; i++) {
|
|
64
|
+
const char = source[i] ?? "";
|
|
65
|
+
if (char === "*") {
|
|
66
|
+
if (source[i + 1] === "*") {
|
|
67
|
+
i += 1;
|
|
68
|
+
if (source[i + 1] === "/") {
|
|
69
|
+
i += 1;
|
|
70
|
+
out += "(?:.*/)?";
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
out += ".*";
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
out += "[^/]*";
|
|
78
|
+
}
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (char === "?") {
|
|
82
|
+
out += "[^/]";
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (char === "[") {
|
|
86
|
+
const end = source.indexOf("]", i + 1);
|
|
87
|
+
if (end !== -1) {
|
|
88
|
+
out += source.slice(i, end + 1);
|
|
89
|
+
i = end;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
out += escapeRegExp(char);
|
|
94
|
+
}
|
|
95
|
+
out += "$";
|
|
96
|
+
return new RegExp(out);
|
|
97
|
+
}
|
|
98
|
+
export function matchesAny(path, patterns) {
|
|
99
|
+
return (patterns ?? []).some((pattern) => {
|
|
100
|
+
try {
|
|
101
|
+
return globToRegExp(pattern).test(path);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
async function walk(root, current, out) {
|
|
109
|
+
const entries = await listDir(current);
|
|
110
|
+
for (const entry of entries) {
|
|
111
|
+
if (entry.isSymbolicLink())
|
|
112
|
+
continue;
|
|
113
|
+
const path = join(current, entry.name);
|
|
114
|
+
if (entry.isDirectory()) {
|
|
115
|
+
if (EXCLUDED_DIRS.has(entry.name))
|
|
116
|
+
continue;
|
|
117
|
+
if (entry.name.startsWith("."))
|
|
118
|
+
continue;
|
|
119
|
+
await walk(root, path, out);
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (!entry.isFile())
|
|
123
|
+
continue;
|
|
124
|
+
out.push(toPosixPath(relative(root, path)));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
export async function listProjectFiles(projectRoot) {
|
|
128
|
+
const out = [];
|
|
129
|
+
await walk(projectRoot, projectRoot, out);
|
|
130
|
+
out.sort((a, b) => Buffer.compare(Buffer.from(a, "utf8"), Buffer.from(b, "utf8")));
|
|
131
|
+
return out;
|
|
132
|
+
}
|
|
133
|
+
function gitLines(projectRoot, args) {
|
|
134
|
+
const result = spawnSync("git", args, {
|
|
135
|
+
cwd: projectRoot,
|
|
136
|
+
encoding: "utf8",
|
|
137
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
138
|
+
});
|
|
139
|
+
if (result.status !== 0)
|
|
140
|
+
return null;
|
|
141
|
+
return (result.stdout ?? "")
|
|
142
|
+
.split("\n")
|
|
143
|
+
.map((line) => line.trim())
|
|
144
|
+
.filter(Boolean);
|
|
145
|
+
}
|
|
146
|
+
function gitCommitTime(projectRoot, path) {
|
|
147
|
+
const lines = gitLines(projectRoot, ["log", "-1", "--format=%ct", "--", path]);
|
|
148
|
+
if (!lines || lines.length === 0)
|
|
149
|
+
return null;
|
|
150
|
+
const value = Number.parseInt(lines[0] ?? "", 10);
|
|
151
|
+
return Number.isFinite(value) ? value : null;
|
|
152
|
+
}
|
|
153
|
+
async function mtimeMs(path) {
|
|
154
|
+
const stat = await statSafe(path);
|
|
155
|
+
return stat ? stat.mtimeMs : null;
|
|
156
|
+
}
|
|
157
|
+
async function codeChangedFiles(surface, { projectRoot, matched, git }) {
|
|
158
|
+
const frontmatter = surface.frontmatter;
|
|
159
|
+
if (!frontmatter)
|
|
160
|
+
return [];
|
|
161
|
+
const commit = frontmatter.last_reviewed_commit;
|
|
162
|
+
if (git && commit) {
|
|
163
|
+
const changed = gitLines(projectRoot, ["diff", "--name-only", `${commit}..HEAD`, "--", ...matched]);
|
|
164
|
+
if (changed !== null) {
|
|
165
|
+
const matchedSet = new Set(matched);
|
|
166
|
+
const files = changed.filter((path) => matchedSet.has(path));
|
|
167
|
+
if (files.length === 0)
|
|
168
|
+
return [];
|
|
169
|
+
const designRelative = toPosixPath(relative(projectRoot, surface.file));
|
|
170
|
+
const designTime = gitCommitTime(projectRoot, designRelative);
|
|
171
|
+
let codeTime = 0;
|
|
172
|
+
for (const path of files) {
|
|
173
|
+
const time = gitCommitTime(projectRoot, path);
|
|
174
|
+
if (time !== null && time > codeTime)
|
|
175
|
+
codeTime = time;
|
|
176
|
+
}
|
|
177
|
+
// A design update at or after the code change is the delta that
|
|
178
|
+
// accompanied it. Only code newer than the design is drift.
|
|
179
|
+
if (designTime !== null && codeTime > 0 && designTime >= codeTime)
|
|
180
|
+
return [];
|
|
181
|
+
return files;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const cutoff = new Date(`${frontmatter.last_reviewed ?? ""}T23:59:59Z`).getTime();
|
|
185
|
+
const changed = [];
|
|
186
|
+
for (const path of matched) {
|
|
187
|
+
const mtime = await mtimeMs(join(projectRoot, path));
|
|
188
|
+
if (mtime !== null && mtime > cutoff)
|
|
189
|
+
changed.push(path);
|
|
190
|
+
}
|
|
191
|
+
if (changed.length === 0)
|
|
192
|
+
return [];
|
|
193
|
+
const designMtime = await mtimeMs(surface.file);
|
|
194
|
+
let newest = 0;
|
|
195
|
+
for (const path of changed) {
|
|
196
|
+
const mtime = await mtimeMs(join(projectRoot, path));
|
|
197
|
+
if (mtime !== null && mtime > newest)
|
|
198
|
+
newest = mtime;
|
|
199
|
+
}
|
|
200
|
+
if (designMtime !== null && designMtime >= newest && newest > 0)
|
|
201
|
+
return [];
|
|
202
|
+
return changed;
|
|
203
|
+
}
|
|
204
|
+
export async function detectCodeDrift({ designRoot, projectRoot, git = true }) {
|
|
205
|
+
const loaded = await loadSurfaces(designRoot, { validate: true });
|
|
206
|
+
if (loaded.errors.length > 0) {
|
|
207
|
+
const lines = loaded.errors.flatMap((entry) => entry.errors.map((error) => `${entry.file}: ${error}`));
|
|
208
|
+
throw new ValidationError("cannot detect drift on an invalid design registry", { errors: lines });
|
|
209
|
+
}
|
|
210
|
+
const projectFiles = await listProjectFiles(projectRoot);
|
|
211
|
+
const flags = [];
|
|
212
|
+
for (const surface of loaded.surfaces) {
|
|
213
|
+
if (surface.frontmatter?.status !== "active")
|
|
214
|
+
continue;
|
|
215
|
+
const patterns = surface.frontmatter?.code_paths ?? [];
|
|
216
|
+
const matched = projectFiles.filter((path) => matchesAny(path, patterns));
|
|
217
|
+
if (matched.length === 0)
|
|
218
|
+
continue;
|
|
219
|
+
const files = await codeChangedFiles(surface, { projectRoot, matched, git });
|
|
220
|
+
if (files.length === 0)
|
|
221
|
+
continue;
|
|
222
|
+
flags.push({
|
|
223
|
+
type: "CODE_DRIFT",
|
|
224
|
+
surface_id: surface.surface_id,
|
|
225
|
+
files,
|
|
226
|
+
last_reviewed: surface.frontmatter?.last_reviewed ?? "",
|
|
227
|
+
last_reviewed_commit: surface.frontmatter?.last_reviewed_commit ?? null,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
return flags;
|
|
231
|
+
}
|
|
232
|
+
function parseChangeLog(body) {
|
|
233
|
+
const entries = [];
|
|
234
|
+
for (const line of String(body ?? "").split("\n")) {
|
|
235
|
+
const match = /^-\s+(\d{4}-\d{2}-\d{2})\s+·\s+v(\d+\.\d+\.\d+)/.exec(line.trim());
|
|
236
|
+
if (match)
|
|
237
|
+
entries.push({ date: match[1] ?? "", version: match[2] ?? "" });
|
|
238
|
+
}
|
|
239
|
+
return entries;
|
|
240
|
+
}
|
|
241
|
+
function versionAt(entries, date) {
|
|
242
|
+
let found = null;
|
|
243
|
+
for (const entry of entries) {
|
|
244
|
+
if (entry.date <= (date ?? ""))
|
|
245
|
+
found = entry.version;
|
|
246
|
+
}
|
|
247
|
+
return found;
|
|
248
|
+
}
|
|
249
|
+
export async function detectDependencyDrift({ designRoot }) {
|
|
250
|
+
const loaded = await loadSurfaces(designRoot, { validate: true });
|
|
251
|
+
if (loaded.errors.length > 0) {
|
|
252
|
+
const lines = loaded.errors.flatMap((entry) => entry.errors.map((error) => `${entry.file}: ${error}`));
|
|
253
|
+
throw new ValidationError("cannot detect dependency drift on an invalid design registry", { errors: lines });
|
|
254
|
+
}
|
|
255
|
+
const byId = new Map(loaded.surfaces.map((surface) => [surface.surface_id, surface]));
|
|
256
|
+
const flags = [];
|
|
257
|
+
for (const surface of loaded.surfaces) {
|
|
258
|
+
const lastReviewed = surface.frontmatter?.last_reviewed;
|
|
259
|
+
for (const depId of surface.frontmatter?.depends_on ?? []) {
|
|
260
|
+
const dep = byId.get(depId);
|
|
261
|
+
if (!dep)
|
|
262
|
+
continue;
|
|
263
|
+
const recorded = versionAt(parseChangeLog(dep.body), lastReviewed);
|
|
264
|
+
if (recorded === null)
|
|
265
|
+
continue;
|
|
266
|
+
const current = dep.frontmatter?.version ?? null;
|
|
267
|
+
if (recorded !== current) {
|
|
268
|
+
flags.push({
|
|
269
|
+
type: "DEPENDENCY_DRIFT",
|
|
270
|
+
surface_id: surface.surface_id,
|
|
271
|
+
depends_on: depId,
|
|
272
|
+
recorded_version: recorded,
|
|
273
|
+
current_version: current,
|
|
274
|
+
at: lastReviewed ?? "",
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return flags;
|
|
280
|
+
}
|
|
281
|
+
export async function readBootstrapFlag(designRoot) {
|
|
282
|
+
const parsed = await readJsonFile(join(designRoot, "_registry.json"));
|
|
283
|
+
if (!parsed.exists || parsed.error || !isRecord(parsed.value)) {
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
return parsed.value["bootstrap_complete"] === true;
|
|
287
|
+
}
|
|
288
|
+
export async function detectCoverage({ designRoot, projectRoot }) {
|
|
289
|
+
const loaded = await loadSurfaces(designRoot, { validate: true });
|
|
290
|
+
if (loaded.errors.length > 0) {
|
|
291
|
+
const lines = loaded.errors.flatMap((entry) => entry.errors.map((error) => `${entry.file}: ${error}`));
|
|
292
|
+
throw new ValidationError("cannot audit coverage on an invalid design registry", { errors: lines });
|
|
293
|
+
}
|
|
294
|
+
const projectFiles = await listProjectFiles(projectRoot);
|
|
295
|
+
const codeFiles = projectFiles.filter((path) => CODE_EXTENSIONS.has(extnameLower(path)));
|
|
296
|
+
const claims = new Map();
|
|
297
|
+
for (const surface of loaded.surfaces) {
|
|
298
|
+
for (const path of codeFiles) {
|
|
299
|
+
if (!matchesAny(path, surface.frontmatter?.code_paths ?? []))
|
|
300
|
+
continue;
|
|
301
|
+
const existing = claims.get(path);
|
|
302
|
+
if (existing)
|
|
303
|
+
existing.push(surface.surface_id);
|
|
304
|
+
else
|
|
305
|
+
claims.set(path, [surface.surface_id]);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
const overlaps = [];
|
|
309
|
+
for (const [path, surfaces] of claims) {
|
|
310
|
+
if (surfaces.length > 1)
|
|
311
|
+
overlaps.push({ path, surfaces: [...surfaces].sort() });
|
|
312
|
+
}
|
|
313
|
+
const unclaimed = codeFiles.filter((path) => !claims.has(path));
|
|
314
|
+
const bootstrapComplete = await readBootstrapFlag(designRoot);
|
|
315
|
+
const enforced = bootstrapComplete === true;
|
|
316
|
+
return {
|
|
317
|
+
bootstrap_complete: bootstrapComplete,
|
|
318
|
+
enforced,
|
|
319
|
+
overlaps: overlaps.sort((a, b) => a.path.localeCompare(b.path)),
|
|
320
|
+
unclaimed,
|
|
321
|
+
claimed_files: claims.size,
|
|
322
|
+
code_files: codeFiles.length,
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
function extnameLower(path) {
|
|
326
|
+
const index = path.lastIndexOf(".");
|
|
327
|
+
return index === -1 ? "" : path.slice(index).toLowerCase();
|
|
328
|
+
}
|
|
329
|
+
export async function runDrift({ designRoot, projectRoot, git = true }) {
|
|
330
|
+
const code = await detectCodeDrift({ designRoot, projectRoot, git });
|
|
331
|
+
const dependency = await detectDependencyDrift({ designRoot });
|
|
332
|
+
const coverage = await detectCoverage({ designRoot, projectRoot });
|
|
333
|
+
const coverageFailing = coverage.enforced && (coverage.overlaps.length > 0 || coverage.unclaimed.length > 0);
|
|
334
|
+
return {
|
|
335
|
+
ok: code.length === 0 && dependency.length === 0 && !coverageFailing,
|
|
336
|
+
code,
|
|
337
|
+
dependency,
|
|
338
|
+
coverage,
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
//# sourceMappingURL=drift.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drift.js","sourceRoot":"","sources":["../../src/design/drift.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface DesignErrorOptions {
|
|
2
|
+
readonly code?: string;
|
|
3
|
+
readonly exitCode?: number;
|
|
4
|
+
readonly detail?: unknown;
|
|
5
|
+
}
|
|
6
|
+
export declare class DesignError extends Error {
|
|
7
|
+
readonly code: string;
|
|
8
|
+
readonly exitCode: number;
|
|
9
|
+
readonly detail: unknown;
|
|
10
|
+
constructor(message: string, { code, exitCode, detail }?: DesignErrorOptions);
|
|
11
|
+
}
|
|
12
|
+
export declare class UsageError extends DesignError {
|
|
13
|
+
constructor(message: string, options?: DesignErrorOptions);
|
|
14
|
+
}
|
|
15
|
+
export declare class ValidationError extends DesignError {
|
|
16
|
+
readonly errors: readonly string[];
|
|
17
|
+
constructor(message: string, { errors, detail }?: {
|
|
18
|
+
readonly errors?: readonly string[];
|
|
19
|
+
readonly detail?: unknown;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export declare class DeltaError extends DesignError {
|
|
23
|
+
constructor(message: string, { code, detail }?: DesignErrorOptions);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/design/errors.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,qBAAa,WAAY,SAAQ,KAAK;IACpC,SAAiB,IAAI,EAAE,MAAM,CAAC;IAC9B,SAAiB,QAAQ,EAAE,MAAM,CAAC;IAClC,SAAiB,MAAM,EAAE,OAAO,CAAC;IAEjC,YACE,OAAO,EAAE,MAAM,EACf,EAAE,IAAqB,EAAE,QAAY,EAAE,MAAa,EAAE,GAAE,kBAAuB,EAOhF;CACF;AAED,qBAAa,UAAW,SAAQ,WAAW;IACzC,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,EAE5D;CACF;AAED,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,SAAiB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAE3C,YAAY,OAAO,EAAE,MAAM,EAAE,EAAE,MAAW,EAAE,MAAa,EAAE,GAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAO,EAGnI;CACF;AAED,qBAAa,UAAW,SAAQ,WAAW;IACzC,YAAY,OAAO,EAAE,MAAM,EAAE,EAAE,IAAsB,EAAE,MAAa,EAAE,GAAE,kBAAuB,EAE9F;CACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Typed errors for the design registry.
|
|
2
|
+
//
|
|
3
|
+
// The CLI maps one error class to one exit code. Validation errors carry every
|
|
4
|
+
// problem found so a single run can report the whole file.
|
|
5
|
+
export class DesignError extends Error {
|
|
6
|
+
constructor(message, { code = "design_error", exitCode = 1, detail = null } = {}) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = new.target.name;
|
|
9
|
+
this.code = code;
|
|
10
|
+
this.exitCode = exitCode;
|
|
11
|
+
this.detail = detail;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class UsageError extends DesignError {
|
|
15
|
+
constructor(message, options = {}) {
|
|
16
|
+
super(message, { code: "usage", ...options });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class ValidationError extends DesignError {
|
|
20
|
+
constructor(message, { errors = [], detail = null } = {}) {
|
|
21
|
+
super(message, { code: "invalid_design", detail: detail ?? { errors } });
|
|
22
|
+
this.errors = errors;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export class DeltaError extends DesignError {
|
|
26
|
+
constructor(message, { code = "invalid_delta", detail = null } = {}) {
|
|
27
|
+
super(message, { code, detail });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/design/errors.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,EAAE;AACF,+EAA+E;AAC/E,2DAA2D;AAQ3D,MAAM,OAAO,WAAY,SAAQ,KAAK;IAKpC,YACE,OAAe,EACf,EAAE,IAAI,GAAG,cAAc,EAAE,QAAQ,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,GAAuB,EAAE;QAE/E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED,MAAM,OAAO,UAAW,SAAQ,WAAW;IACzC,YAAY,OAAe,EAAE,OAAO,GAAuB,EAAE;QAC3D,KAAK,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IAChD,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,WAAW;IAG9C,YAAY,OAAe,EAAE,EAAE,MAAM,GAAG,EAAE,EAAE,MAAM,GAAG,IAAI,EAAE,GAAuE,EAAE;QAClI,KAAK,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;QACzE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED,MAAM,OAAO,UAAW,SAAQ,WAAW;IACzC,YAAY,OAAe,EAAE,EAAE,IAAI,GAAG,eAAe,EAAE,MAAM,GAAG,IAAI,EAAE,GAAuB,EAAE;QAC7F,KAAK,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACnC,CAAC;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { JournalEvent } from "../types/orchestrator.js";
|
|
2
|
+
export interface DesignEventInput {
|
|
3
|
+
readonly stateRoot: string;
|
|
4
|
+
readonly type: string;
|
|
5
|
+
readonly payload?: Record<string, unknown>;
|
|
6
|
+
readonly taskId?: string | null;
|
|
7
|
+
}
|
|
8
|
+
export type DesignEventResult = {
|
|
9
|
+
readonly appended: false;
|
|
10
|
+
readonly reason: string;
|
|
11
|
+
readonly path: string;
|
|
12
|
+
} | {
|
|
13
|
+
readonly appended: true;
|
|
14
|
+
readonly event: JournalEvent;
|
|
15
|
+
readonly path: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function appendDesignEvent({ stateRoot, type, payload, taskId, }: DesignEventInput): Promise<DesignEventResult>;
|
|
18
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/design/events.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAI7D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC5E;IAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErF,wBAAsB,iBAAiB,CAAC,EACtC,SAAS,EACT,IAAI,EACJ,OAAY,EACZ,MAAa,GACd,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAmC/C"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Design registry events on the orchestrator journal.
|
|
2
|
+
//
|
|
3
|
+
// The journal is the source of truth and is hash-chained. The registry appends
|
|
4
|
+
// its events through the same JournalWriter so a later boot replay sees them.
|
|
5
|
+
// A design event does not rewrite state.json; the next load replays the journal.
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { JournalWriter, readJournal } from "../orchestrator/journal.js";
|
|
8
|
+
const DESIGN_SESSION = "s-design-registry";
|
|
9
|
+
export async function appendDesignEvent({ stateRoot, type, payload = {}, taskId = null, }) {
|
|
10
|
+
const journalPath = join(stateRoot, "journal.ndjson");
|
|
11
|
+
const info = await readJournal(journalPath);
|
|
12
|
+
if (!info.exists) {
|
|
13
|
+
return { appended: false, reason: "no_journal", path: journalPath };
|
|
14
|
+
}
|
|
15
|
+
if (info.errors.length > 0) {
|
|
16
|
+
return { appended: false, reason: "journal_unreadable", path: journalPath };
|
|
17
|
+
}
|
|
18
|
+
const last = info.events.at(-1) ?? null;
|
|
19
|
+
const writer = new JournalWriter({
|
|
20
|
+
path: journalPath,
|
|
21
|
+
events: info.events,
|
|
22
|
+
prevHash: last?.hash ?? null,
|
|
23
|
+
lastSeq: last?.seq ?? 0,
|
|
24
|
+
});
|
|
25
|
+
const event = await writer.append({
|
|
26
|
+
type,
|
|
27
|
+
run_id: last?.run_id ?? null,
|
|
28
|
+
session_id: DESIGN_SESSION,
|
|
29
|
+
...payload,
|
|
30
|
+
});
|
|
31
|
+
if (taskId && type === "design_delta_rejected") {
|
|
32
|
+
const reason = payload["reason"];
|
|
33
|
+
await writer.append({
|
|
34
|
+
type: "escalation",
|
|
35
|
+
run_id: last?.run_id ?? null,
|
|
36
|
+
session_id: DESIGN_SESSION,
|
|
37
|
+
task_id: taskId,
|
|
38
|
+
reason: "design_delta_rejected",
|
|
39
|
+
message: typeof reason === "string" ? reason : "design delta rejected",
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return { appended: true, event, path: journalPath };
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/design/events.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,EAAE;AACF,+EAA+E;AAC/E,8EAA8E;AAC9E,iFAAiF;AAEjF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAGxE,MAAM,cAAc,GAAG,mBAAmB,CAAC;AAa3C,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,EACtC,SAAS,EACT,IAAI,EACJ,OAAO,GAAG,EAAE,EACZ,MAAM,GAAG,IAAI,GACI;IACjB,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;IACtD,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,WAAW,CAAC,CAAC;IAC5C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACjB,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IACtE,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,oBAAoB,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAC9E,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC;QAC/B,IAAI,EAAE,WAAW;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,QAAQ,EAAE,IAAI,EAAE,IAAI,IAAI,IAAI;QAC5B,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;KACxB,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;QAChC,IAAI;QACJ,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,IAAI;QAC5B,UAAU,EAAE,cAAc;QAC1B,GAAG,OAAO;KACX,CAAC,CAAC;IAEH,IAAI,MAAM,IAAI,IAAI,KAAK,uBAAuB,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QACjC,MAAM,MAAM,CAAC,MAAM,CAAC;YAClB,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,IAAI;YAC5B,UAAU,EAAE,cAAc;YAC1B,OAAO,EAAE,MAAM;YACf,MAAM,EAAE,uBAAuB;YAC/B,OAAO,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,uBAAuB;SACvE,CAAC,CAAC;IACL,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { DesignFingerprint } from "../types/design.js";
|
|
2
|
+
export interface DesignFingerprintResult {
|
|
3
|
+
readonly registry: DesignFingerprint | null;
|
|
4
|
+
readonly files: Record<string, string> | null;
|
|
5
|
+
readonly designRoot: string | null;
|
|
6
|
+
}
|
|
7
|
+
export declare function computeDesignFingerprint({ designRoot, }?: {
|
|
8
|
+
readonly designRoot?: string | null;
|
|
9
|
+
}): Promise<DesignFingerprintResult>;
|
|
10
|
+
//# sourceMappingURL=fingerprint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/design/fingerprint.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,iBAAiB,EAAgB,MAAM,oBAAoB,CAAC;AAY1E,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,wBAAsB,wBAAwB,CAAC,EAC7C,UAAiB,GAClB,GAAE;IAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA2CjF"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Design registry fingerprint for RESUME.md B4.
|
|
2
|
+
//
|
|
3
|
+
// index_sha256 binds the actual INDEX.md bytes and every surface file, so a
|
|
4
|
+
// body edit is drift even when the derived table would not change. The field
|
|
5
|
+
// name stays index_sha256 per the contract; the hash covers the indexed set.
|
|
6
|
+
import { createHash } from "node:crypto";
|
|
7
|
+
import { join, relative } from "node:path";
|
|
8
|
+
import { readBuffer, statSafe, toPosixPath } from "../orchestrator/fsx.js";
|
|
9
|
+
import { sha256Hex } from "../orchestrator/hash.js";
|
|
10
|
+
import { listSurfaceFiles, STATUS_ORDER } from "./schema.js";
|
|
11
|
+
import { parseFrontmatterDocument } from "./yaml.js";
|
|
12
|
+
function emptyStatusCounts() {
|
|
13
|
+
const counts = { active: 0, draft: 0, deprecated: 0, needs_review: 0 };
|
|
14
|
+
for (const status of STATUS_ORDER)
|
|
15
|
+
counts[status] = 0;
|
|
16
|
+
return counts;
|
|
17
|
+
}
|
|
18
|
+
function isDesignStatus(value) {
|
|
19
|
+
return typeof value === "string" && STATUS_ORDER.includes(value);
|
|
20
|
+
}
|
|
21
|
+
export async function computeDesignFingerprint({ designRoot = null, } = {}) {
|
|
22
|
+
if (!designRoot)
|
|
23
|
+
return { registry: null, files: null, designRoot: null };
|
|
24
|
+
const stat = await statSafe(designRoot);
|
|
25
|
+
if (!stat || !stat.isDirectory())
|
|
26
|
+
return { registry: null, files: null, designRoot };
|
|
27
|
+
const files = await listSurfaceFiles(designRoot);
|
|
28
|
+
const fileMap = {};
|
|
29
|
+
const statusCounts = emptyStatusCounts();
|
|
30
|
+
const hash = createHash("sha256");
|
|
31
|
+
const indexBytes = await readBuffer(join(designRoot, "INDEX.md"));
|
|
32
|
+
hash.update("index\0");
|
|
33
|
+
hash.update(indexBytes ?? Buffer.from("missing", "utf8"));
|
|
34
|
+
hash.update("\0");
|
|
35
|
+
for (const file of files) {
|
|
36
|
+
const relativePath = toPosixPath(relative(designRoot, file));
|
|
37
|
+
const bytes = await readBuffer(file);
|
|
38
|
+
if (bytes === null)
|
|
39
|
+
continue;
|
|
40
|
+
fileMap[relativePath] = `sha256:${sha256Hex(bytes)}`;
|
|
41
|
+
hash.update(relativePath);
|
|
42
|
+
hash.update("\0");
|
|
43
|
+
hash.update(bytes);
|
|
44
|
+
hash.update("\0");
|
|
45
|
+
try {
|
|
46
|
+
const parsed = parseFrontmatterDocument(bytes.toString("utf8"), { label: relativePath });
|
|
47
|
+
const status = parsed.data["status"];
|
|
48
|
+
if (isDesignStatus(status))
|
|
49
|
+
statusCounts[status] += 1;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// An unparsable surface still changes the file hash. Boot reports the
|
|
53
|
+
// drift; it does not guess the status.
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
registry: {
|
|
58
|
+
index_sha256: `sha256:${hash.digest("hex")}`,
|
|
59
|
+
surface_count: files.length,
|
|
60
|
+
status_counts: statusCounts,
|
|
61
|
+
},
|
|
62
|
+
files: fileMap,
|
|
63
|
+
designRoot,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=fingerprint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../src/design/fingerprint.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { DesignSurface, IndexResult } from "../types/design.js";
|
|
2
|
+
declare function byteSort(values: readonly string[]): string[];
|
|
3
|
+
export declare function countGaps(body: unknown): number;
|
|
4
|
+
export declare function deriveGeneratedAt(surfaces: readonly DesignSurface[], override?: string | null): string;
|
|
5
|
+
export interface GenerateIndexInput {
|
|
6
|
+
readonly designRoot: string;
|
|
7
|
+
readonly generatedAt?: string | null;
|
|
8
|
+
}
|
|
9
|
+
export declare function generateIndex({ designRoot, generatedAt }: GenerateIndexInput): Promise<IndexResult>;
|
|
10
|
+
export declare function indexFilePath(designRoot: string): string;
|
|
11
|
+
export interface WrittenIndex extends IndexResult {
|
|
12
|
+
readonly path: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function writeIndex({ designRoot, generatedAt }: GenerateIndexInput): Promise<WrittenIndex>;
|
|
15
|
+
export { byteSort };
|
|
16
|
+
//# sourceMappingURL=index-gen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-gen.d.ts","sourceRoot":"","sources":["../../src/design/index-gen.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAIrE,iBAAS,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAErD;AAOD,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAW/C;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,EAAE,QAAQ,GAAE,MAAM,GAAG,IAAW,GAAG,MAAM,CAe5G;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,wBAAsB,aAAa,CAAC,EAAE,UAAU,EAAE,WAAkB,EAAE,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAoChH;AAED,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,UAAU,CAAC,EAAE,UAAU,EAAE,WAAkB,EAAE,EAAE,kBAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAK9G;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|