@mmnto/totem 1.21.0 → 1.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ast-classifier.d.ts +72 -4
- package/dist/ast-classifier.d.ts.map +1 -1
- package/dist/ast-classifier.js +155 -30
- package/dist/ast-classifier.js.map +1 -1
- package/dist/ast-classifier.test.js +80 -2
- package/dist/ast-classifier.test.js.map +1 -1
- package/dist/ast-grep-query.d.ts.map +1 -1
- package/dist/ast-grep-query.js +31 -11
- package/dist/ast-grep-query.js.map +1 -1
- package/dist/chunkers/chunker-registry.d.ts +77 -0
- package/dist/chunkers/chunker-registry.d.ts.map +1 -0
- package/dist/chunkers/chunker-registry.js +134 -0
- package/dist/chunkers/chunker-registry.js.map +1 -0
- package/dist/chunkers/chunker-registry.test.d.ts +14 -0
- package/dist/chunkers/chunker-registry.test.d.ts.map +1 -0
- package/dist/chunkers/chunker-registry.test.js +95 -0
- package/dist/chunkers/chunker-registry.test.js.map +1 -0
- package/dist/chunkers/chunker.d.ts +18 -3
- package/dist/chunkers/chunker.d.ts.map +1 -1
- package/dist/chunkers/chunker.js +20 -13
- package/dist/chunkers/chunker.js.map +1 -1
- package/dist/config-schema.d.ts +61 -10
- package/dist/config-schema.d.ts.map +1 -1
- package/dist/config-schema.js +43 -2
- package/dist/config-schema.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/pack-discovery.d.ts +201 -0
- package/dist/pack-discovery.d.ts.map +1 -0
- package/dist/pack-discovery.js +298 -0
- package/dist/pack-discovery.js.map +1 -0
- package/dist/pack-discovery.test.d.ts +17 -0
- package/dist/pack-discovery.test.d.ts.map +1 -0
- package/dist/pack-discovery.test.js +343 -0
- package/dist/pack-discovery.test.js.map +1 -0
- package/dist/pack-manifest-writer.d.ts +88 -0
- package/dist/pack-manifest-writer.d.ts.map +1 -0
- package/dist/pack-manifest-writer.js +162 -0
- package/dist/pack-manifest-writer.js.map +1 -0
- package/dist/pack-manifest-writer.test.d.ts +15 -0
- package/dist/pack-manifest-writer.test.d.ts.map +1 -0
- package/dist/pack-manifest-writer.test.js +184 -0
- package/dist/pack-manifest-writer.test.js.map +1 -0
- package/dist/rule-engine.d.ts.map +1 -1
- package/dist/rule-engine.js +24 -2
- package/dist/rule-engine.js.map +1 -1
- package/dist/rule-engine.test.js +74 -0
- package/dist/rule-engine.test.js.map +1 -1
- package/dist/store/lance-schema.d.ts +3 -3
- package/package.json +3 -1
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the pack discovery substrate (mmnto-ai/totem#1768, ADR-097
|
|
3
|
+
* § 5 Q5 + § 10).
|
|
4
|
+
*
|
|
5
|
+
* Covers invariants 1, 2, 3, 4, 8 from `.totem/specs/pack-substrate-bundle.md`:
|
|
6
|
+
*
|
|
7
|
+
* - Missing manifest → empty packs, no throw.
|
|
8
|
+
* - Malformed manifest → fail loud.
|
|
9
|
+
* - peerDependencies engine version mismatch → structured fail loud.
|
|
10
|
+
* - Re-load after seal → throw.
|
|
11
|
+
* - Pack callback can register chunker + language; lookups return registered values.
|
|
12
|
+
*
|
|
13
|
+
* Uses the `inMemoryPacks` test escape hatch to drive the registration
|
|
14
|
+
* phase without writing fixture pack packages to `node_modules`.
|
|
15
|
+
*/
|
|
16
|
+
import * as fs from 'node:fs';
|
|
17
|
+
import * as os from 'node:os';
|
|
18
|
+
import * as path from 'node:path';
|
|
19
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
|
20
|
+
import { __resetLangRegistryForTests, extensionToLanguage, registeredExtensions, } from './ast-classifier.js';
|
|
21
|
+
import { __resetForTests as __resetChunkerRegistryForTests, lookup as lookupChunker, registeredNames as registeredChunkerStrategies, } from './chunkers/chunker-registry.js';
|
|
22
|
+
import { __resetForTests as __resetPackDiscoveryForTests, isEngineSealed, loadInstalledPacks, } from './pack-discovery.js';
|
|
23
|
+
class FakeChunker {
|
|
24
|
+
strategy = 'rust-ast';
|
|
25
|
+
chunk(_content, _filePath, _type) {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
afterEach(() => {
|
|
30
|
+
// Order matters: pack-discovery's seal flag and registries are
|
|
31
|
+
// independent state containers — reset all three each test so seal
|
|
32
|
+
// state from one case doesn't leak into the next.
|
|
33
|
+
__resetPackDiscoveryForTests();
|
|
34
|
+
__resetChunkerRegistryForTests();
|
|
35
|
+
__resetLangRegistryForTests();
|
|
36
|
+
});
|
|
37
|
+
describe('loadInstalledPacks: missing manifest', () => {
|
|
38
|
+
it('returns empty packs and does not throw when installed-packs.json is absent', () => {
|
|
39
|
+
const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'pack-discovery-test-'));
|
|
40
|
+
try {
|
|
41
|
+
const packs = loadInstalledPacks({ projectRoot: tmpRoot, totemDir: '.totem' });
|
|
42
|
+
expect(packs).toEqual([]);
|
|
43
|
+
expect(isEngineSealed()).toBe(true);
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
fs.rmSync(tmpRoot, { recursive: true, force: true });
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
describe('loadInstalledPacks: malformed manifest', () => {
|
|
51
|
+
it('throws structured error on invalid JSON', () => {
|
|
52
|
+
const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'pack-discovery-test-'));
|
|
53
|
+
try {
|
|
54
|
+
const totemDir = path.join(tmpRoot, '.totem');
|
|
55
|
+
fs.mkdirSync(totemDir, { recursive: true });
|
|
56
|
+
fs.writeFileSync(path.join(totemDir, 'installed-packs.json'), '{ this is not json');
|
|
57
|
+
expect(() => loadInstalledPacks({ projectRoot: tmpRoot, totemDir: '.totem' })).toThrowError(/not valid JSON/);
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
fs.rmSync(tmpRoot, { recursive: true, force: true });
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
it('throws structured error on schema validation failure', () => {
|
|
64
|
+
const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'pack-discovery-test-'));
|
|
65
|
+
try {
|
|
66
|
+
const totemDir = path.join(tmpRoot, '.totem');
|
|
67
|
+
fs.mkdirSync(totemDir, { recursive: true });
|
|
68
|
+
fs.writeFileSync(path.join(totemDir, 'installed-packs.json'), JSON.stringify({ version: 99, packs: [] }));
|
|
69
|
+
expect(() => loadInstalledPacks({ projectRoot: tmpRoot, totemDir: '.totem' })).toThrowError(/failed schema validation/);
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
fs.rmSync(tmpRoot, { recursive: true, force: true });
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
it('throws on unknown sibling keys (strict schema)', () => {
|
|
76
|
+
const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'pack-discovery-test-'));
|
|
77
|
+
try {
|
|
78
|
+
const totemDir = path.join(tmpRoot, '.totem');
|
|
79
|
+
fs.mkdirSync(totemDir, { recursive: true });
|
|
80
|
+
fs.writeFileSync(path.join(totemDir, 'installed-packs.json'), JSON.stringify({ version: 1, packs: [], extra: 'oops' }));
|
|
81
|
+
expect(() => loadInstalledPacks({ projectRoot: tmpRoot, totemDir: '.totem' })).toThrowError(/failed schema validation/);
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
fs.rmSync(tmpRoot, { recursive: true, force: true });
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
it('rejects manifest with duplicate pack names at the schema boundary', () => {
|
|
88
|
+
const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'pack-discovery-test-'));
|
|
89
|
+
try {
|
|
90
|
+
const totemDir = path.join(tmpRoot, '.totem');
|
|
91
|
+
fs.mkdirSync(totemDir, { recursive: true });
|
|
92
|
+
fs.writeFileSync(path.join(totemDir, 'installed-packs.json'), JSON.stringify({
|
|
93
|
+
version: 1,
|
|
94
|
+
packs: [
|
|
95
|
+
{
|
|
96
|
+
name: '@totem/pack-rust',
|
|
97
|
+
resolvedPath: path.resolve('/abs/a'),
|
|
98
|
+
declaredEngineRange: '^1.19.0',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: '@totem/pack-rust',
|
|
102
|
+
resolvedPath: path.resolve('/abs/b'),
|
|
103
|
+
declaredEngineRange: '^1.19.0',
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
}));
|
|
107
|
+
expect(() => loadInstalledPacks({ projectRoot: tmpRoot, totemDir: '.totem' })).toThrowError(/duplicate pack entry '@totem\/pack-rust'/);
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
fs.rmSync(tmpRoot, { recursive: true, force: true });
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
it('rejects manifest entries with a relative resolvedPath at the schema boundary', () => {
|
|
114
|
+
const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'pack-discovery-test-'));
|
|
115
|
+
try {
|
|
116
|
+
const totemDir = path.join(tmpRoot, '.totem');
|
|
117
|
+
fs.mkdirSync(totemDir, { recursive: true });
|
|
118
|
+
fs.writeFileSync(path.join(totemDir, 'installed-packs.json'), JSON.stringify({
|
|
119
|
+
version: 1,
|
|
120
|
+
packs: [
|
|
121
|
+
{
|
|
122
|
+
name: '@totem/pack-relative',
|
|
123
|
+
resolvedPath: 'node_modules/@totem/pack-relative',
|
|
124
|
+
declaredEngineRange: '^1.19.0',
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
}));
|
|
128
|
+
expect(() => loadInstalledPacks({ projectRoot: tmpRoot, totemDir: '.totem' })).toThrowError(/resolvedPath must be an absolute path/);
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
fs.rmSync(tmpRoot, { recursive: true, force: true });
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
describe('loadInstalledPacks: peerDependencies engine version mismatch', () => {
|
|
136
|
+
it('throws structured error naming pack name + declared range + actual engine version', () => {
|
|
137
|
+
const fakeCallback = () => { };
|
|
138
|
+
const fakePack = {
|
|
139
|
+
name: '@totem/pack-fake',
|
|
140
|
+
resolvedPath: '/fake/path',
|
|
141
|
+
declaredEngineRange: '^2.0.0',
|
|
142
|
+
};
|
|
143
|
+
expect(() => loadInstalledPacks({
|
|
144
|
+
engineVersion: '1.21.0',
|
|
145
|
+
inMemoryPacks: [{ pack: fakePack, callback: fakeCallback }],
|
|
146
|
+
})).toThrowError(/Pack '@totem\/pack-fake' requires @mmnto\/totem '\^2\.0\.0'.*running engine is 1\.21\.0/);
|
|
147
|
+
});
|
|
148
|
+
it('passes when engine version satisfies declared range', () => {
|
|
149
|
+
const fakeCallback = () => { };
|
|
150
|
+
const fakePack = {
|
|
151
|
+
name: '@totem/pack-fake',
|
|
152
|
+
resolvedPath: '/fake/path',
|
|
153
|
+
declaredEngineRange: '^1.19.0',
|
|
154
|
+
};
|
|
155
|
+
const packs = loadInstalledPacks({
|
|
156
|
+
engineVersion: '1.21.0',
|
|
157
|
+
inMemoryPacks: [{ pack: fakePack, callback: fakeCallback }],
|
|
158
|
+
});
|
|
159
|
+
expect(packs).toHaveLength(1);
|
|
160
|
+
expect(packs[0]?.name).toBe('@totem/pack-fake');
|
|
161
|
+
});
|
|
162
|
+
it('throws when declared range is invalid semver', () => {
|
|
163
|
+
const fakeCallback = () => { };
|
|
164
|
+
const fakePack = {
|
|
165
|
+
name: '@totem/pack-fake',
|
|
166
|
+
resolvedPath: '/fake/path',
|
|
167
|
+
declaredEngineRange: 'not-a-semver-range',
|
|
168
|
+
};
|
|
169
|
+
expect(() => loadInstalledPacks({
|
|
170
|
+
engineVersion: '1.21.0',
|
|
171
|
+
inMemoryPacks: [{ pack: fakePack, callback: fakeCallback }],
|
|
172
|
+
})).toThrowError(/not a valid semver range/);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
describe('loadInstalledPacks: re-load after seal', () => {
|
|
176
|
+
it('throws when called twice', () => {
|
|
177
|
+
loadInstalledPacks({ inMemoryPacks: [] });
|
|
178
|
+
expect(() => loadInstalledPacks({ inMemoryPacks: [] })).toThrowError(/called after engine seal/);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
describe('loadInstalledPacks: pack callback registration', () => {
|
|
182
|
+
it('invokes pack callback with PackRegistrationAPI; lookups return registered values', () => {
|
|
183
|
+
const fakeCallback = (api) => {
|
|
184
|
+
api.registerChunkStrategy('rust-ast', FakeChunker);
|
|
185
|
+
api.registerLanguage('.rs', 'rust', () => '/fake/tree-sitter-rust.wasm');
|
|
186
|
+
};
|
|
187
|
+
const fakePack = {
|
|
188
|
+
name: '@totem/pack-rust-architecture',
|
|
189
|
+
resolvedPath: '/fake/path',
|
|
190
|
+
declaredEngineRange: '^1.19.0',
|
|
191
|
+
};
|
|
192
|
+
loadInstalledPacks({
|
|
193
|
+
engineVersion: '1.21.0',
|
|
194
|
+
inMemoryPacks: [{ pack: fakePack, callback: fakeCallback }],
|
|
195
|
+
});
|
|
196
|
+
expect(lookupChunker('rust-ast')).toBe(FakeChunker);
|
|
197
|
+
expect(registeredChunkerStrategies()).toContain('rust-ast');
|
|
198
|
+
expect(extensionToLanguage('.rs')).toBe('rust');
|
|
199
|
+
expect(registeredExtensions()).toContain('.rs');
|
|
200
|
+
});
|
|
201
|
+
it('seals both registries after every callback returns', () => {
|
|
202
|
+
const fakeCallback = (api) => {
|
|
203
|
+
api.registerChunkStrategy('rust-ast', FakeChunker);
|
|
204
|
+
};
|
|
205
|
+
const fakePack = {
|
|
206
|
+
name: '@totem/pack-rust-architecture',
|
|
207
|
+
resolvedPath: '/fake/path',
|
|
208
|
+
declaredEngineRange: '^1.19.0',
|
|
209
|
+
};
|
|
210
|
+
loadInstalledPacks({
|
|
211
|
+
engineVersion: '1.21.0',
|
|
212
|
+
inMemoryPacks: [{ pack: fakePack, callback: fakeCallback }],
|
|
213
|
+
});
|
|
214
|
+
expect(isEngineSealed()).toBe(true);
|
|
215
|
+
});
|
|
216
|
+
it('rejects an async (Promise-returning) registration callback before sealing', () => {
|
|
217
|
+
const asyncCallback = (async (api) => {
|
|
218
|
+
api.registerChunkStrategy('async-strat', FakeChunker);
|
|
219
|
+
});
|
|
220
|
+
const fakePack = {
|
|
221
|
+
name: '@totem/pack-async',
|
|
222
|
+
resolvedPath: '/fake/path',
|
|
223
|
+
declaredEngineRange: '^1.19.0',
|
|
224
|
+
};
|
|
225
|
+
let caught;
|
|
226
|
+
try {
|
|
227
|
+
loadInstalledPacks({
|
|
228
|
+
engineVersion: '1.21.0',
|
|
229
|
+
inMemoryPacks: [{ pack: fakePack, callback: asyncCallback }],
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
catch (err) {
|
|
233
|
+
caught = err;
|
|
234
|
+
}
|
|
235
|
+
expect(caught).toBeInstanceOf(Error);
|
|
236
|
+
expect(caught.message).toMatch(/registration must be synchronous/);
|
|
237
|
+
expect(caught.message).toMatch(/ADR-097 § 5 Q5/);
|
|
238
|
+
expect(isEngineSealed()).toBe(false);
|
|
239
|
+
});
|
|
240
|
+
it('throws and names the pack when callback throws', () => {
|
|
241
|
+
const errorThrowingCallback = () => {
|
|
242
|
+
throw new Error('pack-side bug');
|
|
243
|
+
};
|
|
244
|
+
const fakePack = {
|
|
245
|
+
name: '@totem/pack-broken',
|
|
246
|
+
resolvedPath: '/fake/path',
|
|
247
|
+
declaredEngineRange: '^1.19.0',
|
|
248
|
+
};
|
|
249
|
+
let caught;
|
|
250
|
+
try {
|
|
251
|
+
loadInstalledPacks({
|
|
252
|
+
engineVersion: '1.21.0',
|
|
253
|
+
inMemoryPacks: [{ pack: fakePack, callback: errorThrowingCallback }],
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
catch (err) {
|
|
257
|
+
caught = err;
|
|
258
|
+
}
|
|
259
|
+
expect(caught).toBeInstanceOf(Error);
|
|
260
|
+
const outer = caught;
|
|
261
|
+
expect(outer.message).toMatch(/Pack '@totem\/pack-broken' registration callback threw/);
|
|
262
|
+
expect(outer.message).toMatch(/must be fixed or removed/);
|
|
263
|
+
expect(outer.cause).toBeInstanceOf(Error);
|
|
264
|
+
expect(outer.cause.message).toBe('pack-side bug');
|
|
265
|
+
});
|
|
266
|
+
it('two packs registering same chunk strategy: second fails loud', () => {
|
|
267
|
+
const callback1 = (api) => {
|
|
268
|
+
api.registerChunkStrategy('shared', FakeChunker);
|
|
269
|
+
};
|
|
270
|
+
const callback2 = (api) => {
|
|
271
|
+
api.registerChunkStrategy('shared', FakeChunker);
|
|
272
|
+
};
|
|
273
|
+
let caught;
|
|
274
|
+
try {
|
|
275
|
+
loadInstalledPacks({
|
|
276
|
+
engineVersion: '1.21.0',
|
|
277
|
+
inMemoryPacks: [
|
|
278
|
+
{
|
|
279
|
+
pack: {
|
|
280
|
+
name: '@totem/pack-a',
|
|
281
|
+
resolvedPath: '/a',
|
|
282
|
+
declaredEngineRange: '^1.19.0',
|
|
283
|
+
},
|
|
284
|
+
callback: callback1,
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
pack: {
|
|
288
|
+
name: '@totem/pack-b',
|
|
289
|
+
resolvedPath: '/b',
|
|
290
|
+
declaredEngineRange: '^1.19.0',
|
|
291
|
+
},
|
|
292
|
+
callback: callback2,
|
|
293
|
+
},
|
|
294
|
+
],
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
catch (err) {
|
|
298
|
+
caught = err;
|
|
299
|
+
}
|
|
300
|
+
expect(caught).toBeInstanceOf(Error);
|
|
301
|
+
expect(caught.message).toMatch(/Pack '@totem\/pack-b' registration callback threw/);
|
|
302
|
+
expect(caught.cause.message).toMatch(/already registered/);
|
|
303
|
+
});
|
|
304
|
+
it('two packs registering same extension to different langs: second fails loud', () => {
|
|
305
|
+
const callback1 = (api) => {
|
|
306
|
+
api.registerLanguage('.shared', 'lang-a', () => '/a.wasm');
|
|
307
|
+
};
|
|
308
|
+
const callback2 = (api) => {
|
|
309
|
+
api.registerLanguage('.shared', 'lang-b', () => '/b.wasm');
|
|
310
|
+
};
|
|
311
|
+
let caught;
|
|
312
|
+
try {
|
|
313
|
+
loadInstalledPacks({
|
|
314
|
+
engineVersion: '1.21.0',
|
|
315
|
+
inMemoryPacks: [
|
|
316
|
+
{
|
|
317
|
+
pack: {
|
|
318
|
+
name: '@totem/pack-a',
|
|
319
|
+
resolvedPath: '/a',
|
|
320
|
+
declaredEngineRange: '^1.19.0',
|
|
321
|
+
},
|
|
322
|
+
callback: callback1,
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
pack: {
|
|
326
|
+
name: '@totem/pack-b',
|
|
327
|
+
resolvedPath: '/b',
|
|
328
|
+
declaredEngineRange: '^1.19.0',
|
|
329
|
+
},
|
|
330
|
+
callback: callback2,
|
|
331
|
+
},
|
|
332
|
+
],
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
catch (err) {
|
|
336
|
+
caught = err;
|
|
337
|
+
}
|
|
338
|
+
expect(caught).toBeInstanceOf(Error);
|
|
339
|
+
expect(caught.message).toMatch(/Pack '@totem\/pack-b' registration callback threw/);
|
|
340
|
+
expect(caught.cause.message).toMatch(/already registered to language/);
|
|
341
|
+
});
|
|
342
|
+
});
|
|
343
|
+
//# sourceMappingURL=pack-discovery.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack-discovery.test.js","sourceRoot":"","sources":["../src/pack-discovery.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `installed-packs.json` writer (mmnto-ai/totem#1768, Step 4).
|
|
3
|
+
*
|
|
4
|
+
* Walks two source surfaces — the consumer's `package.json` dependencies
|
|
5
|
+
* for `@totem/pack-*` entries, and the consumer's `totem.config.ts`
|
|
6
|
+
* `extends` array — deduplicates, resolves each pack's installed path
|
|
7
|
+
* via npm/pnpm semantics, and writes `.totem/installed-packs.json` for
|
|
8
|
+
* `pack-discovery.ts:loadInstalledPacks()` to consume at boot.
|
|
9
|
+
*
|
|
10
|
+
* Mismatch handling (ADR-097 § 5 Q4 + Open Question 4 disposition):
|
|
11
|
+
* - In both surfaces: union, no warning.
|
|
12
|
+
* - In `extends` only (declared but not resolvable via npm): emit a
|
|
13
|
+
* warning naming the pack; skip from the manifest. Consumer must
|
|
14
|
+
* `pnpm add` the pack to make it work.
|
|
15
|
+
* - In `package.json` only (resolvable but not declared in extends):
|
|
16
|
+
* emit a warning; skip from the manifest. Pack-merge only consumes
|
|
17
|
+
* `extends`-declared packs; including the dep-only entry would be
|
|
18
|
+
* misleading.
|
|
19
|
+
*
|
|
20
|
+
* Atomic write semantics: the writer goes through a temp file +
|
|
21
|
+
* rename, mirroring `writeReviewExtensionsFile` (mmnto-ai/totem#1527).
|
|
22
|
+
*
|
|
23
|
+
* Filesystem access happens at the CLI boundary (this module is invoked
|
|
24
|
+
* by `syncCommand`); the resolver itself takes paths + content as
|
|
25
|
+
* inputs so tests can drive it without disk I/O.
|
|
26
|
+
*/
|
|
27
|
+
import type { TotemConfig } from './config-schema.js';
|
|
28
|
+
import type { InstalledPacksManifest } from './pack-discovery.js';
|
|
29
|
+
export interface PackResolutionWarning {
|
|
30
|
+
/** Pack name surfaced in the warning. */
|
|
31
|
+
readonly name: string;
|
|
32
|
+
/**
|
|
33
|
+
* Why the pack didn't make it to the manifest. Two shapes:
|
|
34
|
+
*
|
|
35
|
+
* - `dep-only`: present in package.json but not declared in
|
|
36
|
+
* `totem.config.ts` `extends`. Skipped because pack-merge only
|
|
37
|
+
* consumes `extends`-declared packs.
|
|
38
|
+
* - `extends-only`: declared in `extends` but not installed
|
|
39
|
+
* (`require.resolve` failed). Skipped because the engine cannot
|
|
40
|
+
* load it.
|
|
41
|
+
* - `not-a-pack`: present somewhere but doesn't expose a `register`
|
|
42
|
+
* callback (default export or named `register` function). Skipped
|
|
43
|
+
* because pack-discovery would throw on first attempt.
|
|
44
|
+
*/
|
|
45
|
+
readonly reason: 'dep-only' | 'extends-only' | 'not-a-pack';
|
|
46
|
+
}
|
|
47
|
+
export interface PackResolutionResult {
|
|
48
|
+
/** Packs that landed in the manifest (sorted by name). */
|
|
49
|
+
readonly resolved: InstalledPacksManifest['packs'];
|
|
50
|
+
/** Per-pack warnings for the consumer (sorted by name). */
|
|
51
|
+
readonly warnings: readonly PackResolutionWarning[];
|
|
52
|
+
}
|
|
53
|
+
export interface ResolveInstalledPacksInput {
|
|
54
|
+
/** Project root (where `package.json` lives). */
|
|
55
|
+
readonly projectRoot: string;
|
|
56
|
+
/** Loaded totem config (read for `extends`). */
|
|
57
|
+
readonly config: TotemConfig;
|
|
58
|
+
/**
|
|
59
|
+
* Optional override for the package.json read. Tests pass a synthetic
|
|
60
|
+
* dependencies map; production callers leave it undefined and the
|
|
61
|
+
* function reads `<projectRoot>/package.json`.
|
|
62
|
+
*/
|
|
63
|
+
readonly packageJsonDeps?: Readonly<Record<string, string>>;
|
|
64
|
+
/**
|
|
65
|
+
* Optional override for the require resolver. Tests stub this to
|
|
66
|
+
* resolve fixture packs without writing to `node_modules`; production
|
|
67
|
+
* callers use the default which delegates to `createRequire`.
|
|
68
|
+
*/
|
|
69
|
+
readonly resolvePackPath?: (name: string, fromDir: string) => string | undefined;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Compute the deduplicated union of `package.json` `@totem/pack-*` deps
|
|
73
|
+
* and `totem.config.ts` `extends` entries. Returns the manifest payload
|
|
74
|
+
* shape ready for `installed-packs.json` plus per-pack warnings for any
|
|
75
|
+
* surface mismatch.
|
|
76
|
+
*
|
|
77
|
+
* Pure function — no filesystem write. The CLI integration calls
|
|
78
|
+
* `writeInstalledPacksManifest()` to persist.
|
|
79
|
+
*/
|
|
80
|
+
export declare function resolveInstalledPacks(input: ResolveInstalledPacksInput): PackResolutionResult;
|
|
81
|
+
/**
|
|
82
|
+
* Atomically write `<totemDir>/installed-packs.json` with the given
|
|
83
|
+
* manifest payload. Mirrors `writeReviewExtensionsFile` semantics: temp
|
|
84
|
+
* file + rename so a concurrent boot-time read sees the old or new
|
|
85
|
+
* contents, never a partial write.
|
|
86
|
+
*/
|
|
87
|
+
export declare function writeInstalledPacksManifest(totemDirAbs: string, manifest: InstalledPacksManifest): string;
|
|
88
|
+
//# sourceMappingURL=pack-manifest-writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack-manifest-writer.d.ts","sourceRoot":"","sources":["../src/pack-manifest-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAIlE,MAAM,WAAW,qBAAqB;IACpC,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,cAAc,GAAG,YAAY,CAAC;CAC7D;AAED,MAAM,WAAW,oBAAoB;IACnC,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAC,OAAO,CAAC,CAAC;IACnD,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACrD;AAED,MAAM,WAAW,0BAA0B;IACzC,iDAAiD;IACjD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,gDAAgD;IAChD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5D;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CAClF;AAMD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,GAAG,oBAAoB,CAkD7F;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,sBAAsB,GAC/B,MAAM,CASR"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `installed-packs.json` writer (mmnto-ai/totem#1768, Step 4).
|
|
3
|
+
*
|
|
4
|
+
* Walks two source surfaces — the consumer's `package.json` dependencies
|
|
5
|
+
* for `@totem/pack-*` entries, and the consumer's `totem.config.ts`
|
|
6
|
+
* `extends` array — deduplicates, resolves each pack's installed path
|
|
7
|
+
* via npm/pnpm semantics, and writes `.totem/installed-packs.json` for
|
|
8
|
+
* `pack-discovery.ts:loadInstalledPacks()` to consume at boot.
|
|
9
|
+
*
|
|
10
|
+
* Mismatch handling (ADR-097 § 5 Q4 + Open Question 4 disposition):
|
|
11
|
+
* - In both surfaces: union, no warning.
|
|
12
|
+
* - In `extends` only (declared but not resolvable via npm): emit a
|
|
13
|
+
* warning naming the pack; skip from the manifest. Consumer must
|
|
14
|
+
* `pnpm add` the pack to make it work.
|
|
15
|
+
* - In `package.json` only (resolvable but not declared in extends):
|
|
16
|
+
* emit a warning; skip from the manifest. Pack-merge only consumes
|
|
17
|
+
* `extends`-declared packs; including the dep-only entry would be
|
|
18
|
+
* misleading.
|
|
19
|
+
*
|
|
20
|
+
* Atomic write semantics: the writer goes through a temp file +
|
|
21
|
+
* rename, mirroring `writeReviewExtensionsFile` (mmnto-ai/totem#1527).
|
|
22
|
+
*
|
|
23
|
+
* Filesystem access happens at the CLI boundary (this module is invoked
|
|
24
|
+
* by `syncCommand`); the resolver itself takes paths + content as
|
|
25
|
+
* inputs so tests can drive it without disk I/O.
|
|
26
|
+
*/
|
|
27
|
+
import * as fs from 'node:fs';
|
|
28
|
+
import { createRequire } from 'node:module';
|
|
29
|
+
import * as path from 'node:path';
|
|
30
|
+
// ─── Resolver ───────────────────────────────────────
|
|
31
|
+
const PACK_NAME_PREFIX = '@totem/pack-';
|
|
32
|
+
/**
|
|
33
|
+
* Compute the deduplicated union of `package.json` `@totem/pack-*` deps
|
|
34
|
+
* and `totem.config.ts` `extends` entries. Returns the manifest payload
|
|
35
|
+
* shape ready for `installed-packs.json` plus per-pack warnings for any
|
|
36
|
+
* surface mismatch.
|
|
37
|
+
*
|
|
38
|
+
* Pure function — no filesystem write. The CLI integration calls
|
|
39
|
+
* `writeInstalledPacksManifest()` to persist.
|
|
40
|
+
*/
|
|
41
|
+
export function resolveInstalledPacks(input) {
|
|
42
|
+
const deps = input.packageJsonDeps ?? readPackageJsonDeps(input.projectRoot);
|
|
43
|
+
const extendsList = (input.config.extends ?? []).filter((name) => name.startsWith(PACK_NAME_PREFIX));
|
|
44
|
+
const depPackNames = Object.keys(deps).filter((name) => name.startsWith(PACK_NAME_PREFIX)); // totem-context: Object.keys() returns strings; not fileGlobs ast-grep object form
|
|
45
|
+
const extendsSet = new Set(extendsList);
|
|
46
|
+
const depsSet = new Set(depPackNames);
|
|
47
|
+
const union = new Set([...extendsSet, ...depsSet]);
|
|
48
|
+
const warnings = [];
|
|
49
|
+
const resolved = [];
|
|
50
|
+
for (const name of [...union].sort()) {
|
|
51
|
+
if (!extendsSet.has(name)) {
|
|
52
|
+
// Resolvable dep that the consumer hasn't opted into via `extends`.
|
|
53
|
+
// Pack-merge only consumes extends-declared packs, so this pack
|
|
54
|
+
// would never have its rules merged anyway. Skip with a warning.
|
|
55
|
+
warnings.push({ name, reason: 'dep-only' });
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (!depsSet.has(name)) {
|
|
59
|
+
// Declared in extends but not installed via package manager.
|
|
60
|
+
// Cannot resolve a path; skip with a warning.
|
|
61
|
+
warnings.push({ name, reason: 'extends-only' });
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const resolver = input.resolvePackPath ?? defaultResolvePackPath;
|
|
65
|
+
const resolvedPath = resolver(name, input.projectRoot);
|
|
66
|
+
if (!resolvedPath) {
|
|
67
|
+
warnings.push({ name, reason: 'extends-only' });
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const declaredEngineRange = readPeerEngineRange(resolvedPath);
|
|
71
|
+
if (!declaredEngineRange) {
|
|
72
|
+
warnings.push({ name, reason: 'not-a-pack' });
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
resolved.push({
|
|
76
|
+
name,
|
|
77
|
+
resolvedPath,
|
|
78
|
+
declaredEngineRange,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return { resolved, warnings };
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Atomically write `<totemDir>/installed-packs.json` with the given
|
|
85
|
+
* manifest payload. Mirrors `writeReviewExtensionsFile` semantics: temp
|
|
86
|
+
* file + rename so a concurrent boot-time read sees the old or new
|
|
87
|
+
* contents, never a partial write.
|
|
88
|
+
*/
|
|
89
|
+
export function writeInstalledPacksManifest(totemDirAbs, manifest) {
|
|
90
|
+
if (!fs.existsSync(totemDirAbs)) {
|
|
91
|
+
fs.mkdirSync(totemDirAbs, { recursive: true });
|
|
92
|
+
}
|
|
93
|
+
const finalPath = path.join(totemDirAbs, 'installed-packs.json');
|
|
94
|
+
const tmpPath = finalPath + '.tmp';
|
|
95
|
+
fs.writeFileSync(tmpPath, JSON.stringify(manifest, null, 2) + '\n', 'utf-8');
|
|
96
|
+
fs.renameSync(tmpPath, finalPath);
|
|
97
|
+
return finalPath;
|
|
98
|
+
}
|
|
99
|
+
// ─── Internal helpers ───────────────────────────────
|
|
100
|
+
function readPackageJsonDeps(projectRoot) {
|
|
101
|
+
const pkgPath = path.join(projectRoot, 'package.json');
|
|
102
|
+
if (!fs.existsSync(pkgPath))
|
|
103
|
+
return {};
|
|
104
|
+
let parsed;
|
|
105
|
+
// totem-context: intentional cleanup — package.json missing/corrupt is non-fatal to sync; treat as no deps
|
|
106
|
+
try {
|
|
107
|
+
parsed = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')); // totem-context: sync read at boot; sync command is itself synchronous CLI top-level
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return {};
|
|
111
|
+
}
|
|
112
|
+
if (typeof parsed !== 'object' || parsed === null)
|
|
113
|
+
return {};
|
|
114
|
+
const obj = parsed;
|
|
115
|
+
const out = {};
|
|
116
|
+
for (const field of ['dependencies', 'devDependencies']) {
|
|
117
|
+
const section = obj[field];
|
|
118
|
+
if (typeof section !== 'object' || section === null)
|
|
119
|
+
continue;
|
|
120
|
+
for (const [name, value] of Object.entries(section)) {
|
|
121
|
+
if (typeof value === 'string')
|
|
122
|
+
out[name] = value;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return out;
|
|
126
|
+
}
|
|
127
|
+
function defaultResolvePackPath(name, fromDir) {
|
|
128
|
+
// We resolve from the project root rather than from this module — packs
|
|
129
|
+
// live in the consumer's node_modules, not core's.
|
|
130
|
+
const require = createRequire(path.join(fromDir, 'package.json'));
|
|
131
|
+
try {
|
|
132
|
+
// Resolve to the package's package.json so the directory containing it
|
|
133
|
+
// is the pack's package root. require.resolve(name) would land on the
|
|
134
|
+
// package's `main` entry, which isn't what pack-discovery wants.
|
|
135
|
+
const pkgJsonPath = require.resolve(`${name}/package.json`);
|
|
136
|
+
return path.dirname(pkgJsonPath); // totem-context: intentional cleanup — unresolvable pack returns undefined to flow into the `extends-only` warning path
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function readPeerEngineRange(packResolvedPath) {
|
|
143
|
+
const pkgPath = path.join(packResolvedPath, 'package.json');
|
|
144
|
+
if (!fs.existsSync(pkgPath))
|
|
145
|
+
return undefined;
|
|
146
|
+
let parsed;
|
|
147
|
+
// totem-context: intentional cleanup — corrupted pack package.json returns undefined to flow into the `not-a-pack` warning path
|
|
148
|
+
try {
|
|
149
|
+
parsed = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')); // totem-context: sync read at boot; sync command is itself synchronous CLI top-level
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
if (typeof parsed !== 'object' || parsed === null)
|
|
155
|
+
return undefined;
|
|
156
|
+
const peer = parsed.peerDependencies; // totem-context: parsed was narrowed via `typeof !== 'object' || === null` guard above; the cast is for index access into already-validated JSON
|
|
157
|
+
if (typeof peer !== 'object' || peer === null)
|
|
158
|
+
return undefined;
|
|
159
|
+
const range = peer['@mmnto/totem']; // totem-context: peer was narrowed via `typeof !== 'object' || === null` guard above; the cast is for index access; result is runtime-checked via `typeof range === 'string'` below
|
|
160
|
+
return typeof range === 'string' ? range : undefined;
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=pack-manifest-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack-manifest-writer.js","sourceRoot":"","sources":["../src/pack-manifest-writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for pack manifest resolution + writer (mmnto-ai/totem#1768
|
|
3
|
+
* Step 4, Q4 disposition).
|
|
4
|
+
*
|
|
5
|
+
* Covers invariant 18 from `.totem/specs/pack-substrate-bundle.md`:
|
|
6
|
+
*
|
|
7
|
+
* - Resolves a pack present in BOTH `package.json` deps AND
|
|
8
|
+
* `totem.config.ts` `extends` → manifest entry, no warning.
|
|
9
|
+
* - Resolves a pack only in deps → no manifest entry, `dep-only` warning.
|
|
10
|
+
* - Resolves a pack only in extends → no manifest entry, `extends-only` warning.
|
|
11
|
+
* - Pack without `peerDependencies['@mmnto/totem']` → `not-a-pack` warning.
|
|
12
|
+
* - Atomic write produces a stable JSON file.
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=pack-manifest-writer.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack-manifest-writer.test.d.ts","sourceRoot":"","sources":["../src/pack-manifest-writer.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
|