mewkit 1.10.3 → 1.10.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/README.md +49 -4
  2. package/dist/commands/budget.d.ts +13 -0
  3. package/dist/commands/budget.d.ts.map +1 -1
  4. package/dist/commands/budget.js +45 -0
  5. package/dist/commands/budget.js.map +1 -1
  6. package/dist/commands/doctor-checks.d.ts +1 -1
  7. package/dist/commands/doctor-checks.d.ts.map +1 -1
  8. package/dist/commands/doctor-checks.js +7 -1
  9. package/dist/commands/doctor-checks.js.map +1 -1
  10. package/dist/commands/doctor-hard-gates.d.ts +3 -0
  11. package/dist/commands/doctor-hard-gates.d.ts.map +1 -0
  12. package/dist/commands/doctor-hard-gates.js +170 -0
  13. package/dist/commands/doctor-hard-gates.js.map +1 -0
  14. package/dist/commands/doctor.d.ts +1 -0
  15. package/dist/commands/doctor.d.ts.map +1 -1
  16. package/dist/commands/doctor.js +12 -3
  17. package/dist/commands/doctor.js.map +1 -1
  18. package/dist/commands/evolve.d.ts +11 -0
  19. package/dist/commands/evolve.d.ts.map +1 -0
  20. package/dist/commands/evolve.js +63 -0
  21. package/dist/commands/evolve.js.map +1 -0
  22. package/dist/commands/health.d.ts +14 -0
  23. package/dist/commands/health.d.ts.map +1 -0
  24. package/dist/commands/health.js +193 -0
  25. package/dist/commands/health.js.map +1 -0
  26. package/dist/commands/init.d.ts +6 -0
  27. package/dist/commands/init.d.ts.map +1 -1
  28. package/dist/commands/init.js +64 -3
  29. package/dist/commands/init.js.map +1 -1
  30. package/dist/commands/inventory.d.ts +13 -0
  31. package/dist/commands/inventory.d.ts.map +1 -0
  32. package/dist/commands/inventory.js +85 -0
  33. package/dist/commands/inventory.js.map +1 -0
  34. package/dist/commands/pack-helpers.d.ts +37 -0
  35. package/dist/commands/pack-helpers.d.ts.map +1 -0
  36. package/dist/commands/pack-helpers.js +105 -0
  37. package/dist/commands/pack-helpers.js.map +1 -0
  38. package/dist/commands/pack.d.ts +9 -0
  39. package/dist/commands/pack.d.ts.map +1 -0
  40. package/dist/commands/pack.js +160 -0
  41. package/dist/commands/pack.js.map +1 -0
  42. package/dist/commands/policy.d.ts +8 -0
  43. package/dist/commands/policy.d.ts.map +1 -0
  44. package/dist/commands/policy.js +65 -0
  45. package/dist/commands/policy.js.map +1 -0
  46. package/dist/commands/portability.d.ts +7 -0
  47. package/dist/commands/portability.d.ts.map +1 -0
  48. package/dist/commands/portability.js +50 -0
  49. package/dist/commands/portability.js.map +1 -0
  50. package/dist/commands/providers.d.ts +6 -0
  51. package/dist/commands/providers.d.ts.map +1 -0
  52. package/dist/commands/providers.js +94 -0
  53. package/dist/commands/providers.js.map +1 -0
  54. package/dist/commands/reflect.d.ts +14 -0
  55. package/dist/commands/reflect.d.ts.map +1 -0
  56. package/dist/commands/reflect.js +135 -0
  57. package/dist/commands/reflect.js.map +1 -0
  58. package/dist/commands/simulate.d.ts +14 -0
  59. package/dist/commands/simulate.d.ts.map +1 -0
  60. package/dist/commands/simulate.js +86 -0
  61. package/dist/commands/simulate.js.map +1 -0
  62. package/dist/commands/upgrade.d.ts.map +1 -1
  63. package/dist/commands/upgrade.js +22 -1
  64. package/dist/commands/upgrade.js.map +1 -1
  65. package/dist/commands/validate.d.ts +29 -0
  66. package/dist/commands/validate.d.ts.map +1 -1
  67. package/dist/commands/validate.js +242 -94
  68. package/dist/commands/validate.js.map +1 -1
  69. package/dist/core/build-inventory.d.ts +71 -0
  70. package/dist/core/build-inventory.d.ts.map +1 -0
  71. package/dist/core/build-inventory.js +222 -0
  72. package/dist/core/build-inventory.js.map +1 -0
  73. package/dist/core/check-packs.d.ts +13 -0
  74. package/dist/core/check-packs.d.ts.map +1 -0
  75. package/dist/core/check-packs.js +131 -0
  76. package/dist/core/check-packs.js.map +1 -0
  77. package/dist/core/check-stale-index.d.ts +35 -0
  78. package/dist/core/check-stale-index.d.ts.map +1 -0
  79. package/dist/core/check-stale-index.js +132 -0
  80. package/dist/core/check-stale-index.js.map +1 -0
  81. package/dist/core/check-workflow-drift.d.ts +49 -0
  82. package/dist/core/check-workflow-drift.d.ts.map +1 -0
  83. package/dist/core/check-workflow-drift.js +226 -0
  84. package/dist/core/check-workflow-drift.js.map +1 -0
  85. package/dist/core/context-budget.d.ts +9 -0
  86. package/dist/core/context-budget.d.ts.map +1 -0
  87. package/dist/core/context-budget.js +46 -0
  88. package/dist/core/context-budget.js.map +1 -0
  89. package/dist/core/event-log.d.ts +44 -0
  90. package/dist/core/event-log.d.ts.map +1 -0
  91. package/dist/core/event-log.js +169 -0
  92. package/dist/core/event-log.js.map +1 -0
  93. package/dist/core/evolution/event-clusters.d.ts +4 -0
  94. package/dist/core/evolution/event-clusters.d.ts.map +1 -0
  95. package/dist/core/evolution/event-clusters.js +82 -0
  96. package/dist/core/evolution/event-clusters.js.map +1 -0
  97. package/dist/core/evolution/recommendation-renderer.d.ts +3 -0
  98. package/dist/core/evolution/recommendation-renderer.d.ts.map +1 -0
  99. package/dist/core/evolution/recommendation-renderer.js +24 -0
  100. package/dist/core/evolution/recommendation-renderer.js.map +1 -0
  101. package/dist/core/evolution/review-failure-clusters.d.ts +10 -0
  102. package/dist/core/evolution/review-failure-clusters.d.ts.map +1 -0
  103. package/dist/core/evolution/review-failure-clusters.js +30 -0
  104. package/dist/core/evolution/review-failure-clusters.js.map +1 -0
  105. package/dist/core/evolution/suggestions.d.ts +24 -0
  106. package/dist/core/evolution/suggestions.d.ts.map +1 -0
  107. package/dist/core/evolution/suggestions.js +11 -0
  108. package/dist/core/evolution/suggestions.js.map +1 -0
  109. package/dist/core/gate-policy.d.ts +20 -0
  110. package/dist/core/gate-policy.d.ts.map +1 -0
  111. package/dist/core/gate-policy.js +64 -0
  112. package/dist/core/gate-policy.js.map +1 -0
  113. package/dist/core/harness-scaffold.d.ts +29 -0
  114. package/dist/core/harness-scaffold.d.ts.map +1 -0
  115. package/dist/core/harness-scaffold.js +53 -0
  116. package/dist/core/harness-scaffold.js.map +1 -0
  117. package/dist/core/hook-runner.d.ts +69 -0
  118. package/dist/core/hook-runner.d.ts.map +1 -0
  119. package/dist/core/hook-runner.js +95 -0
  120. package/dist/core/hook-runner.js.map +1 -0
  121. package/dist/core/index.d.ts +2 -0
  122. package/dist/core/index.d.ts.map +1 -1
  123. package/dist/core/index.js +2 -0
  124. package/dist/core/index.js.map +1 -1
  125. package/dist/core/install-metadata.d.ts +15 -0
  126. package/dist/core/install-metadata.d.ts.map +1 -1
  127. package/dist/core/install-metadata.js +11 -0
  128. package/dist/core/install-metadata.js.map +1 -1
  129. package/dist/core/is-hook-script.d.ts +2 -0
  130. package/dist/core/is-hook-script.d.ts.map +1 -0
  131. package/dist/core/is-hook-script.js +45 -0
  132. package/dist/core/is-hook-script.js.map +1 -0
  133. package/dist/core/pack-manifest.d.ts +48 -0
  134. package/dist/core/pack-manifest.d.ts.map +1 -0
  135. package/dist/core/pack-manifest.js +126 -0
  136. package/dist/core/pack-manifest.js.map +1 -0
  137. package/dist/core/pack-resolver.d.ts +18 -0
  138. package/dist/core/pack-resolver.d.ts.map +1 -0
  139. package/dist/core/pack-resolver.js +144 -0
  140. package/dist/core/pack-resolver.js.map +1 -0
  141. package/dist/core/portability-matrix.d.ts +17 -0
  142. package/dist/core/portability-matrix.d.ts.map +1 -0
  143. package/dist/core/portability-matrix.js +31 -0
  144. package/dist/core/portability-matrix.js.map +1 -0
  145. package/dist/core/simulation-runner.d.ts +93 -0
  146. package/dist/core/simulation-runner.d.ts.map +1 -0
  147. package/dist/core/simulation-runner.js +161 -0
  148. package/dist/core/simulation-runner.js.map +1 -0
  149. package/dist/core/smart-update.d.ts +24 -0
  150. package/dist/core/smart-update.d.ts.map +1 -1
  151. package/dist/core/smart-update.js +69 -0
  152. package/dist/core/smart-update.js.map +1 -1
  153. package/dist/core/usage/usage-analyzer.d.ts +18 -0
  154. package/dist/core/usage/usage-analyzer.d.ts.map +1 -0
  155. package/dist/core/usage/usage-analyzer.js +41 -0
  156. package/dist/core/usage/usage-analyzer.js.map +1 -0
  157. package/dist/core/validate-install.d.ts.map +1 -1
  158. package/dist/core/validate-install.js +3 -1
  159. package/dist/core/validate-install.js.map +1 -1
  160. package/dist/index.js +91 -4
  161. package/dist/index.js.map +1 -1
  162. package/dist/memory/archive.d.ts +9 -0
  163. package/dist/memory/archive.d.ts.map +1 -0
  164. package/dist/memory/archive.js +42 -0
  165. package/dist/memory/archive.js.map +1 -0
  166. package/dist/memory/compact.d.ts +9 -0
  167. package/dist/memory/compact.d.ts.map +1 -0
  168. package/dist/memory/compact.js +33 -0
  169. package/dist/memory/compact.js.map +1 -0
  170. package/dist/memory/conflicts.d.ts +8 -0
  171. package/dist/memory/conflicts.d.ts.map +1 -0
  172. package/dist/memory/conflicts.js +28 -0
  173. package/dist/memory/conflicts.js.map +1 -0
  174. package/dist/memory/promote.d.ts +8 -0
  175. package/dist/memory/promote.d.ts.map +1 -0
  176. package/dist/memory/promote.js +10 -0
  177. package/dist/memory/promote.js.map +1 -0
  178. package/dist/memory/store-utils.d.ts +14 -0
  179. package/dist/memory/store-utils.d.ts.map +1 -0
  180. package/dist/memory/store-utils.js +44 -0
  181. package/dist/memory/store-utils.js.map +1 -0
  182. package/dist/migrate/converters/md-to-codex-rules.d.ts.map +1 -1
  183. package/dist/migrate/converters/md-to-codex-rules.js +30 -0
  184. package/dist/migrate/converters/md-to-codex-rules.js.map +1 -1
  185. package/dist/migrate/portability-policy.d.ts.map +1 -1
  186. package/dist/migrate/portability-policy.js +44 -23
  187. package/dist/migrate/portability-policy.js.map +1 -1
  188. package/dist/migrate/provider-support-summary.d.ts +49 -0
  189. package/dist/migrate/provider-support-summary.d.ts.map +1 -0
  190. package/dist/migrate/provider-support-summary.js +98 -0
  191. package/dist/migrate/provider-support-summary.js.map +1 -0
  192. package/dist/migrate/types.d.ts +2 -2
  193. package/package.json +1 -1
@@ -0,0 +1,222 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import yaml from "js-yaml";
4
+ /** Runtime/tooling dirs that are never harness artifacts. */
5
+ const DENYLIST_DIRS = new Set([".venv", "__pycache__", "node_modules"]);
6
+ const REQUIRED_FIELDS = ["owner", "criticality", "status", "runtime"];
7
+ function listMarkdown(dir) {
8
+ if (!fs.existsSync(dir))
9
+ return [];
10
+ return fs.readdirSync(dir).filter((f) => f.endsWith(".md"));
11
+ }
12
+ /**
13
+ * The canonical "what counts" enumeration. Returns artifact references plus any
14
+ * structural anomalies (e.g. a skill subdir with no SKILL.md that is not a known
15
+ * runtime dir). Counting is presence-based; rules and rules-conditional are
16
+ * deliberately NOT merged — callers label them as separate buckets.
17
+ */
18
+ export function enumerateArtifacts(claudeDir) {
19
+ const refs = [];
20
+ const issues = [];
21
+ // skills — subdirs containing SKILL.md
22
+ const skillsDir = path.join(claudeDir, "skills");
23
+ if (fs.existsSync(skillsDir)) {
24
+ for (const entry of fs.readdirSync(skillsDir)) {
25
+ if (DENYLIST_DIRS.has(entry))
26
+ continue;
27
+ const subdir = path.join(skillsDir, entry);
28
+ if (!fs.statSync(subdir).isDirectory())
29
+ continue;
30
+ const skillMd = path.join(subdir, "SKILL.md");
31
+ if (fs.existsSync(skillMd)) {
32
+ const fm = readFrontmatter(skillMd);
33
+ const id = typeof fm.name === "string" ? fm.name : entry;
34
+ refs.push({ type: "skill", rel: `skills/${entry}/SKILL.md`, abs: skillMd, id, metaSource: "frontmatter" });
35
+ }
36
+ else {
37
+ issues.push({ path: `skills/${entry}`, type: "unknown", problem: "skill directory has no SKILL.md (not a known runtime dir)" });
38
+ }
39
+ }
40
+ }
41
+ // agents — *.md excluding *_INDEX.md
42
+ const agentsDir = path.join(claudeDir, "agents");
43
+ for (const f of listMarkdown(agentsDir)) {
44
+ if (f.endsWith("_INDEX.md"))
45
+ continue;
46
+ refs.push({ type: "agent", rel: `agents/${f}`, abs: path.join(agentsDir, f), id: f.replace(/\.md$/, ""), metaSource: "frontmatter" });
47
+ }
48
+ // rules + rules-conditional — separate buckets, registry-sourced
49
+ for (const f of listMarkdown(path.join(claudeDir, "rules"))) {
50
+ refs.push({ type: "rule", rel: `rules/${f}`, abs: path.join(claudeDir, "rules", f), id: f.replace(/\.md$/, ""), metaSource: "registry" });
51
+ }
52
+ for (const f of listMarkdown(path.join(claudeDir, "rules-conditional"))) {
53
+ refs.push({ type: "rule", rel: `rules-conditional/${f}`, abs: path.join(claudeDir, "rules-conditional", f), id: f.replace(/\.md$/, ""), metaSource: "registry" });
54
+ }
55
+ // commands — commands/mk/*.md, registry-sourced
56
+ const cmdDir = path.join(claudeDir, "commands", "mk");
57
+ for (const f of listMarkdown(cmdDir)) {
58
+ refs.push({ type: "command", rel: `commands/mk/${f}`, abs: path.join(cmdDir, f), id: f.replace(/\.md$/, ""), metaSource: "registry" });
59
+ }
60
+ // hooks — isHookScript-true files, registry-sourced
61
+ const hooksDir = path.join(claudeDir, "hooks");
62
+ if (fs.existsSync(hooksDir)) {
63
+ for (const f of fs.readdirSync(hooksDir)) {
64
+ const abs = path.join(hooksDir, f);
65
+ if (!fs.statSync(abs).isFile())
66
+ continue;
67
+ if (!f.endsWith(".sh"))
68
+ continue; // top-level shell hooks are the counted set
69
+ refs.push({ type: "hook", rel: `hooks/${f}`, abs, id: f.replace(/\.sh$/, ""), metaSource: "registry" });
70
+ }
71
+ }
72
+ return { refs, issues };
73
+ }
74
+ /** Extract the YAML frontmatter block of a markdown file, or {} if none. */
75
+ function readFrontmatter(abs) {
76
+ try {
77
+ const body = fs.readFileSync(abs, "utf-8");
78
+ const m = /^---\n([\s\S]*?)\n---/.exec(body);
79
+ if (!m)
80
+ return {};
81
+ const parsed = yaml.load(m[1]);
82
+ return parsed && typeof parsed === "object" ? parsed : {};
83
+ }
84
+ catch {
85
+ return {};
86
+ }
87
+ }
88
+ /** Read the central registry for rules/commands/hooks. */
89
+ export function readRegistry(claudeDir) {
90
+ const regPath = path.join(claudeDir, "harness-inventory.json");
91
+ if (!fs.existsSync(regPath))
92
+ return {};
93
+ try {
94
+ const parsed = JSON.parse(fs.readFileSync(regPath, "utf-8"));
95
+ return parsed.artifacts ?? {};
96
+ }
97
+ catch {
98
+ return {};
99
+ }
100
+ }
101
+ function str(v) {
102
+ return typeof v === "string" ? v : "";
103
+ }
104
+ /**
105
+ * Build the unified inventory. Each artifact's metadata comes from frontmatter
106
+ * (skills/agents) or the registry (rules/commands/hooks). Missing records and
107
+ * missing required fields are recorded as issues — never silently defaulted to
108
+ * a passing value.
109
+ */
110
+ export function buildInventory(claudeDir) {
111
+ const { refs, issues } = enumerateArtifacts(claudeDir);
112
+ const registry = readRegistry(claudeDir);
113
+ const entries = [];
114
+ const allIssues = [...issues];
115
+ for (const ref of refs) {
116
+ const meta = ref.metaSource === "frontmatter" ? readFrontmatter(ref.abs) : registry[ref.rel] ?? {};
117
+ const hasRecord = ref.metaSource === "frontmatter" ? Object.keys(meta).length > 0 : ref.rel in registry;
118
+ if (!hasRecord) {
119
+ allIssues.push({ path: ref.rel, type: ref.type, problem: `no governance metadata (${ref.metaSource})` });
120
+ }
121
+ const entry = {
122
+ type: ref.type,
123
+ path: ref.rel,
124
+ id: ref.id,
125
+ owner: str(meta.owner),
126
+ criticality: str(meta.criticality),
127
+ status: str(meta.status),
128
+ runtime: str(meta.runtime),
129
+ source: ref.metaSource,
130
+ };
131
+ if (typeof meta.context_cost === "string")
132
+ entry.contextCost = meta.context_cost;
133
+ if (Array.isArray(meta.depends_on))
134
+ entry.dependsOn = meta.depends_on.map(String);
135
+ entries.push(entry);
136
+ }
137
+ // Registry keys that point at no enumerated artifact (stale registry entry).
138
+ const enumerated = new Set(refs.map((r) => r.rel));
139
+ for (const key of Object.keys(registry)) {
140
+ if (!enumerated.has(key)) {
141
+ allIssues.push({ path: key, type: "unknown", problem: "registry entry has no matching artifact on disk" });
142
+ }
143
+ }
144
+ return { entries, issues: allIssues };
145
+ }
146
+ /** Load the allowed-enum sets from the governance schema (single source). */
147
+ export function loadSchemaEnums(claudeDir) {
148
+ const schemaPath = path.join(claudeDir, "schemas", "harness-metadata-schema.json");
149
+ if (!fs.existsSync(schemaPath))
150
+ return null;
151
+ try {
152
+ const schema = JSON.parse(fs.readFileSync(schemaPath, "utf-8"));
153
+ const props = schema.properties ?? {};
154
+ return {
155
+ owner: new Set(props.owner?.enum ?? []),
156
+ criticality: new Set(props.criticality?.enum ?? []),
157
+ status: new Set(props.status?.enum ?? []),
158
+ runtime: new Set(props.runtime?.enum ?? []),
159
+ };
160
+ }
161
+ catch {
162
+ return null;
163
+ }
164
+ }
165
+ /**
166
+ * Ownership-completeness validation. FAILS when any artifact lacks a metadata
167
+ * record, is missing a required field, or carries an out-of-enum value, or when
168
+ * a structural anomaly exists (unknown dir, stale registry entry). PASSES only
169
+ * when every discovered artifact is 100% covered with valid values.
170
+ */
171
+ export function checkOwnership(claudeDir, opts = {}) {
172
+ // The governance schema is the install signal: absent ⇒ the metadata layer
173
+ // is not installed. In a non-scoped run that downgrades to WARN (prompt the
174
+ // upgrade); the scoped `--ownership` CI check keeps it a hard FAIL.
175
+ const schemaPath = path.join(claudeDir, "schemas", "harness-metadata-schema.json");
176
+ if (!fs.existsSync(schemaPath)) {
177
+ const status = opts.missingInfraSeverity ?? "fail";
178
+ const detail = status === "warn"
179
+ ? "Ownership metadata not installed (no harness-metadata-schema.json) — run `mewkit upgrade`"
180
+ : "Missing/unreadable .claude/schemas/harness-metadata-schema.json";
181
+ return [{ name: "Governance metadata installed", status, detail, section: "Ownership" }];
182
+ }
183
+ const enums = loadSchemaEnums(claudeDir);
184
+ if (!enums) {
185
+ return [{ name: "Governance schema loads", status: "fail", detail: "Unreadable .claude/schemas/harness-metadata-schema.json", section: "Ownership" }];
186
+ }
187
+ const { entries, issues } = buildInventory(claudeDir);
188
+ const results = [];
189
+ for (const issue of issues) {
190
+ results.push({ name: `Ownership: ${issue.path}`, status: "fail", detail: `${issue.type}: ${issue.problem}`, section: "Ownership" });
191
+ }
192
+ const enumOf = {
193
+ owner: enums.owner,
194
+ criticality: enums.criticality,
195
+ status: enums.status,
196
+ runtime: enums.runtime,
197
+ };
198
+ for (const e of entries) {
199
+ const problems = [];
200
+ for (const field of REQUIRED_FIELDS) {
201
+ const value = e[field];
202
+ if (!value) {
203
+ problems.push(`missing ${field}`);
204
+ }
205
+ else if (!enumOf[field].has(value)) {
206
+ problems.push(`${field}="${value}" not in enum`);
207
+ }
208
+ }
209
+ if (problems.length > 0) {
210
+ results.push({ name: `Ownership: ${e.path}`, status: "fail", detail: problems.join("; "), section: "Ownership" });
211
+ }
212
+ }
213
+ const failed = results.filter((r) => r.status === "fail").length;
214
+ results.push({
215
+ name: "Ownership coverage",
216
+ status: failed === 0 ? "pass" : "fail",
217
+ detail: failed === 0 ? `${entries.length} artifacts, 100% governance coverage` : `${failed} artifact(s) with missing/invalid metadata`,
218
+ section: "Ownership",
219
+ });
220
+ return results;
221
+ }
222
+ //# sourceMappingURL=build-inventory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-inventory.js","sourceRoot":"","sources":["../../src/core/build-inventory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { CheckResult } from "../commands/validate.js";
2
+ import type { Status } from "../commands/doctor-checks.js";
3
+ /**
4
+ * Safety surface that MUST resolve into `base` for every profile — the Phase-1
5
+ * gate + privacy hooks, the dispatch chain, settings, statusline, and the always-on
6
+ * rules. Paths are exact (note `hooks/lib/...`); a missing one makes a profile
7
+ * shippable without enforcement, so each absence is a hard FAIL.
8
+ */
9
+ export declare const SAFETY_PATHS: string[];
10
+ export declare function checkPacks(claudeDir: string, opts?: {
11
+ missingInfraSeverity?: Status;
12
+ }): CheckResult[];
13
+ //# sourceMappingURL=check-packs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-packs.d.ts","sourceRoot":"","sources":["../../src/core/check-packs.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,YAAY,UAqBxB,CAAC;AAKF,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,WAAW,EAAE,CA4GzG"}
@@ -0,0 +1,131 @@
1
+ // Static `validate --packs` coherence + safety check. Proves the pack manifest is
2
+ // internally consistent (resolvable profiles, real override ids, resolvable
3
+ // depends_on), that every governed artifact belongs to ≥1 pack or base, and — the
4
+ // non-negotiable safety invariant — that base carries the full gate/privacy/dispatch
5
+ // chain at its exact verified paths. Mirrors checkOwnership's quad-state pattern.
6
+ import { buildInventory } from "./build-inventory.js";
7
+ import { availablePacks, availableProfiles, BASE_PACK, flattenProfile, hasPackManifest, loadPackManifest, } from "./pack-manifest.js";
8
+ import { resolvePacksDetailed } from "./pack-resolver.js";
9
+ /**
10
+ * Safety surface that MUST resolve into `base` for every profile — the Phase-1
11
+ * gate + privacy hooks, the dispatch chain, settings, statusline, and the always-on
12
+ * rules. Paths are exact (note `hooks/lib/...`); a missing one makes a profile
13
+ * shippable without enforcement, so each absence is a hard FAIL.
14
+ */
15
+ export const SAFETY_PATHS = [
16
+ "statusline.cjs",
17
+ "settings.json",
18
+ "hooks/gate-enforcement.sh",
19
+ "hooks/privacy-block.sh",
20
+ "hooks/pre-completion-check.sh",
21
+ "hooks/lib/read-hook-input.sh",
22
+ "hooks/lib/load-dotenv.sh",
23
+ "hooks/dispatch.cjs",
24
+ "hooks/lib/parse-stdin.cjs",
25
+ "hooks/lib/shared-state.cjs",
26
+ "hooks/handlers.json",
27
+ "rules/security-rules.md",
28
+ "rules/injection-rules.md",
29
+ "rules/gate-rules.md",
30
+ "rules/core-behaviors.md",
31
+ "rules/development-rules.md",
32
+ // essential cross-profile commands — a profile without these has no /mk:plan etc.
33
+ "commands/mk/plan.md",
34
+ "commands/mk/upgrade.md",
35
+ "commands/mk/validate.md",
36
+ ];
37
+ const PASS = (name, detail) => ({ name, status: "pass", detail, section: "Packs" });
38
+ const FAIL = (name, detail) => ({ name, status: "fail", detail, section: "Packs" });
39
+ export function checkPacks(claudeDir, opts = {}) {
40
+ // Manifest absent ⇒ pack modularization not installed. Default run downgrades to
41
+ // WARN (prompt upgrade); scoped `--packs` keeps it a hard FAIL for CI.
42
+ if (!hasPackManifest(claudeDir)) {
43
+ const status = opts.missingInfraSeverity ?? "fail";
44
+ return [
45
+ {
46
+ name: "Pack manifest installed",
47
+ status,
48
+ detail: status === "warn"
49
+ ? "No pack-manifest.json — pack modularization not installed; run `mewkit upgrade`"
50
+ : "Missing .claude/pack-manifest.json",
51
+ section: "Packs",
52
+ },
53
+ ];
54
+ }
55
+ let manifest;
56
+ try {
57
+ manifest = loadPackManifest(claudeDir);
58
+ }
59
+ catch (err) {
60
+ return [FAIL("Pack manifest loads", err.message)];
61
+ }
62
+ const results = [];
63
+ // 1. Every profile flattens without an unknown ref or cycle.
64
+ for (const profile of availableProfiles(manifest)) {
65
+ try {
66
+ flattenProfile(manifest, profile);
67
+ }
68
+ catch (err) {
69
+ results.push(FAIL(`Profile resolves: ${profile}`, err.message));
70
+ }
71
+ }
72
+ const inv = buildInventory(claudeDir);
73
+ const invIds = new Set(inv.entries.map((e) => e.id));
74
+ // 2. Every artifactsAdd/Exclude id is a real artifact (catches phantom ids).
75
+ for (const [packName, def] of Object.entries(manifest.packs)) {
76
+ for (const id of [...(def.artifactsAdd ?? []), ...(def.artifactsExclude ?? [])]) {
77
+ if (!invIds.has(id)) {
78
+ results.push(FAIL(`Pack override id: ${packName}`, `references unknown artifact id "${id}"`));
79
+ }
80
+ }
81
+ }
82
+ // 3. Completeness: every governed artifact belongs to ≥1 pack OR base.
83
+ const coveredOwners = new Set();
84
+ const coveredAddIds = new Set();
85
+ for (const def of Object.values(manifest.packs)) {
86
+ for (const o of def.owners ?? [])
87
+ coveredOwners.add(o);
88
+ for (const id of def.artifactsAdd ?? [])
89
+ coveredAddIds.add(id);
90
+ }
91
+ let baseSet;
92
+ try {
93
+ baseSet = resolvePacksDetailed(claudeDir, manifest, []).packMembership.get(BASE_PACK) ?? new Set();
94
+ }
95
+ catch (err) {
96
+ return [...results, FAIL("Base resolves", err.message)];
97
+ }
98
+ const strays = inv.entries.filter((e) => !coveredOwners.has(e.owner) && !coveredAddIds.has(e.id) && !baseSet.has(e.path));
99
+ if (strays.length > 0) {
100
+ results.push(FAIL("Pack completeness", `${strays.length} artifact(s) in no pack/base: ${strays.slice(0, 8).map((e) => `${e.id}(${e.owner || "no-owner"})`).join(", ")}`));
101
+ }
102
+ // 4. Safety invariant: base carries every gate/privacy/dispatch path.
103
+ const missingSafety = SAFETY_PATHS.filter((p) => !baseSet.has(p));
104
+ if (missingSafety.length > 0) {
105
+ results.push(FAIL("Base safety invariant", `base missing required safety file(s): ${missingSafety.join(", ")}`));
106
+ }
107
+ // 5. depends_on resolvability + the empty-edges advisory.
108
+ let anyEdges = false;
109
+ for (const e of inv.entries) {
110
+ for (const dep of e.dependsOn ?? []) {
111
+ anyEdges = true;
112
+ if (!invIds.has(dep)) {
113
+ results.push(FAIL(`depends_on: ${e.id}`, `unresolvable dependency "${dep}"`));
114
+ }
115
+ }
116
+ }
117
+ if (!anyEdges && inv.entries.length > 0) {
118
+ results.push({
119
+ name: "depends_on edges",
120
+ status: "warn",
121
+ detail: `inventory has ${inv.entries.length} artifacts but no depends_on edges — closure is inert (future-proofing only)`,
122
+ section: "Packs",
123
+ });
124
+ }
125
+ const failed = results.filter((r) => r.status === "fail").length;
126
+ results.push(failed === 0
127
+ ? PASS("Pack coherence", `${availableProfiles(manifest).length} profiles, ${availablePacks(manifest).length} packs, ${inv.entries.length} artifacts — 100% covered`)
128
+ : FAIL("Pack coherence", `${failed} pack defect(s)`));
129
+ return results;
130
+ }
131
+ //# sourceMappingURL=check-packs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-packs.js","sourceRoot":"","sources":["../../src/core/check-packs.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,4EAA4E;AAC5E,kFAAkF;AAClF,qFAAqF;AACrF,kFAAkF;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EACN,cAAc,EACd,iBAAiB,EACjB,SAAS,EACT,cAAc,EACd,eAAe,EACf,gBAAgB,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAI1D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC3B,gBAAgB;IAChB,eAAe;IACf,2BAA2B;IAC3B,wBAAwB;IACxB,+BAA+B;IAC/B,8BAA8B;IAC9B,0BAA0B;IAC1B,oBAAoB;IACpB,2BAA2B;IAC3B,4BAA4B;IAC5B,qBAAqB;IACrB,yBAAyB;IACzB,0BAA0B;IAC1B,qBAAqB;IACrB,yBAAyB;IACzB,4BAA4B;IAC5B,kFAAkF;IAClF,qBAAqB;IACrB,wBAAwB;IACxB,yBAAyB;CACzB,CAAC;AAEF,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,MAAc,EAAe,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;AACjH,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,MAAc,EAAe,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;AAEjH,MAAM,UAAU,UAAU,CAAC,SAAiB,EAAE,OAA0C,EAAE;IACzF,iFAAiF;IACjF,uEAAuE;IACvE,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,CAAC;QACjC,MAAM,MAAM,GAAW,IAAI,CAAC,oBAAoB,IAAI,MAAM,CAAC;QAC3D,OAAO;YACN;gBACC,IAAI,EAAE,yBAAyB;gBAC/B,MAAM;gBACN,MAAM,EACL,MAAM,KAAK,MAAM;oBAChB,CAAC,CAAC,iFAAiF;oBACnF,CAAC,CAAC,oCAAoC;gBACxC,OAAO,EAAE,OAAO;aAChB;SACD,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC;IACb,IAAI,CAAC;QACJ,QAAQ,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,6DAA6D;IAC7D,KAAK,MAAM,OAAO,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnD,IAAI,CAAC;YACJ,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,qBAAqB,OAAO,EAAE,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC,CAAC;QAC5E,CAAC;IACF,CAAC;IAED,MAAM,GAAG,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAErD,6EAA6E;IAC7E,KAAK,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9D,KAAK,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;YACjF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACrB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,qBAAqB,QAAQ,EAAE,EAAE,mCAAmC,EAAE,GAAG,CAAC,CAAC,CAAC;YAC/F,CAAC;QACF,CAAC;IACF,CAAC;IAED,uEAAuE;IACvE,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;IACxC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;IACxC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE;YAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACvD,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,YAAY,IAAI,EAAE;YAAE,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,OAAoB,CAAC;IACzB,IAAI,CAAC;QACJ,OAAO,GAAG,oBAAoB,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;IACpG,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,OAAO,EAAE,IAAI,CAAC,eAAe,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC,CAAC;IACpE,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAChC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CACtF,CAAC;IACF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,IAAI,CACX,IAAI,CACH,mBAAmB,EACnB,GAAG,MAAM,CAAC,MAAM,iCAAiC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAChI,CACD,CAAC;IACH,CAAC;IAED,sEAAsE;IACtE,MAAM,aAAa,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAClE,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE,yCAAyC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAClH,CAAC;IAED,0DAA0D;IAC1D,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QAC7B,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;YACrC,QAAQ,GAAG,IAAI,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,EAAE,EAAE,4BAA4B,GAAG,GAAG,CAAC,CAAC,CAAC;YAC/E,CAAC;QACF,CAAC;IACF,CAAC;IACD,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzC,OAAO,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,kBAAkB;YACxB,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,iBAAiB,GAAG,CAAC,OAAO,CAAC,MAAM,8EAA8E;YACzH,OAAO,EAAE,OAAO;SAChB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IACjE,OAAO,CAAC,IAAI,CACX,MAAM,KAAK,CAAC;QACX,CAAC,CAAC,IAAI,CACJ,gBAAgB,EAChB,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC,MAAM,cAAc,cAAc,CAAC,QAAQ,CAAC,CAAC,MAAM,WAAW,GAAG,CAAC,OAAO,CAAC,MAAM,2BAA2B,CAC1I;QACF,CAAC,CAAC,IAAI,CAAC,gBAAgB,EAAE,GAAG,MAAM,iBAAiB,CAAC,CACrD,CAAC;IACF,OAAO,OAAO,CAAC;AAChB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { CheckResult } from "../commands/validate.js";
2
+ /** A single declared-vs-actual count claim found in a doc. */
3
+ export interface CountDiff {
4
+ source: string;
5
+ label: string;
6
+ declared: number;
7
+ actual: number;
8
+ }
9
+ /** A canonical count token: its file, a human label, the regex, and the truth. */
10
+ interface CountSpec {
11
+ source: string;
12
+ label: string;
13
+ pattern: RegExp;
14
+ actual: number;
15
+ }
16
+ /** Build the list of count specifications anchored to each doc's real format. */
17
+ export declare function countSpecs(repoRoot: string): CountSpec[];
18
+ /** Parse declared counts and diff them against the inventory. */
19
+ export declare function compareCounts(repoRoot: string): CountDiff[];
20
+ /** Completeness: every artifact id must appear in its index file. */
21
+ export declare function missingRows(repoRoot: string): {
22
+ source: string;
23
+ type: string;
24
+ missingIds: string[];
25
+ }[];
26
+ /** Full stale-index check → CheckResults under the "Inventory" section. */
27
+ export declare function checkStaleIndex(repoRoot: string): CheckResult[];
28
+ /**
29
+ * Rewrite ONLY the count number tokens in README + index headers to match the
30
+ * inventory. Curated index prose/rows are never touched. Returns the files it
31
+ * changed. Missing completeness rows are reported by the check, never auto-filled.
32
+ */
33
+ export declare function emitCounts(repoRoot: string): string[];
34
+ export {};
35
+ //# sourceMappingURL=check-stale-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-stale-index.d.ts","sourceRoot":"","sources":["../../src/core/check-stale-index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AA+B3D,8DAA8D;AAC9D,MAAM,WAAW,SAAS;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CACf;AAED,kFAAkF;AAClF,UAAU,SAAS;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CACf;AAOD,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,CAaxD;AAED,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,CAkB3D;AAED,qEAAqE;AACrE,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,CAkBtG;AAED,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE,CA4B/D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAuBrD"}
@@ -0,0 +1,132 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { buildInventory } from "./build-inventory.js";
4
+ function actualCounts(claudeDir) {
5
+ const { entries } = buildInventory(claudeDir);
6
+ const byType = (t) => entries.filter((e) => e.type === t);
7
+ const rules = byType("rule");
8
+ return {
9
+ skills: byType("skill"),
10
+ agents: byType("agent"),
11
+ commands: byType("command"),
12
+ rules: rules.filter((e) => e.path.startsWith("rules/")),
13
+ rulesConditional: rules.filter((e) => e.path.startsWith("rules-conditional/")),
14
+ hooks: byType("hook"),
15
+ };
16
+ }
17
+ function read(repoRoot, rel) {
18
+ const p = path.join(repoRoot, rel);
19
+ return fs.existsSync(p) ? fs.readFileSync(p, "utf-8") : "";
20
+ }
21
+ /** Build the list of count specifications anchored to each doc's real format. */
22
+ export function countSpecs(repoRoot) {
23
+ const claudeDir = path.join(repoRoot, ".claude");
24
+ const a = actualCounts(claudeDir);
25
+ return [
26
+ { source: "README.md", label: "skills", pattern: /(\d+)\s+skills/g, actual: a.skills.length },
27
+ { source: "README.md", label: "agents", pattern: /(\d+)\s+(?:specialist\s+)?agents/g, actual: a.agents.length },
28
+ { source: "README.md", label: "commands", pattern: /(\d+)\s+(?:slash\s+)?commands/g, actual: a.commands.length },
29
+ { source: "README.md", label: "rules", pattern: /(\d+)\s+(?:enforcement\s+)?rules/g, actual: a.rules.length },
30
+ { source: "README.md", label: "hook scripts", pattern: /(\d+)\s+hook scripts/g, actual: a.hooks.length },
31
+ { source: ".claude/agents/SKILLS_INDEX.md", label: "skills total", pattern: /\*\*Total\*\*\|\*\*(\d+)\*\*/g, actual: a.skills.length },
32
+ { source: ".claude/agents/AGENTS_INDEX.md", label: "agents index header", pattern: /\[(\d+)\]\{agent_file/g, actual: a.agents.length },
33
+ { source: ".claude/hooks/HOOKS_INDEX.md", label: "shell hooks", pattern: /(\d+)\s+shell hook/g, actual: a.hooks.length },
34
+ ];
35
+ }
36
+ /** Parse declared counts and diff them against the inventory. */
37
+ export function compareCounts(repoRoot) {
38
+ const diffs = [];
39
+ for (const spec of countSpecs(repoRoot)) {
40
+ const body = read(repoRoot, spec.source);
41
+ const matches = [...body.matchAll(spec.pattern)];
42
+ if (matches.length === 0) {
43
+ // A count token that cannot be found is itself a failure — never pass-on-no-match.
44
+ diffs.push({ source: spec.source, label: `${spec.label} (token not found)`, declared: -1, actual: spec.actual });
45
+ continue;
46
+ }
47
+ for (const m of matches) {
48
+ const declared = Number(m[1]);
49
+ if (declared !== spec.actual) {
50
+ diffs.push({ source: spec.source, label: spec.label, declared, actual: spec.actual });
51
+ }
52
+ }
53
+ }
54
+ return diffs;
55
+ }
56
+ /** Completeness: every artifact id must appear in its index file. */
57
+ export function missingRows(repoRoot) {
58
+ const claudeDir = path.join(repoRoot, ".claude");
59
+ const a = actualCounts(claudeDir);
60
+ const out = [];
61
+ const skillsIndex = read(repoRoot, ".claude/agents/SKILLS_INDEX.md");
62
+ const missSkills = a.skills.filter((e) => !skillsIndex.includes(e.id)).map((e) => e.id);
63
+ if (missSkills.length > 0)
64
+ out.push({ source: ".claude/agents/SKILLS_INDEX.md", type: "skill", missingIds: missSkills });
65
+ const agentsIndex = read(repoRoot, ".claude/agents/AGENTS_INDEX.md");
66
+ const missAgents = a.agents.filter((e) => !agentsIndex.includes(e.id)).map((e) => e.id);
67
+ if (missAgents.length > 0)
68
+ out.push({ source: ".claude/agents/AGENTS_INDEX.md", type: "agent", missingIds: missAgents });
69
+ const hooksIndex = read(repoRoot, ".claude/hooks/HOOKS_INDEX.md");
70
+ const missHooks = a.hooks.filter((e) => !hooksIndex.includes(e.id)).map((e) => e.id);
71
+ if (missHooks.length > 0)
72
+ out.push({ source: ".claude/hooks/HOOKS_INDEX.md", type: "hook", missingIds: missHooks });
73
+ return out;
74
+ }
75
+ /** Full stale-index check → CheckResults under the "Inventory" section. */
76
+ export function checkStaleIndex(repoRoot) {
77
+ const results = [];
78
+ const diffs = compareCounts(repoRoot);
79
+ for (const d of diffs) {
80
+ const declared = d.declared < 0 ? "not found" : String(d.declared);
81
+ results.push({
82
+ name: `Count drift: ${d.source} (${d.label})`,
83
+ status: "fail",
84
+ detail: `declared ${declared}, found ${d.actual}`,
85
+ section: "Inventory",
86
+ });
87
+ }
88
+ const missing = missingRows(repoRoot);
89
+ for (const m of missing) {
90
+ results.push({
91
+ name: `Index incomplete: ${m.source}`,
92
+ status: "fail",
93
+ detail: `${m.missingIds.length} ${m.type}(s) missing: ${m.missingIds.join(", ")}`,
94
+ section: "Inventory",
95
+ });
96
+ }
97
+ if (diffs.length === 0 && missing.length === 0) {
98
+ results.push({ name: "Index counts & completeness", status: "pass", detail: "README + index files match the inventory", section: "Inventory" });
99
+ }
100
+ return results;
101
+ }
102
+ /**
103
+ * Rewrite ONLY the count number tokens in README + index headers to match the
104
+ * inventory. Curated index prose/rows are never touched. Returns the files it
105
+ * changed. Missing completeness rows are reported by the check, never auto-filled.
106
+ */
107
+ export function emitCounts(repoRoot) {
108
+ const changed = new Set();
109
+ // Group specs by source so each file is read/written once.
110
+ const bySource = new Map();
111
+ for (const spec of countSpecs(repoRoot)) {
112
+ const list = bySource.get(spec.source) ?? [];
113
+ list.push(spec);
114
+ bySource.set(spec.source, list);
115
+ }
116
+ for (const [source, specs] of bySource) {
117
+ const abs = path.join(repoRoot, source);
118
+ if (!fs.existsSync(abs))
119
+ continue;
120
+ const body = fs.readFileSync(abs, "utf-8");
121
+ let next = body;
122
+ for (const spec of specs) {
123
+ next = next.replace(spec.pattern, (full, num) => full.replace(num, String(spec.actual)));
124
+ }
125
+ if (next !== body) {
126
+ fs.writeFileSync(abs, next);
127
+ changed.add(source);
128
+ }
129
+ }
130
+ return [...changed];
131
+ }
132
+ //# sourceMappingURL=check-stale-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-stale-index.js","sourceRoot":"","sources":["../../src/core/check-stale-index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import type { CheckResult } from "../commands/validate.js";
2
+ import type { Status } from "../commands/doctor-checks.js";
3
+ /** A single drift finding with enough context to locate and fix it. */
4
+ export interface Violation {
5
+ file: string;
6
+ line: number;
7
+ found: string;
8
+ expected: string;
9
+ }
10
+ /** The canonical lifecycle, distilled from workflow.yaml into checkable sets. */
11
+ export interface CanonicalSpec {
12
+ /** Every phase + substep name (Orient, Plan, ..., Simplify, Verify). */
13
+ phaseNames: Set<string>;
14
+ /** id (as written: "0".."6", "3.5", "3.6") → canonical name. */
15
+ nameById: Map<string, string>;
16
+ /** Integer phase ids that an `applies_to:` list must fully enumerate. */
17
+ integerPhaseIds: number[];
18
+ /** Gate id → its single required-output glob. */
19
+ gateOutput: Map<string, string>;
20
+ /** Canonical second path-segments under tasks/ that carry required outputs. */
21
+ outputDirs: Set<string>;
22
+ /** Reflect-phase canonical leads (all must co-occur where leads are listed). */
23
+ reflectLeads: string[];
24
+ /** Prose files to scan, relative to project root. */
25
+ sources: string[];
26
+ }
27
+ export declare class WorkflowSpecError extends Error {
28
+ readonly kind: "missing" | "unparseable" | "malformed";
29
+ /** "missing" = file absent (downgradable to WARN in a non-scoped run);
30
+ * "unparseable"/"malformed" = present but broken (always a FAIL). */
31
+ constructor(message: string, kind?: "missing" | "unparseable" | "malformed");
32
+ }
33
+ /**
34
+ * Parse `.claude/workflow.yaml` into a CanonicalSpec. Throws WorkflowSpecError
35
+ * if the file is missing or unparseable — NEVER returns a degenerate "empty"
36
+ * spec that would let drift pass silently.
37
+ */
38
+ export declare function loadWorkflowSpec(projectRoot: string): CanonicalSpec;
39
+ /** Scan one prose file for tokens that contradict the canonical spec. */
40
+ export declare function scanForViolations(spec: CanonicalSpec, projectRoot: string, relPath: string): Violation[];
41
+ /**
42
+ * Run the full drift check. Returns CheckResults under the "Workflow" section:
43
+ * a hard FAIL if the spec can't load, a per-source PASS/FAIL otherwise, and a
44
+ * spec-level FAIL if any canonical phase name appears in NO source file.
45
+ */
46
+ export declare function checkWorkflowDrift(projectRoot: string, opts?: {
47
+ missingSpecSeverity?: Status;
48
+ }): CheckResult[];
49
+ //# sourceMappingURL=check-workflow-drift.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-workflow-drift.d.ts","sourceRoot":"","sources":["../../src/core/check-workflow-drift.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAgB3D,uEAAuE;AACvE,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,iFAAiF;AACjF,MAAM,WAAW,aAAa;IAC7B,wEAAwE;IACxE,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB,gEAAgE;IAChE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,yEAAyE;IACzE,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,iDAAiD;IACjD,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,+EAA+E;IAC/E,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB,gFAAgF;IAChF,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,qDAAqD;IACrD,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qBAAa,iBAAkB,SAAQ,KAAK;IAK1C,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,aAAa,GAAG,WAAW;IAJvD;0EACsE;gBAErE,OAAO,EAAE,MAAM,EACN,IAAI,GAAE,SAAS,GAAG,aAAa,GAAG,WAA2B;CAIvE;AAgCD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CA4DnE;AAQD,yEAAyE;AACzE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,CAkFxG;AAOD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,WAAW,EAAE,CAgDlH"}