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.
- package/dist/commands/doctor-memory-checks.d.ts +3 -0
- package/dist/commands/doctor-memory-checks.d.ts.map +1 -0
- package/dist/commands/doctor-memory-checks.js +39 -0
- package/dist/commands/doctor-memory-checks.js.map +1 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +67 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/memory.d.ts +3 -1
- package/dist/commands/memory.d.ts.map +1 -1
- package/dist/commands/memory.js +97 -19
- package/dist/commands/memory.js.map +1 -1
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +11 -6
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/commands/verdict-gate.d.ts +4 -0
- package/dist/commands/verdict-gate.d.ts.map +1 -0
- package/dist/commands/verdict-gate.js +29 -0
- package/dist/commands/verdict-gate.js.map +1 -0
- package/dist/core/compute-checksums.d.ts +7 -0
- package/dist/core/compute-checksums.d.ts.map +1 -1
- package/dist/core/compute-checksums.js +12 -3
- package/dist/core/compute-checksums.js.map +1 -1
- package/dist/core/file-lock.d.ts +3 -0
- package/dist/core/file-lock.d.ts.map +1 -0
- package/dist/core/file-lock.js +84 -0
- package/dist/core/file-lock.js.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +4 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/install-metadata-backref.d.ts +14 -0
- package/dist/core/install-metadata-backref.d.ts.map +1 -0
- package/dist/core/install-metadata-backref.js +39 -0
- package/dist/core/install-metadata-backref.js.map +1 -0
- package/dist/core/install-metadata-writer.d.ts +4 -0
- package/dist/core/install-metadata-writer.d.ts.map +1 -0
- package/dist/core/install-metadata-writer.js +31 -0
- package/dist/core/install-metadata-writer.js.map +1 -0
- package/dist/core/install-metadata.d.ts +158 -0
- package/dist/core/install-metadata.d.ts.map +1 -0
- package/dist/core/install-metadata.js +180 -0
- package/dist/core/install-metadata.js.map +1 -0
- package/dist/core/release-metadata.d.ts +80 -0
- package/dist/core/release-metadata.d.ts.map +1 -0
- package/dist/core/release-metadata.js +70 -0
- package/dist/core/release-metadata.js.map +1 -0
- package/dist/core/smart-update.d.ts +8 -0
- package/dist/core/smart-update.d.ts.map +1 -1
- package/dist/core/smart-update.js +170 -47
- package/dist/core/smart-update.js.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/memory/render-views.d.ts +18 -0
- package/dist/memory/render-views.d.ts.map +1 -0
- package/dist/memory/render-views.js +114 -0
- package/dist/memory/render-views.js.map +1 -0
- package/dist/memory/schemas.d.ts +642 -0
- package/dist/memory/schemas.d.ts.map +1 -0
- package/dist/memory/schemas.js +94 -0
- package/dist/memory/schemas.js.map +1 -0
- package/dist/memory/seed-from-md.d.ts +7 -0
- package/dist/memory/seed-from-md.d.ts.map +1 -0
- package/dist/memory/seed-from-md.js +167 -0
- package/dist/memory/seed-from-md.js.map +1 -0
- package/dist/memory/validate.d.ts +26 -0
- package/dist/memory/validate.d.ts.map +1 -0
- package/dist/memory/validate.js +102 -0
- package/dist/memory/validate.js.map +1 -0
- package/dist/memory/verdict-schema.d.ts +86 -0
- package/dist/memory/verdict-schema.d.ts.map +1 -0
- package/dist/memory/verdict-schema.js +71 -0
- package/dist/memory/verdict-schema.js.map +1 -0
- package/dist/migrate/migrate-orchestrator.d.ts.map +1 -1
- package/dist/migrate/migrate-orchestrator.js +6 -2
- package/dist/migrate/migrate-orchestrator.js.map +1 -1
- package/dist/migrate/portable-installer.d.ts +3 -0
- package/dist/migrate/portable-installer.d.ts.map +1 -1
- package/dist/migrate/portable-installer.js +3 -0
- package/dist/migrate/portable-installer.js.map +1 -1
- package/dist/migrate/reconcile/portable-registry-lock.d.ts.map +1 -1
- package/dist/migrate/reconcile/portable-registry-lock.js +6 -78
- package/dist/migrate/reconcile/portable-registry-lock.js.map +1 -1
- package/dist/migrate/reconcile/portable-registry.d.ts +24 -6
- package/dist/migrate/reconcile/portable-registry.d.ts.map +1 -1
- package/dist/migrate/reconcile/portable-registry.js +7 -1
- package/dist/migrate/reconcile/portable-registry.js.map +1 -1
- package/dist/migrate/skill-directory-installer.d.ts +2 -0
- package/dist/migrate/skill-directory-installer.d.ts.map +1 -1
- package/dist/migrate/skill-directory-installer.js +3 -0
- package/dist/migrate/skill-directory-installer.js.map +1 -1
- package/dist/migrate/types.d.ts +2 -2
- 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 @@
|
|
|
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;
|
|
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
|
-
|
|
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,
|