mewkit 1.10.1 → 1.10.3

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 (92) hide show
  1. package/dist/commands/doctor-memory-checks.d.ts +3 -0
  2. package/dist/commands/doctor-memory-checks.d.ts.map +1 -0
  3. package/dist/commands/doctor-memory-checks.js +39 -0
  4. package/dist/commands/doctor-memory-checks.js.map +1 -0
  5. package/dist/commands/doctor.d.ts.map +1 -1
  6. package/dist/commands/doctor.js +67 -0
  7. package/dist/commands/doctor.js.map +1 -1
  8. package/dist/commands/memory.d.ts +3 -1
  9. package/dist/commands/memory.d.ts.map +1 -1
  10. package/dist/commands/memory.js +97 -19
  11. package/dist/commands/memory.js.map +1 -1
  12. package/dist/commands/upgrade.d.ts.map +1 -1
  13. package/dist/commands/upgrade.js +11 -6
  14. package/dist/commands/upgrade.js.map +1 -1
  15. package/dist/commands/verdict-gate.d.ts +4 -0
  16. package/dist/commands/verdict-gate.d.ts.map +1 -0
  17. package/dist/commands/verdict-gate.js +29 -0
  18. package/dist/commands/verdict-gate.js.map +1 -0
  19. package/dist/core/compute-checksums.d.ts +7 -0
  20. package/dist/core/compute-checksums.d.ts.map +1 -1
  21. package/dist/core/compute-checksums.js +12 -3
  22. package/dist/core/compute-checksums.js.map +1 -1
  23. package/dist/core/file-lock.d.ts +3 -0
  24. package/dist/core/file-lock.d.ts.map +1 -0
  25. package/dist/core/file-lock.js +84 -0
  26. package/dist/core/file-lock.js.map +1 -0
  27. package/dist/core/index.d.ts +4 -0
  28. package/dist/core/index.d.ts.map +1 -1
  29. package/dist/core/index.js +4 -0
  30. package/dist/core/index.js.map +1 -1
  31. package/dist/core/install-metadata-backref.d.ts +14 -0
  32. package/dist/core/install-metadata-backref.d.ts.map +1 -0
  33. package/dist/core/install-metadata-backref.js +39 -0
  34. package/dist/core/install-metadata-backref.js.map +1 -0
  35. package/dist/core/install-metadata-writer.d.ts +4 -0
  36. package/dist/core/install-metadata-writer.d.ts.map +1 -0
  37. package/dist/core/install-metadata-writer.js +31 -0
  38. package/dist/core/install-metadata-writer.js.map +1 -0
  39. package/dist/core/install-metadata.d.ts +158 -0
  40. package/dist/core/install-metadata.d.ts.map +1 -0
  41. package/dist/core/install-metadata.js +180 -0
  42. package/dist/core/install-metadata.js.map +1 -0
  43. package/dist/core/release-metadata.d.ts +80 -0
  44. package/dist/core/release-metadata.d.ts.map +1 -0
  45. package/dist/core/release-metadata.js +70 -0
  46. package/dist/core/release-metadata.js.map +1 -0
  47. package/dist/core/smart-update.d.ts +8 -0
  48. package/dist/core/smart-update.d.ts.map +1 -1
  49. package/dist/core/smart-update.js +170 -47
  50. package/dist/core/smart-update.js.map +1 -1
  51. package/dist/index.js +8 -1
  52. package/dist/index.js.map +1 -1
  53. package/dist/memory/render-views.d.ts +18 -0
  54. package/dist/memory/render-views.d.ts.map +1 -0
  55. package/dist/memory/render-views.js +114 -0
  56. package/dist/memory/render-views.js.map +1 -0
  57. package/dist/memory/schemas.d.ts +642 -0
  58. package/dist/memory/schemas.d.ts.map +1 -0
  59. package/dist/memory/schemas.js +94 -0
  60. package/dist/memory/schemas.js.map +1 -0
  61. package/dist/memory/seed-from-md.d.ts +7 -0
  62. package/dist/memory/seed-from-md.d.ts.map +1 -0
  63. package/dist/memory/seed-from-md.js +167 -0
  64. package/dist/memory/seed-from-md.js.map +1 -0
  65. package/dist/memory/validate.d.ts +26 -0
  66. package/dist/memory/validate.d.ts.map +1 -0
  67. package/dist/memory/validate.js +102 -0
  68. package/dist/memory/validate.js.map +1 -0
  69. package/dist/memory/verdict-schema.d.ts +86 -0
  70. package/dist/memory/verdict-schema.d.ts.map +1 -0
  71. package/dist/memory/verdict-schema.js +71 -0
  72. package/dist/memory/verdict-schema.js.map +1 -0
  73. package/dist/migrate/migrate-orchestrator.d.ts.map +1 -1
  74. package/dist/migrate/migrate-orchestrator.js +6 -2
  75. package/dist/migrate/migrate-orchestrator.js.map +1 -1
  76. package/dist/migrate/portable-installer.d.ts +3 -0
  77. package/dist/migrate/portable-installer.d.ts.map +1 -1
  78. package/dist/migrate/portable-installer.js +3 -0
  79. package/dist/migrate/portable-installer.js.map +1 -1
  80. package/dist/migrate/reconcile/portable-registry-lock.d.ts.map +1 -1
  81. package/dist/migrate/reconcile/portable-registry-lock.js +6 -78
  82. package/dist/migrate/reconcile/portable-registry-lock.js.map +1 -1
  83. package/dist/migrate/reconcile/portable-registry.d.ts +24 -6
  84. package/dist/migrate/reconcile/portable-registry.d.ts.map +1 -1
  85. package/dist/migrate/reconcile/portable-registry.js +7 -1
  86. package/dist/migrate/reconcile/portable-registry.js.map +1 -1
  87. package/dist/migrate/skill-directory-installer.d.ts +2 -0
  88. package/dist/migrate/skill-directory-installer.d.ts.map +1 -1
  89. package/dist/migrate/skill-directory-installer.js +3 -0
  90. package/dist/migrate/skill-directory-installer.js.map +1 -1
  91. package/dist/migrate/types.d.ts +2 -2
  92. package/package.json +1 -1
@@ -0,0 +1,94 @@
1
+ import { z } from "zod";
2
+ // Zod schemas for the curated-memory stores. Source of truth = the live v2.0.0
3
+ // JSON shape (EMPTY_SKELETON in commands/memory.ts) + immediate-capture-handler.
4
+ // Design rules:
5
+ // - `.passthrough()` everywhere → unknown/future fields are kept, never rejected
6
+ // (additive forward-compat: current data must validate clean).
7
+ // - Only the structurally load-bearing fields are required (id, version, scope,
8
+ // consumer) so legacy entries captured before richer fields existed still pass.
9
+ // - Validators WARN on soft issues; they never hard-fail valid v2.0.0 data.
10
+ const Metadata = z
11
+ .object({
12
+ created: z.string().optional(),
13
+ last_updated: z.string().optional(),
14
+ })
15
+ .passthrough();
16
+ // Per-pattern entry for fixes / review-patterns / architecture-decisions.
17
+ export const PatternSchema = z
18
+ .object({
19
+ id: z.string().min(1),
20
+ type: z.string().optional(),
21
+ category: z.string().optional(),
22
+ severity: z.string().optional(),
23
+ domain: z.array(z.string()).optional(),
24
+ applicable_when: z.string().optional(),
25
+ context: z.string().optional(),
26
+ pattern: z.string().optional(),
27
+ frequency: z.number().optional(),
28
+ lastSeen: z.string().optional(),
29
+ timestamp: z.string().optional(),
30
+ })
31
+ .passthrough();
32
+ // Curated pattern store (fixes, review-patterns, architecture-decisions).
33
+ function patternStore(scope) {
34
+ return z
35
+ .object({
36
+ version: z.string(),
37
+ scope: z.literal(scope),
38
+ consumer: z.string(),
39
+ patterns: z.array(PatternSchema),
40
+ metadata: Metadata.optional(),
41
+ })
42
+ .passthrough();
43
+ }
44
+ export const FixesSchema = patternStore("fixes");
45
+ export const ReviewPatternsSchema = patternStore("review-patterns");
46
+ export const ArchitectureDecisionsSchema = patternStore("architecture-decisions");
47
+ // Security findings store — narrative shape, not the pattern shape.
48
+ export const SecurityFindingSchema = z
49
+ .object({
50
+ id: z.string().min(1),
51
+ finding: z.string(),
52
+ severity: z.string().optional(),
53
+ evidence: z.string().optional(),
54
+ status: z.string().optional(),
55
+ lastSeen: z.string().optional(),
56
+ })
57
+ .passthrough();
58
+ export const SecurityFindingsSchema = z
59
+ .object({
60
+ version: z.string(),
61
+ scope: z.literal("security-findings"),
62
+ consumer: z.string(),
63
+ findings: z.array(SecurityFindingSchema),
64
+ metadata: Metadata.optional(),
65
+ })
66
+ .passthrough();
67
+ // The four curated stores. `trace-event` is intentionally excluded — its writer
68
+ // is bash (append-trace.sh) and readers are bash/python, so a TS schema would be
69
+ // inert and would drift from the real writer.
70
+ export const CURATED_STORES = [
71
+ { file: "fixes.json", scope: "fixes", schema: FixesSchema, itemsKey: "patterns", textFields: ["pattern", "context"] },
72
+ {
73
+ file: "review-patterns.json",
74
+ scope: "review-patterns",
75
+ schema: ReviewPatternsSchema,
76
+ itemsKey: "patterns",
77
+ textFields: ["pattern", "context"],
78
+ },
79
+ {
80
+ file: "architecture-decisions.json",
81
+ scope: "architecture-decisions",
82
+ schema: ArchitectureDecisionsSchema,
83
+ itemsKey: "patterns",
84
+ textFields: ["pattern", "context"],
85
+ },
86
+ {
87
+ file: "security-findings.json",
88
+ scope: "security-findings",
89
+ schema: SecurityFindingsSchema,
90
+ itemsKey: "findings",
91
+ textFields: ["finding", "evidence"],
92
+ },
93
+ ];
94
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/memory/schemas.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface SeedResult {
2
+ file: string;
3
+ added: number;
4
+ total: number;
5
+ }
6
+ export declare function seedFromMd(memoryDir: string): SeedResult[];
7
+ //# sourceMappingURL=seed-from-md.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed-from-md.d.ts","sourceRoot":"","sources":["../../src/memory/seed-from-md.ts"],"names":[],"mappings":"AAmHA,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,EAAE,CAwE1D"}
@@ -0,0 +1,167 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ const SEED_SOURCES = [
4
+ { file: "fixes.json", scope: "fixes", consumer: "mk:fix", itemsKey: "patterns", mdSources: ["fixes.md"], category: "bug-class" },
5
+ {
6
+ file: "review-patterns.json",
7
+ scope: "review-patterns",
8
+ consumer: "mk:review,mk:plan-creator",
9
+ itemsKey: "patterns",
10
+ mdSources: ["review-patterns.md"],
11
+ category: "pattern",
12
+ },
13
+ {
14
+ file: "architecture-decisions.json",
15
+ scope: "architecture-decisions",
16
+ consumer: "mk:plan-creator,mk:cook",
17
+ itemsKey: "patterns",
18
+ mdSources: ["architecture-decisions.md"],
19
+ category: "decision",
20
+ },
21
+ {
22
+ file: "security-findings.json",
23
+ scope: "security-findings",
24
+ consumer: "mk:cso,mk:review",
25
+ itemsKey: "findings",
26
+ mdSources: ["security-log.md", "security-notes.md"],
27
+ },
28
+ ];
29
+ // Split a topic MD into `## ` sections (the `# ` title and `> ` intro are skipped).
30
+ function parseSections(content) {
31
+ const lines = content.split("\n");
32
+ const sections = [];
33
+ let current = null;
34
+ for (const line of lines) {
35
+ if (line.startsWith("## ")) {
36
+ if (current)
37
+ sections.push(current);
38
+ current = { heading: line.slice(3).trim(), body: "" };
39
+ }
40
+ else if (current) {
41
+ current.body += line + "\n";
42
+ }
43
+ }
44
+ if (current)
45
+ sections.push(current);
46
+ return sections;
47
+ }
48
+ function slugify(heading) {
49
+ return heading
50
+ .replace(/\([^)]*\)/g, "") // drop (date, ...) parentheticals
51
+ .replace(/[—–-]\s*\d{4}-\d{2}-\d{2}.*$/, "") // drop "— 2026-05-01" date suffixes
52
+ .replace(/^(plan|decision|note):\s*/i, "")
53
+ .toLowerCase()
54
+ .replace(/[^a-z0-9]+/g, "-")
55
+ .replace(/^-+|-+$/g, "")
56
+ .slice(0, 60)
57
+ .replace(/-+$/g, "");
58
+ }
59
+ function deriveId(section) {
60
+ const migrated = section.body.match(/<!--\s*migrated-id:\s*([^\s>]+)\s*-->/);
61
+ if (migrated)
62
+ return migrated[1];
63
+ const slug = slugify(section.heading);
64
+ return slug || `entry-${section.heading.length}`;
65
+ }
66
+ function deriveDate(heading) {
67
+ const iso = heading.match(/(\d{4}-\d{2}-\d{2})/);
68
+ if (iso)
69
+ return iso[1];
70
+ return undefined;
71
+ }
72
+ function loadStore(filePath, source) {
73
+ if (fs.existsSync(filePath)) {
74
+ try {
75
+ return JSON.parse(fs.readFileSync(filePath, "utf-8"));
76
+ }
77
+ catch {
78
+ // fall through to skeleton
79
+ }
80
+ }
81
+ const today = new Date().toISOString().split("T")[0];
82
+ return {
83
+ version: "2.0.0",
84
+ scope: source.scope,
85
+ consumer: source.consumer,
86
+ [source.itemsKey]: [],
87
+ metadata: { created: today, last_updated: today },
88
+ };
89
+ }
90
+ function atomicWrite(filePath, data) {
91
+ const tmp = `${filePath}.tmp-${process.pid}`;
92
+ fs.writeFileSync(tmp, JSON.stringify(data, null, 2) + "\n", "utf-8");
93
+ fs.renameSync(tmp, filePath);
94
+ }
95
+ export function seedFromMd(memoryDir) {
96
+ const results = [];
97
+ for (const source of SEED_SOURCES) {
98
+ const filePath = path.join(memoryDir, source.file);
99
+ const store = loadStore(filePath, source);
100
+ const items = store[source.itemsKey] ?? [];
101
+ const existingIds = new Set(items.map((it) => String(it.id)));
102
+ let added = 0;
103
+ for (const mdName of source.mdSources) {
104
+ const mdPath = path.join(memoryDir, mdName);
105
+ if (!fs.existsSync(mdPath))
106
+ continue;
107
+ const content = fs.readFileSync(mdPath, "utf-8");
108
+ if (source.itemsKey === "findings") {
109
+ // Findings are written as bracketed log lines by injection-audit.py
110
+ // ([DATE] [LEVEL] ...). `## ` headers AND fenced format-doc templates
111
+ // in these files are NOT findings, so both are intentionally skipped.
112
+ let inFence = false;
113
+ let lineIndex = 0; // stable across runs (counts every matched finding line, not just added) — keeps ids idempotent
114
+ for (const line of content.split("\n")) {
115
+ if (line.trim().startsWith("```")) {
116
+ inFence = !inFence;
117
+ continue;
118
+ }
119
+ if (inFence)
120
+ continue;
121
+ const m = line.match(/^\[([^\]]+)\]\s*\[([^\]]+)\]\s*(.+)$/);
122
+ if (!m)
123
+ continue;
124
+ const id = `sec-${slugify(m[3]).slice(0, 40)}-${lineIndex}`;
125
+ lineIndex++;
126
+ if (existingIds.has(id))
127
+ continue;
128
+ items.push({ id, finding: m[3].trim(), severity: m[2].trim(), status: "migrated", source: "seed-from-md" });
129
+ existingIds.add(id);
130
+ added++;
131
+ }
132
+ continue;
133
+ }
134
+ for (const section of parseSections(content)) {
135
+ const id = deriveId(section);
136
+ if (existingIds.has(id))
137
+ continue;
138
+ const date = deriveDate(section.heading);
139
+ items.push({
140
+ id,
141
+ category: source.category,
142
+ context: section.body.trim(),
143
+ pattern: section.heading,
144
+ source: "seed-from-md",
145
+ ...(date ? { lastSeen: date } : {}),
146
+ });
147
+ existingIds.add(id);
148
+ added++;
149
+ }
150
+ }
151
+ if (added > 0) {
152
+ store[source.itemsKey] = items;
153
+ const meta = store.metadata ?? {};
154
+ meta.last_updated = new Date().toISOString().split("T")[0];
155
+ store.metadata = meta;
156
+ atomicWrite(filePath, store);
157
+ }
158
+ else if (!fs.existsSync(filePath)) {
159
+ // Ensure a valid skeleton exists even when there was nothing to seed
160
+ // (e.g. security stores with no real findings yet).
161
+ atomicWrite(filePath, store);
162
+ }
163
+ results.push({ file: source.file, added, total: items.length });
164
+ }
165
+ return results;
166
+ }
167
+ //# sourceMappingURL=seed-from-md.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed-from-md.js","sourceRoot":"","sources":["../../src/memory/seed-from-md.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ export type IssueLevel = "error" | "warn";
2
+ export interface Issue {
3
+ level: IssueLevel;
4
+ message: string;
5
+ }
6
+ export interface StoreResult {
7
+ file: string;
8
+ exists: boolean;
9
+ entryCount: number;
10
+ issues: Issue[];
11
+ }
12
+ export interface ValidationReport {
13
+ stores: StoreResult[];
14
+ errorCount: number;
15
+ warnCount: number;
16
+ }
17
+ export interface ContentValidator {
18
+ (text: string): {
19
+ valid: boolean;
20
+ pattern?: string;
21
+ match?: string;
22
+ };
23
+ }
24
+ export declare function loadContentValidator(memoryDir: string): ContentValidator | null;
25
+ export declare function validateMemory(memoryDir: string): ValidationReport;
26
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/memory/validate.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;AAE1C,MAAM,WAAW,KAAK;IACrB,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,KAAK,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAChC,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACrE;AAID,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAU/E;AA0ED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAYlE"}
@@ -0,0 +1,102 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { createRequire } from "node:module";
4
+ import { CURATED_STORES } from "./schemas.js";
5
+ const require = createRequire(import.meta.url);
6
+ // Load the real validate-content.cjs (DRY — never reimplement the injection
7
+ // patterns) from the project that owns this memory dir. Absent → recheck skipped.
8
+ export function loadContentValidator(memoryDir) {
9
+ const projectRoot = path.resolve(memoryDir, "..", "..");
10
+ const libPath = path.join(projectRoot, ".claude", "hooks", "lib", "validate-content.cjs");
11
+ if (!fs.existsSync(libPath))
12
+ return null;
13
+ try {
14
+ const mod = require(libPath);
15
+ return typeof mod.validateContent === "function" ? mod.validateContent : null;
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ }
21
+ // Count `## ` section headings in a topic MD file — proxy for entry count, used
22
+ // only for the advisory MD↔JSON divergence warning.
23
+ function countMdSections(mdPath) {
24
+ if (!fs.existsSync(mdPath))
25
+ return 0;
26
+ const content = fs.readFileSync(mdPath, "utf-8");
27
+ const headings = content.match(/^## /gm);
28
+ return headings ? headings.length : 0;
29
+ }
30
+ function validateStore(memoryDir, spec, contentValidator) {
31
+ const filePath = path.join(memoryDir, spec.file);
32
+ const result = { file: spec.file, exists: fs.existsSync(filePath), entryCount: 0, issues: [] };
33
+ if (!result.exists) {
34
+ // Missing curated store is a soft state: warn, never fail.
35
+ result.issues.push({ level: "warn", message: `${spec.file} not found` });
36
+ return result;
37
+ }
38
+ let raw;
39
+ try {
40
+ raw = JSON.parse(fs.readFileSync(filePath, "utf-8"));
41
+ }
42
+ catch (err) {
43
+ result.issues.push({ level: "error", message: `invalid JSON: ${err.message}` });
44
+ return result;
45
+ }
46
+ const parsed = spec.schema.safeParse(raw);
47
+ if (!parsed.success) {
48
+ for (const issue of parsed.error.issues) {
49
+ result.issues.push({ level: "error", message: `${issue.path.join(".") || "<root>"}: ${issue.message}` });
50
+ }
51
+ return result;
52
+ }
53
+ const data = parsed.data;
54
+ const items = data[spec.itemsKey] ?? [];
55
+ result.entryCount = items.length;
56
+ // Per-field injection recheck — catches entries captured before the
57
+ // write-path guard existed (defense-in-depth).
58
+ if (contentValidator) {
59
+ for (const item of items) {
60
+ const id = String(item.id ?? "<unknown>");
61
+ for (const field of spec.textFields) {
62
+ const text = item[field];
63
+ if (typeof text !== "string")
64
+ continue;
65
+ const check = contentValidator(text);
66
+ if (!check.valid) {
67
+ result.issues.push({
68
+ level: "warn",
69
+ message: `entry ${id}.${field} matched injection pattern (${check.match ?? check.pattern})`,
70
+ });
71
+ }
72
+ }
73
+ }
74
+ }
75
+ // Advisory MD↔JSON divergence: empty JSON store while its topic MD has entries
76
+ // signals a missing seed (knowledge would be invisible to JSON-first readers).
77
+ const mdName = spec.file.replace(/\.json$/, ".md");
78
+ const mdSections = countMdSections(path.join(memoryDir, mdName));
79
+ if (result.entryCount === 0 && mdSections > 0) {
80
+ result.issues.push({
81
+ level: "warn",
82
+ message: `${spec.file} is empty but ${mdName} has ${mdSections} section(s) — run 'mewkit memory seed-from-md'`,
83
+ });
84
+ }
85
+ return result;
86
+ }
87
+ export function validateMemory(memoryDir) {
88
+ const contentValidator = loadContentValidator(memoryDir);
89
+ const stores = CURATED_STORES.map((spec) => validateStore(memoryDir, spec, contentValidator));
90
+ let errorCount = 0;
91
+ let warnCount = 0;
92
+ for (const s of stores) {
93
+ for (const issue of s.issues) {
94
+ if (issue.level === "error")
95
+ errorCount++;
96
+ else
97
+ warnCount++;
98
+ }
99
+ }
100
+ return { stores, errorCount, warnCount };
101
+ }
102
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/memory/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ import { z } from "zod";
2
+ export declare const DimensionSchema: z.ZodObject<{
3
+ name: z.ZodString;
4
+ verdict: z.ZodEnum<["PASS", "WARN", "FAIL"]>;
5
+ note: z.ZodOptional<z.ZodString>;
6
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
7
+ name: z.ZodString;
8
+ verdict: z.ZodEnum<["PASS", "WARN", "FAIL"]>;
9
+ note: z.ZodOptional<z.ZodString>;
10
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
11
+ name: z.ZodString;
12
+ verdict: z.ZodEnum<["PASS", "WARN", "FAIL"]>;
13
+ note: z.ZodOptional<z.ZodString>;
14
+ }, z.ZodTypeAny, "passthrough">>;
15
+ export declare const VerdictSchema: z.ZodObject<{
16
+ schema_version: z.ZodString;
17
+ slug: z.ZodString;
18
+ gate: z.ZodEnum<["review", "contract"]>;
19
+ decision: z.ZodEnum<["PASS", "PASS_WITH_RISK", "BLOCKED"]>;
20
+ dimensions: z.ZodArray<z.ZodObject<{
21
+ name: z.ZodString;
22
+ verdict: z.ZodEnum<["PASS", "WARN", "FAIL"]>;
23
+ note: z.ZodOptional<z.ZodString>;
24
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
25
+ name: z.ZodString;
26
+ verdict: z.ZodEnum<["PASS", "WARN", "FAIL"]>;
27
+ note: z.ZodOptional<z.ZodString>;
28
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
29
+ name: z.ZodString;
30
+ verdict: z.ZodEnum<["PASS", "WARN", "FAIL"]>;
31
+ note: z.ZodOptional<z.ZodString>;
32
+ }, z.ZodTypeAny, "passthrough">>, "many">;
33
+ evidence_refs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
34
+ created_at: z.ZodString;
35
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
36
+ schema_version: z.ZodString;
37
+ slug: z.ZodString;
38
+ gate: z.ZodEnum<["review", "contract"]>;
39
+ decision: z.ZodEnum<["PASS", "PASS_WITH_RISK", "BLOCKED"]>;
40
+ dimensions: z.ZodArray<z.ZodObject<{
41
+ name: z.ZodString;
42
+ verdict: z.ZodEnum<["PASS", "WARN", "FAIL"]>;
43
+ note: z.ZodOptional<z.ZodString>;
44
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
45
+ name: z.ZodString;
46
+ verdict: z.ZodEnum<["PASS", "WARN", "FAIL"]>;
47
+ note: z.ZodOptional<z.ZodString>;
48
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
49
+ name: z.ZodString;
50
+ verdict: z.ZodEnum<["PASS", "WARN", "FAIL"]>;
51
+ note: z.ZodOptional<z.ZodString>;
52
+ }, z.ZodTypeAny, "passthrough">>, "many">;
53
+ evidence_refs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
54
+ created_at: z.ZodString;
55
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
56
+ schema_version: z.ZodString;
57
+ slug: z.ZodString;
58
+ gate: z.ZodEnum<["review", "contract"]>;
59
+ decision: z.ZodEnum<["PASS", "PASS_WITH_RISK", "BLOCKED"]>;
60
+ dimensions: z.ZodArray<z.ZodObject<{
61
+ name: z.ZodString;
62
+ verdict: z.ZodEnum<["PASS", "WARN", "FAIL"]>;
63
+ note: z.ZodOptional<z.ZodString>;
64
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
65
+ name: z.ZodString;
66
+ verdict: z.ZodEnum<["PASS", "WARN", "FAIL"]>;
67
+ note: z.ZodOptional<z.ZodString>;
68
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
69
+ name: z.ZodString;
70
+ verdict: z.ZodEnum<["PASS", "WARN", "FAIL"]>;
71
+ note: z.ZodOptional<z.ZodString>;
72
+ }, z.ZodTypeAny, "passthrough">>, "many">;
73
+ evidence_refs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
74
+ created_at: z.ZodString;
75
+ }, z.ZodTypeAny, "passthrough">>;
76
+ export type Verdict = z.infer<typeof VerdictSchema>;
77
+ export type VerdictGateStatus = "pass" | "blocked" | "invalid" | "missing" | "legacy-md";
78
+ export interface VerdictGateResult {
79
+ ok: boolean;
80
+ status: VerdictGateStatus;
81
+ decision?: string;
82
+ errors: string[];
83
+ }
84
+ export declare function resolveVerdictPath(slugOrPath: string): string;
85
+ export declare function evaluateVerdictGate(slugOrPath: string): VerdictGateResult;
86
+ //# sourceMappingURL=verdict-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verdict-schema.d.ts","sourceRoot":"","sources":["../../src/memory/verdict-schema.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,eAAe;;;;;;;;;;;;gCAMb,CAAC;AAEhB,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAUX,CAAC;AAEhB,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEpD,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;AAEzF,MAAM,WAAW,iBAAiB;IACjC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAGD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAI7D;AAKD,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,iBAAiB,CAoCzE"}
@@ -0,0 +1,71 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { z } from "zod";
4
+ // MeowKit-native, Zod-validated review verdict proof-bundle (the machine-readable
5
+ // companion to the human `tasks/reviews/<slug>-verdict.md`). Adopts the deterministic
6
+ // proof-bundle PATTERN only — no ClaudeKit script port. Stays under tasks/ and is
7
+ // never injected into model context.
8
+ export const DimensionSchema = z
9
+ .object({
10
+ name: z.string().min(1),
11
+ verdict: z.enum(["PASS", "WARN", "FAIL"]),
12
+ note: z.string().optional(),
13
+ })
14
+ .passthrough();
15
+ export const VerdictSchema = z
16
+ .object({
17
+ schema_version: z.string(),
18
+ slug: z.string().min(1),
19
+ gate: z.enum(["review", "contract"]),
20
+ decision: z.enum(["PASS", "PASS_WITH_RISK", "BLOCKED"]),
21
+ dimensions: z.array(DimensionSchema),
22
+ evidence_refs: z.array(z.string()).optional(),
23
+ created_at: z.string(),
24
+ })
25
+ .passthrough();
26
+ // Resolve a slug or explicit path to the verdict JSON path.
27
+ export function resolveVerdictPath(slugOrPath) {
28
+ if (slugOrPath.endsWith(".json"))
29
+ return slugOrPath;
30
+ if (slugOrPath.endsWith(".md"))
31
+ return slugOrPath.replace(/\.md$/, ".json");
32
+ return path.join("tasks", "reviews", `${slugOrPath}-verdict.json`);
33
+ }
34
+ // The gate. Pass on a valid PASS / PASS_WITH_RISK verdict. Block on BLOCKED,
35
+ // invalid JSON/schema, or total absence. Tolerate a legacy markdown-only verdict
36
+ // during the transition window (warn, but pass) so existing reviews keep shipping.
37
+ export function evaluateVerdictGate(slugOrPath) {
38
+ const jsonPath = resolveVerdictPath(slugOrPath);
39
+ const mdPath = jsonPath.replace(/\.json$/, ".md");
40
+ if (!fs.existsSync(jsonPath)) {
41
+ if (fs.existsSync(mdPath)) {
42
+ return {
43
+ ok: true,
44
+ status: "legacy-md",
45
+ errors: [`No verdict JSON at ${jsonPath}; markdown-only verdict tolerated during transition.`],
46
+ };
47
+ }
48
+ return { ok: false, status: "missing", errors: [`No verdict found at ${jsonPath} (or sibling .md).`] };
49
+ }
50
+ let raw;
51
+ try {
52
+ raw = JSON.parse(fs.readFileSync(jsonPath, "utf-8"));
53
+ }
54
+ catch (err) {
55
+ return { ok: false, status: "invalid", errors: [`invalid JSON: ${err.message}`] };
56
+ }
57
+ const parsed = VerdictSchema.safeParse(raw);
58
+ if (!parsed.success) {
59
+ return {
60
+ ok: false,
61
+ status: "invalid",
62
+ errors: parsed.error.issues.map((i) => `${i.path.join(".") || "<root>"}: ${i.message}`),
63
+ };
64
+ }
65
+ const { decision } = parsed.data;
66
+ if (decision === "BLOCKED") {
67
+ return { ok: false, status: "blocked", decision, errors: ["verdict decision is BLOCKED — Gate 2 blocks ship."] };
68
+ }
69
+ return { ok: true, status: "pass", decision, errors: [] };
70
+ }
71
+ //# sourceMappingURL=verdict-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verdict-schema.js","sourceRoot":"","sources":["../../src/memory/verdict-schema.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"migrate-orchestrator.d.ts","sourceRoot":"","sources":["../../src/migrate/migrate-orchestrator.ts"],"names":[],"mappings":"AAUA,OAAO,EACN,kBAAkB,EAKlB,MAAM,4BAA4B,CAAC;AAkCpC,OAAO,KAAK,EAAE,cAAc,EAAuD,MAAM,YAAY,CAAC;AAEtG,MAAM,WAAW,iBAAiB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;CACf;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BjG;AA4RD,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
1
+ {"version":3,"file":"migrate-orchestrator.d.ts","sourceRoot":"","sources":["../../src/migrate/migrate-orchestrator.ts"],"names":[],"mappings":"AAUA,OAAO,EACN,kBAAkB,EAKlB,MAAM,4BAA4B,CAAC;AAmCpC,OAAO,KAAK,EAAE,cAAc,EAAuD,MAAM,YAAY,CAAC;AAEtG,MAAM,WAAW,iBAAiB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;CACf;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BjG;AAgSD,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -15,6 +15,7 @@ import { convertItem } from "./converters/index.js";
15
15
  import { codexBulkActionShim, providerKey, skillActionShim } from "./migrate-action-shims.js";
16
16
  import { executeDeleteAction, executeInstallAction } from "./portable-installer.js";
17
17
  import { installSkillDirectory } from "./skill-directory-installer.js";
18
+ import { buildInstalledBackRef } from "../core/install-metadata-backref.js";
18
19
  import { installCodexAgents, mergeHooksSettings } from "./hooks/index.js";
19
20
  import { loadModelRoutingConfig } from "./model-routing-config.js";
20
21
  import { printActionDetails, printFinalSummary, printPreflight } from "./migrate-ui-summary.js";
@@ -131,7 +132,10 @@ async function runMigrateUnderLock(options, ctx, scope, targets, isGlobal, model
131
132
  portabilityFiltered.plan.summary.delete));
132
133
  if (!confirmed)
133
134
  return 130;
134
- const results = await executePlan(portabilityFiltered.plan.actions, { allItems: itemsByT }, portableSkills.skillsByProvider, targets, isGlobal, scope.skills, join(discovered.source.root, "settings.json"));
135
+ // One-way bridge: link exported assets back to the installed metadata they
136
+ // came from. Absent installed metadata yields null and the bridge is omitted.
137
+ const installedBackRef = buildInstalledBackRef(discovered.source.root);
138
+ const results = await executePlan(portabilityFiltered.plan.actions, { allItems: itemsByT, installedBackRef }, portableSkills.skillsByProvider, targets, isGlobal, scope.skills, join(discovered.source.root, "settings.json"));
135
139
  printFinalSummary(results);
136
140
  const hasFailures = results.some((r) => !r.success);
137
141
  if (!hasFailures && manifest) {
@@ -239,7 +243,7 @@ async function executePlan(actions, ctx, skillsByProvider, targets, isGlobal, sk
239
243
  continue;
240
244
  const skills = skillsByProvider.get(target) ?? [];
241
245
  for (const skill of skills) {
242
- const r = await installSkillDirectory(skill, target, { global: isGlobal });
246
+ const r = await installSkillDirectory(skill, target, { global: isGlobal, installedBackRef: ctx.installedBackRef });
243
247
  results.push({
244
248
  action: skillActionShim(skill, target, isGlobal, r.path ?? ""),
245
249
  success: r.success,