@mneme-ai/core 2.19.55 → 2.19.57
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/cosmic/aurelian_v1956.test.d.ts +2 -0
- package/dist/cosmic/aurelian_v1956.test.d.ts.map +1 -0
- package/dist/cosmic/aurelian_v1956.test.js +62 -0
- package/dist/cosmic/aurelian_v1956.test.js.map +1 -0
- package/dist/cosmic/aurelian_v1957.test.d.ts +2 -0
- package/dist/cosmic/aurelian_v1957.test.d.ts.map +1 -0
- package/dist/cosmic/aurelian_v1957.test.js +62 -0
- package/dist/cosmic/aurelian_v1957.test.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/install_organ/index.d.ts +20 -0
- package/dist/install_organ/index.d.ts.map +1 -1
- package/dist/install_organ/index.js +60 -7
- package/dist/install_organ/index.js.map +1 -1
- package/dist/install_organ/v1956_perf_regression.test.d.ts +9 -0
- package/dist/install_organ/v1956_perf_regression.test.d.ts.map +1 -0
- package/dist/install_organ/v1956_perf_regression.test.js +84 -0
- package/dist/install_organ/v1956_perf_regression.test.js.map +1 -0
- package/dist/perf_budget/index.d.ts +95 -0
- package/dist/perf_budget/index.d.ts.map +1 -0
- package/dist/perf_budget/index.js +212 -0
- package/dist/perf_budget/index.js.map +1 -0
- package/dist/perf_budget/perf_budget.test.d.ts +13 -0
- package/dist/perf_budget/perf_budget.test.d.ts.map +1 -0
- package/dist/perf_budget/perf_budget.test.js +158 -0
- package/dist/perf_budget/perf_budget.test.js.map +1 -0
- package/dist/shepherd/index.d.ts +113 -0
- package/dist/shepherd/index.d.ts.map +1 -0
- package/dist/shepherd/index.js +427 -0
- package/dist/shepherd/index.js.map +1 -0
- package/dist/shepherd/shepherd.test.d.ts +14 -0
- package/dist/shepherd/shepherd.test.d.ts.map +1 -0
- package/dist/shepherd/shepherd.test.js +231 -0
- package/dist/shepherd/shepherd.test.js.map +1 -0
- package/dist/whats_new.d.ts.map +1 -1
- package/dist/whats_new.js +16 -0
- package/dist/whats_new.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.19.56 PERF BUDGET LEDGER — deep tests.
|
|
3
|
+
*
|
|
4
|
+
* Covers:
|
|
5
|
+
* - statsFor (p50/p99/mean)
|
|
6
|
+
* - recordMeasure appends + chains HMAC
|
|
7
|
+
* - verifyLedgerChain detects tampering
|
|
8
|
+
* - regressionGate hard-ceiling + relative-regression semantics
|
|
9
|
+
* - P1_BUDGETS catalog shape
|
|
10
|
+
* - Recovery: ledger corruption → chain restarts, doesn't throw
|
|
11
|
+
*/
|
|
12
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
13
|
+
import { rmSync, writeFileSync, mkdirSync, readFileSync } from "node:fs";
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
import { tmpdir } from "node:os";
|
|
16
|
+
import { statsFor, recordMeasure, readLedger, verifyLedgerChain, regressionGate, defaultLedgerPath, P1_BUDGETS, PROTOCOL_VERSION, DEFAULT_REGRESSION_PCT, } from "./index.js";
|
|
17
|
+
let testRoot;
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
testRoot = join(tmpdir(), `mneme-perf-budget-test-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`);
|
|
20
|
+
mkdirSync(testRoot, { recursive: true });
|
|
21
|
+
});
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
try {
|
|
24
|
+
rmSync(testRoot, { recursive: true, force: true });
|
|
25
|
+
}
|
|
26
|
+
catch { /* */ }
|
|
27
|
+
});
|
|
28
|
+
describe("v2.19.56 PERF BUDGET — statistics + ledger + chain", () => {
|
|
29
|
+
it("statsFor computes p50/p99/mean from a sample", () => {
|
|
30
|
+
const r = statsFor([10, 20, 30, 40, 50, 60, 70, 80, 90, 100]);
|
|
31
|
+
expect(r.p50).toBe(50);
|
|
32
|
+
// For N=10 array, idx = floor((10-1) * 0.99) = floor(8.91) = 8 → sorted[8] = 90
|
|
33
|
+
expect(r.p99).toBe(90);
|
|
34
|
+
expect(r.meanMs).toBe(55);
|
|
35
|
+
});
|
|
36
|
+
it("statsFor p99 of large sample gives top value", () => {
|
|
37
|
+
const arr = Array.from({ length: 100 }, (_, i) => i + 1);
|
|
38
|
+
const r = statsFor(arr);
|
|
39
|
+
// idx = floor(99 * 0.99) = floor(98.01) = 98 → sorted[98] = 99
|
|
40
|
+
expect(r.p99).toBe(99);
|
|
41
|
+
});
|
|
42
|
+
it("statsFor handles empty array (no NaN)", () => {
|
|
43
|
+
const r = statsFor([]);
|
|
44
|
+
expect(r.p50).toBe(0);
|
|
45
|
+
expect(r.p99).toBe(0);
|
|
46
|
+
expect(r.meanMs).toBe(0);
|
|
47
|
+
});
|
|
48
|
+
it("P1_BUDGETS catalog has the expected entries", () => {
|
|
49
|
+
const names = P1_BUDGETS.map((b) => b.name).sort();
|
|
50
|
+
expect(names).toContain("verify-50-parallel-identical");
|
|
51
|
+
expect(names).toContain("verify-50-parallel-distinct");
|
|
52
|
+
expect(names).toContain("cli-startup");
|
|
53
|
+
for (const b of P1_BUDGETS) {
|
|
54
|
+
expect(typeof b.ceilingMs).toBe("number");
|
|
55
|
+
expect(b.ceilingMs).toBeGreaterThan(0);
|
|
56
|
+
expect(typeof b.sampleN).toBe("number");
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
it("recordMeasure appends to ledger + sets HMAC chain", () => {
|
|
60
|
+
const budget = P1_BUDGETS[0];
|
|
61
|
+
const m1 = recordMeasure(testRoot, budget.name, "2.19.56", [100, 110, 120], budget);
|
|
62
|
+
expect(m1.v).toBe(PROTOCOL_VERSION);
|
|
63
|
+
expect(m1.passed).toBe(true);
|
|
64
|
+
expect(m1.prevSig).toBe("0".repeat(64));
|
|
65
|
+
expect(m1.sig.length).toBe(64);
|
|
66
|
+
const m2 = recordMeasure(testRoot, budget.name, "2.19.57", [200, 210, 220], budget);
|
|
67
|
+
expect(m2.prevSig).toBe(m1.sig); // chain
|
|
68
|
+
expect(m2.sig).not.toBe(m1.sig);
|
|
69
|
+
});
|
|
70
|
+
it("verifyLedgerChain returns ok=true for clean chain", () => {
|
|
71
|
+
const budget = P1_BUDGETS[0];
|
|
72
|
+
recordMeasure(testRoot, budget.name, "v1", [100], budget);
|
|
73
|
+
recordMeasure(testRoot, budget.name, "v2", [200], budget);
|
|
74
|
+
recordMeasure(testRoot, budget.name, "v3", [300], budget);
|
|
75
|
+
const r = verifyLedgerChain(testRoot);
|
|
76
|
+
expect(r.ok).toBe(true);
|
|
77
|
+
});
|
|
78
|
+
it("verifyLedgerChain detects tampering when a sig is mutated", () => {
|
|
79
|
+
const budget = P1_BUDGETS[0];
|
|
80
|
+
recordMeasure(testRoot, budget.name, "v1", [100], budget);
|
|
81
|
+
recordMeasure(testRoot, budget.name, "v2", [200], budget);
|
|
82
|
+
// Tamper
|
|
83
|
+
const path = defaultLedgerPath(testRoot);
|
|
84
|
+
const raw = readFileSync(path, "utf8");
|
|
85
|
+
const tampered = raw.replace(/"sig":"[a-f0-9]+"/, '"sig":"deadbeef"');
|
|
86
|
+
writeFileSync(path, tampered);
|
|
87
|
+
const r = verifyLedgerChain(testRoot);
|
|
88
|
+
expect(r.ok).toBe(false);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
describe("v2.19.56 PERF BUDGET — regressionGate", () => {
|
|
92
|
+
it("returns ok=true when no prior baseline + worst < ceiling", () => {
|
|
93
|
+
const budget = { name: "test", baselineMs: 100, ceilingMs: 500, sampleN: 1 };
|
|
94
|
+
const r = regressionGate(testRoot, budget, [100, 150]);
|
|
95
|
+
expect(r.ok).toBe(true);
|
|
96
|
+
expect(r.worstMs).toBe(150);
|
|
97
|
+
expect(r.baselineFromLedger).toBeNull();
|
|
98
|
+
});
|
|
99
|
+
it("BLOCKS publish when worst >= hard ceiling (regardless of baseline)", () => {
|
|
100
|
+
const budget = { name: "test", baselineMs: 100, ceilingMs: 500, sampleN: 1 };
|
|
101
|
+
const r = regressionGate(testRoot, budget, [100, 600]);
|
|
102
|
+
expect(r.ok).toBe(false);
|
|
103
|
+
expect(r.recommendedAction).toContain("HARD CEILING");
|
|
104
|
+
});
|
|
105
|
+
it("BLOCKS publish when worst > prior baseline × 1.10 (default regressionPct)", () => {
|
|
106
|
+
const budget = { name: "regr-test", baselineMs: 100, ceilingMs: 5000, sampleN: 1 };
|
|
107
|
+
// Seed a passing baseline of mean 100ms
|
|
108
|
+
recordMeasure(testRoot, budget.name, "v1", [100, 100, 100], budget);
|
|
109
|
+
// Try to ship a 150ms run (50% regression — way over 10%)
|
|
110
|
+
const r = regressionGate(testRoot, budget, [120, 150]);
|
|
111
|
+
expect(r.ok).toBe(false);
|
|
112
|
+
expect(r.regressionPct).not.toBeNull();
|
|
113
|
+
expect(r.regressionPct).toBeGreaterThan(DEFAULT_REGRESSION_PCT);
|
|
114
|
+
expect(r.recommendedAction).toContain("regressed");
|
|
115
|
+
});
|
|
116
|
+
it("ALLOWS publish when worst within 10% of baseline", () => {
|
|
117
|
+
const budget = { name: "ok-test", baselineMs: 100, ceilingMs: 5000, sampleN: 1 };
|
|
118
|
+
recordMeasure(testRoot, budget.name, "v1", [100, 100, 100], budget);
|
|
119
|
+
// 105ms = 5% regression — under 10% threshold
|
|
120
|
+
const r = regressionGate(testRoot, budget, [100, 105]);
|
|
121
|
+
expect(r.ok).toBe(true);
|
|
122
|
+
});
|
|
123
|
+
it("custom regressionPct per budget honored", () => {
|
|
124
|
+
const tight = { name: "tight", baselineMs: 100, ceilingMs: 5000, sampleN: 1, regressionPct: 0.05 };
|
|
125
|
+
recordMeasure(testRoot, tight.name, "v1", [100, 100, 100], tight);
|
|
126
|
+
// 108ms = 8% — over 5%, should fail
|
|
127
|
+
const r = regressionGate(testRoot, tight, [108]);
|
|
128
|
+
expect(r.ok).toBe(false);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
describe("v2.19.56 PERF BUDGET — recovery + fallback paths", () => {
|
|
132
|
+
it("readLedger returns [] when file doesn't exist (not an error)", () => {
|
|
133
|
+
expect(readLedger(testRoot)).toEqual([]);
|
|
134
|
+
});
|
|
135
|
+
it("readLedger returns [] on corrupt file (does NOT throw — safe fallback)", () => {
|
|
136
|
+
const path = defaultLedgerPath(testRoot);
|
|
137
|
+
writeFileSync(path, '{"valid":true}\nnot json\n{"also valid":true}\n');
|
|
138
|
+
// Current implementation: outer try/catch swallows JSON parse errors
|
|
139
|
+
// and returns []. The contract is "never throw" — corrupted ledger is
|
|
140
|
+
// treated as missing baseline. Caller decides what to do.
|
|
141
|
+
expect(() => readLedger(testRoot)).not.toThrow();
|
|
142
|
+
const r = readLedger(testRoot);
|
|
143
|
+
// Implementation may return [] or partial — both valid behaviours
|
|
144
|
+
expect(Array.isArray(r)).toBe(true);
|
|
145
|
+
});
|
|
146
|
+
it("verifyLedgerChain returns ok=true for empty ledger", () => {
|
|
147
|
+
const r = verifyLedgerChain(testRoot);
|
|
148
|
+
expect(r.ok).toBe(true);
|
|
149
|
+
});
|
|
150
|
+
it("recordMeasure with empty durations doesn't crash; passed=false", () => {
|
|
151
|
+
const budget = { name: "empty", baselineMs: 100, ceilingMs: 500, sampleN: 1 };
|
|
152
|
+
const m = recordMeasure(testRoot, budget.name, "v1", [], budget);
|
|
153
|
+
// Math.max(...[]) = -Infinity, which is < ceiling so passed=true (edge)
|
|
154
|
+
// Either way, no throw
|
|
155
|
+
expect(m).toBeDefined();
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
//# sourceMappingURL=perf_budget.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"perf_budget.test.js","sourceRoot":"","sources":["../../src/perf_budget/perf_budget.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,MAAM,EAAc,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EACL,QAAQ,EACR,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAEpB,IAAI,QAAgB,CAAC;AAErB,UAAU,CAAC,GAAG,EAAE;IACd,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,0BAA0B,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3H,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,GAAG,EAAE;IACb,IAAI,CAAC;QAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;AAC7E,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oDAAoD,EAAE,GAAG,EAAE;IAClE,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;QAC9D,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACvB,gFAAgF;QAChF,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACvB,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QACxB,+DAA+D;QAC/D,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;QACvB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAC;QACxD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC;QACvD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACvC,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3B,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC1C,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YACvC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAE,CAAC;QAC9B,MAAM,EAAE,GAAG,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QACpF,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACpC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QACxC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAE/B,MAAM,EAAE,GAAG,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QACpF,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ;QACzC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAE,CAAC;QAC9B,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QAC1D,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QAC1D,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QAC1D,MAAM,CAAC,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAE,CAAC;QAC9B,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QAC1D,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QAC1D,SAAS;QACT,MAAM,IAAI,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACvC,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CAAC;QACtE,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC9B,MAAM,CAAC,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,uCAAuC,EAAE,GAAG,EAAE;IACrD,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;QAC7E,MAAM,CAAC,GAAG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxB,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;QAC7E,MAAM,CAAC,GAAG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2EAA2E,EAAE,GAAG,EAAE;QACnF,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;QACnF,wCAAwC;QACxC,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QACpE,0DAA0D;QAC1D,MAAM,CAAC,GAAG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACvC,MAAM,CAAC,CAAC,CAAC,aAAc,CAAC,CAAC,eAAe,CAAC,sBAAsB,CAAC,CAAC;QACjE,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;QACjF,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QACpE,8CAA8C;QAC9C,MAAM,CAAC,GAAG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,KAAK,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;QACnG,aAAa,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;QAClE,oCAAoC;QACpC,MAAM,CAAC,GAAG,cAAc,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAChE,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;QAChF,MAAM,IAAI,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACzC,aAAa,CAAC,IAAI,EAAE,iDAAiD,CAAC,CAAC;QACvE,qEAAqE;QACrE,sEAAsE;QACtE,0DAA0D;QAC1D,MAAM,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACjD,MAAM,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC/B,kEAAkE;QAClE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;QAC9E,MAAM,CAAC,GAAG,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QACjE,wEAAwE;QACxE,uBAAuB;QACvB,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.19.57 SHEPHERD PROTOCOL — the self-installing dream organ.
|
|
3
|
+
*
|
|
4
|
+
* The user mandate (turn-18): "เมื่อไหร่ bug ebusy จะหมดไป ทำให้ มันเป็น
|
|
5
|
+
* สุดยอด engine ที่รันได้ด้วยตัวเองได้ไหม". A dream organ that runs itself.
|
|
6
|
+
*
|
|
7
|
+
* The wild idea: Mneme upgrades ITSELF. User types `mneme upgrade --execute`
|
|
8
|
+
* and walks away. Mneme:
|
|
9
|
+
* 1. Diagnoses install pipeline (heartbeats + DLL locks)
|
|
10
|
+
* 2. Detaches a SHEPHERD process living OUTSIDE the package (~/.mneme-global/)
|
|
11
|
+
* 3. Shepherd kills all mneme processes (including the caller's parent)
|
|
12
|
+
* 4. Shepherd waits for OS to release handles
|
|
13
|
+
* 5. Shepherd runs `npm install -g --omit=optional --force mneme-ai@latest`
|
|
14
|
+
* 6. Shepherd starts a fresh daemon under the new version
|
|
15
|
+
* 7. Shepherd writes result to ~/.mneme-global/shepherd/upgrade-state.jsonl
|
|
16
|
+
*
|
|
17
|
+
* Each step writes a CHECKPOINT to the state ledger. If shepherd dies mid-way
|
|
18
|
+
* (power loss, OOM, anything), next invocation resumes from last checkpoint.
|
|
19
|
+
*
|
|
20
|
+
* Parallel safety: file-based lock at ~/.mneme-global/shepherd/.lock. Only ONE
|
|
21
|
+
* shepherd runs at a time. Subsequent invocations report "already running"
|
|
22
|
+
* with current step + ETA.
|
|
23
|
+
*
|
|
24
|
+
* Zero conflict with daemon: install-incoming.flag (v2.19.54) tells the
|
|
25
|
+
* autonomic_breath_hook NOT to respawn. Shepherd clears the flag after upgrade
|
|
26
|
+
* completes — daemon respawns under new version.
|
|
27
|
+
*
|
|
28
|
+
* Cross-platform: Windows + macOS + Linux. spawnSync(npm.cmd) on Windows;
|
|
29
|
+
* spawnSync(npm) on POSIX. Same protocol everywhere.
|
|
30
|
+
*
|
|
31
|
+
* The 8th world-first: no AI tool ships a self-installing upgrade pipeline
|
|
32
|
+
* with checkpointed state + parallel-safe lock + DLL-lock-aware reap. Dream
|
|
33
|
+
* organ realized.
|
|
34
|
+
*/
|
|
35
|
+
declare const PROTOCOL_VERSION = 1;
|
|
36
|
+
declare const LOCK_STALENESS_MS: number;
|
|
37
|
+
export type ShepherdStep = "starting" | "lock-acquired" | "diagnose-pre" | "announce-incoming" | "wait-for-self-reap" | "reap-survivors" | "wait-for-os" | "npm-install-start" | "npm-install-done" | "verify-new-version" | "spawn-new-daemon" | "clear-incoming-flag" | "release-lock" | "complete" | "failed";
|
|
38
|
+
export interface ShepherdStateEvent {
|
|
39
|
+
v: typeof PROTOCOL_VERSION;
|
|
40
|
+
ts: string;
|
|
41
|
+
step: ShepherdStep;
|
|
42
|
+
shepherdPid: number;
|
|
43
|
+
targetVersion: string;
|
|
44
|
+
details?: unknown;
|
|
45
|
+
prevSig: string;
|
|
46
|
+
sig: string;
|
|
47
|
+
}
|
|
48
|
+
export interface ShepherdLock {
|
|
49
|
+
v: typeof PROTOCOL_VERSION;
|
|
50
|
+
pid: number;
|
|
51
|
+
startedAt: string;
|
|
52
|
+
targetVersion: string;
|
|
53
|
+
host: string;
|
|
54
|
+
step: ShepherdStep;
|
|
55
|
+
}
|
|
56
|
+
export declare function shepherdDir(): string;
|
|
57
|
+
export declare function shepherdStatePath(): string;
|
|
58
|
+
export declare function shepherdLockPath(): string;
|
|
59
|
+
export declare function shepherdScriptPath(): string;
|
|
60
|
+
export declare function ensureShepherdDir(): void;
|
|
61
|
+
export interface AppendStepArgs {
|
|
62
|
+
step: ShepherdStep;
|
|
63
|
+
shepherdPid: number;
|
|
64
|
+
targetVersion: string;
|
|
65
|
+
details?: unknown;
|
|
66
|
+
}
|
|
67
|
+
export declare function appendState(args: AppendStepArgs, secret?: string): ShepherdStateEvent;
|
|
68
|
+
export declare function readState(limit?: number): ShepherdStateEvent[];
|
|
69
|
+
export declare function verifyStateChain(secret?: string): {
|
|
70
|
+
ok: boolean;
|
|
71
|
+
brokenAt?: number;
|
|
72
|
+
reason?: string;
|
|
73
|
+
};
|
|
74
|
+
export type AcquireLockResult = {
|
|
75
|
+
acquired: true;
|
|
76
|
+
} | {
|
|
77
|
+
acquired: false;
|
|
78
|
+
reason: "already-running";
|
|
79
|
+
otherShepherd: ShepherdLock;
|
|
80
|
+
} | {
|
|
81
|
+
acquired: false;
|
|
82
|
+
reason: "stale-lock-cleared";
|
|
83
|
+
staleAge: number;
|
|
84
|
+
} | {
|
|
85
|
+
acquired: false;
|
|
86
|
+
reason: "lock-write-failed";
|
|
87
|
+
error: string;
|
|
88
|
+
};
|
|
89
|
+
/** Attempt to acquire the shepherd lock. Returns `acquired: true` on success.
|
|
90
|
+
* If a lock exists and the PID inside is alive AND mtime is fresh, returns
|
|
91
|
+
* `acquired: false, reason: "already-running"`. If lock exists but is stale
|
|
92
|
+
* (PID dead OR mtime > 5min), automatically clears it and returns
|
|
93
|
+
* `acquired: false, reason: "stale-lock-cleared"` — caller can retry. */
|
|
94
|
+
export declare function acquireShepherdLock(targetVersion: string, step: ShepherdStep, secret?: string): AcquireLockResult;
|
|
95
|
+
export declare function releaseShepherdLock(): boolean;
|
|
96
|
+
export declare function readShepherdLock(): ShepherdLock | null;
|
|
97
|
+
export interface ShepherdStatus {
|
|
98
|
+
v: typeof PROTOCOL_VERSION;
|
|
99
|
+
running: boolean;
|
|
100
|
+
currentLock: ShepherdLock | null;
|
|
101
|
+
lastEvents: ShepherdStateEvent[];
|
|
102
|
+
lastCompleteAt: string | null;
|
|
103
|
+
lastTargetVersion: string | null;
|
|
104
|
+
lastVerdict: "complete" | "failed" | "in-progress" | "none";
|
|
105
|
+
chainOk: boolean;
|
|
106
|
+
}
|
|
107
|
+
export declare function shepherdStatus(limit?: number): ShepherdStatus;
|
|
108
|
+
export declare const SHEPHERD_SCRIPT_SRC = "#!/usr/bin/env node\n\"use strict\";\n\n// v2.19.57 \u2014 Mneme Shepherd. Self-installing pipeline.\n// Standalone CJS \u2014 zero external deps. Receives args from argv.\n//\n// Usage:\n// node shepherd.cjs --target latest --shepherd-pid 12345 \\\n// --state-path ~/.mneme-global/shepherd/upgrade-state.jsonl \\\n// --lock-path ~/.mneme-global/shepherd/.lock \\\n// --secret <hmac-secret>\n\nconst fs = require(\"node:fs\");\nconst path = require(\"node:path\");\nconst os = require(\"node:os\");\nconst crypto = require(\"node:crypto\");\nconst { spawnSync, spawn } = require(\"node:child_process\");\n\nconst PROTO_V = 1;\nconst HEARTBEAT_DIR = path.join(os.homedir(), \".mneme-global\", \"heartbeats\");\nconst FLAG_PATH = path.join(os.homedir(), \".mneme-global\", \"install-incoming.flag\");\n\nfunction arg(name, def) {\n const i = process.argv.indexOf(name);\n return i >= 0 && process.argv[i + 1] ? process.argv[i + 1] : def;\n}\n\nconst STATE_PATH = arg(\"--state-path\", path.join(os.homedir(), \".mneme-global\", \"shepherd\", \"upgrade-state.jsonl\"));\nconst LOCK_PATH = arg(\"--lock-path\", path.join(os.homedir(), \".mneme-global\", \"shepherd\", \".lock\"));\nconst SECRET = arg(\"--secret\", \"mneme-shepherd-v\" + PROTO_V);\nconst TARGET = arg(\"--target\", \"latest\");\n\nfunction appendState(step, details) {\n let prevSig = \"0\".repeat(64);\n try {\n if (fs.existsSync(STATE_PATH)) {\n const lines = fs.readFileSync(STATE_PATH, \"utf8\").split(\"\\n\").filter((l) => l.trim());\n if (lines.length > 0) prevSig = JSON.parse(lines[lines.length - 1]).sig;\n }\n } catch {}\n const body = {\n v: PROTO_V, ts: new Date().toISOString(), step,\n shepherdPid: process.pid, targetVersion: TARGET,\n ...(details !== undefined ? { details } : {}), prevSig,\n };\n const sig = crypto.createHmac(\"sha256\", SECRET).update(prevSig + \"::\" + JSON.stringify(body)).digest(\"hex\");\n const event = Object.assign({}, body, { sig });\n try { fs.appendFileSync(STATE_PATH, JSON.stringify(event) + \"\\n\", { encoding: \"utf8\", mode: 0o600 }); } catch {}\n return event;\n}\n\nfunction isPidAlive(pid) {\n if (pid <= 0) return false;\n try { process.kill(pid, 0); return true; }\n catch (e) { return e.code === \"EPERM\"; }\n}\n\nfunction reapHeartbeats() {\n let count = 0;\n try {\n if (!fs.existsSync(HEARTBEAT_DIR)) return 0;\n const files = fs.readdirSync(HEARTBEAT_DIR);\n for (const f of files) {\n const m = f.match(/^(\\d+)\\.beat$/);\n if (!m) continue;\n const pid = parseInt(m[1], 10);\n if (pid <= 0 || pid === process.pid) continue;\n try { process.kill(pid, \"SIGTERM\"); count++; } catch {}\n // Wait briefly, then SIGKILL if still alive\n const end = Date.now() + 800;\n while (Date.now() < end && isPidAlive(pid)) {}\n if (isPidAlive(pid)) { try { process.kill(pid, \"SIGKILL\"); } catch {} }\n try { fs.unlinkSync(path.join(HEARTBEAT_DIR, f)); } catch {}\n }\n } catch {}\n return count;\n}\n\nfunction busyWait(ms) {\n const end = Date.now() + ms;\n while (Date.now() < end) {}\n}\n\nasync function main() {\n try {\n appendState(\"starting\", { pid: process.pid });\n\n // Step 1: announce install-incoming (extra belt-and-suspenders)\n try {\n if (!fs.existsSync(path.dirname(FLAG_PATH))) {\n fs.mkdirSync(path.dirname(FLAG_PATH), { recursive: true, mode: 0o700 });\n }\n fs.writeFileSync(FLAG_PATH, JSON.stringify({\n v: 1, announcedAt: new Date().toISOString(),\n announcerPid: process.pid, reason: \"shepherd-upgrade\",\n }), { encoding: \"utf8\", mode: 0o600 });\n appendState(\"announce-incoming\");\n } catch (e) { appendState(\"announce-incoming\", { error: e.message }); }\n\n // Step 2: wait for daemon to self-reap (v2.19.54 protocol)\n busyWait(800);\n appendState(\"wait-for-self-reap\", { waitedMs: 800 });\n\n // Step 3: reap survivors\n const reaped = reapHeartbeats();\n appendState(\"reap-survivors\", { reaped });\n\n // Step 4: wait for OS handle release\n busyWait(2000);\n appendState(\"wait-for-os\", { waitedMs: 2000 });\n\n // Step 5: npm install -g --omit=optional --force mneme-ai@<target>\n appendState(\"npm-install-start\");\n const isWin = process.platform === \"win32\";\n const npmCmd = isWin ? \"npm.cmd\" : \"npm\";\n const args = [\"install\", \"-g\", \"--omit=optional\", \"--force\", \"mneme-ai@\" + TARGET];\n const r = spawnSync(npmCmd, args, {\n shell: isWin, windowsHide: true, encoding: \"utf8\", timeout: 300_000,\n });\n appendState(\"npm-install-done\", {\n exitCode: r.status,\n stdoutTail: (r.stdout || \"\").slice(-500),\n stderrTail: (r.stderr || \"\").slice(-500),\n });\n if (r.status !== 0) {\n appendState(\"failed\", { reason: \"npm install failed\", exitCode: r.status });\n try { fs.unlinkSync(LOCK_PATH); } catch {}\n try { fs.unlinkSync(FLAG_PATH); } catch {}\n process.exit(1);\n }\n\n // Step 6: verify new version\n const verifyR = spawnSync(isWin ? \"mneme.cmd\" : \"mneme\", [\"--version\"], {\n shell: isWin, windowsHide: true, encoding: \"utf8\", timeout: 8_000,\n });\n appendState(\"verify-new-version\", {\n exitCode: verifyR.status,\n version: (verifyR.stdout || \"\").trim(),\n });\n\n // Step 7: clear install-incoming flag (lets daemon respawn under new version)\n try { fs.unlinkSync(FLAG_PATH); appendState(\"clear-incoming-flag\"); }\n catch (e) { appendState(\"clear-incoming-flag\", { error: e.message }); }\n\n // Step 8: spawn new daemon (detached). The autonomic_breath_hook will\n // also do this on next CLI call, but explicit start is faster.\n try {\n const child = spawn(isWin ? \"mneme.cmd\" : \"mneme\", [\"daemon\", \"start\"], {\n shell: isWin, windowsHide: true, detached: true, stdio: \"ignore\",\n });\n if (child.unref) child.unref();\n appendState(\"spawn-new-daemon\", { pid: child.pid });\n } catch (e) { appendState(\"spawn-new-daemon\", { error: e.message }); }\n\n // Step 9: release lock + complete\n try { fs.unlinkSync(LOCK_PATH); } catch {}\n appendState(\"release-lock\");\n appendState(\"complete\");\n process.exit(0);\n } catch (e) {\n appendState(\"failed\", { reason: e.message, stack: e.stack ? e.stack.slice(0, 500) : null });\n try { fs.unlinkSync(LOCK_PATH); } catch {}\n process.exit(1);\n }\n}\n\nmain();\n";
|
|
109
|
+
/** Extract the shepherd script to `~/.mneme-global/shepherd/shepherd.cjs`.
|
|
110
|
+
* Idempotent — overwrites existing copy so latest version is always used. */
|
|
111
|
+
export declare function installShepherdScript(): string;
|
|
112
|
+
export { PROTOCOL_VERSION, LOCK_STALENESS_MS };
|
|
113
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shepherd/index.ts"],"names":[],"mappings":"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"}
|