@mmnto/totem 1.20.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.
Files changed (65) hide show
  1. package/dist/ast-classifier.d.ts +72 -4
  2. package/dist/ast-classifier.d.ts.map +1 -1
  3. package/dist/ast-classifier.js +155 -30
  4. package/dist/ast-classifier.js.map +1 -1
  5. package/dist/ast-classifier.test.js +80 -2
  6. package/dist/ast-classifier.test.js.map +1 -1
  7. package/dist/ast-grep-query.d.ts.map +1 -1
  8. package/dist/ast-grep-query.js +31 -11
  9. package/dist/ast-grep-query.js.map +1 -1
  10. package/dist/chunkers/chunker-registry.d.ts +77 -0
  11. package/dist/chunkers/chunker-registry.d.ts.map +1 -0
  12. package/dist/chunkers/chunker-registry.js +134 -0
  13. package/dist/chunkers/chunker-registry.js.map +1 -0
  14. package/dist/chunkers/chunker-registry.test.d.ts +14 -0
  15. package/dist/chunkers/chunker-registry.test.d.ts.map +1 -0
  16. package/dist/chunkers/chunker-registry.test.js +95 -0
  17. package/dist/chunkers/chunker-registry.test.js.map +1 -0
  18. package/dist/chunkers/chunker.d.ts +18 -3
  19. package/dist/chunkers/chunker.d.ts.map +1 -1
  20. package/dist/chunkers/chunker.js +20 -13
  21. package/dist/chunkers/chunker.js.map +1 -1
  22. package/dist/compiler.d.ts +1 -1
  23. package/dist/compiler.d.ts.map +1 -1
  24. package/dist/compiler.js +1 -1
  25. package/dist/compiler.js.map +1 -1
  26. package/dist/config-schema.d.ts +193 -10
  27. package/dist/config-schema.d.ts.map +1 -1
  28. package/dist/config-schema.js +87 -2
  29. package/dist/config-schema.js.map +1 -1
  30. package/dist/config-schema.test.js +122 -0
  31. package/dist/config-schema.test.js.map +1 -1
  32. package/dist/index.d.ts +9 -3
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +10 -2
  35. package/dist/index.js.map +1 -1
  36. package/dist/pack-discovery.d.ts +201 -0
  37. package/dist/pack-discovery.d.ts.map +1 -0
  38. package/dist/pack-discovery.js +298 -0
  39. package/dist/pack-discovery.js.map +1 -0
  40. package/dist/pack-discovery.test.d.ts +17 -0
  41. package/dist/pack-discovery.test.d.ts.map +1 -0
  42. package/dist/pack-discovery.test.js +343 -0
  43. package/dist/pack-discovery.test.js.map +1 -0
  44. package/dist/pack-manifest-writer.d.ts +88 -0
  45. package/dist/pack-manifest-writer.d.ts.map +1 -0
  46. package/dist/pack-manifest-writer.js +162 -0
  47. package/dist/pack-manifest-writer.js.map +1 -0
  48. package/dist/pack-manifest-writer.test.d.ts +15 -0
  49. package/dist/pack-manifest-writer.test.d.ts.map +1 -0
  50. package/dist/pack-manifest-writer.test.js +184 -0
  51. package/dist/pack-manifest-writer.test.js.map +1 -0
  52. package/dist/rule-engine.d.ts +11 -0
  53. package/dist/rule-engine.d.ts.map +1 -1
  54. package/dist/rule-engine.js +60 -6
  55. package/dist/rule-engine.js.map +1 -1
  56. package/dist/rule-engine.test.js +116 -0
  57. package/dist/rule-engine.test.js.map +1 -1
  58. package/dist/stage4-verifier.d.ts +94 -1
  59. package/dist/stage4-verifier.d.ts.map +1 -1
  60. package/dist/stage4-verifier.js +139 -71
  61. package/dist/stage4-verifier.js.map +1 -1
  62. package/dist/stage4-verifier.test.js +215 -4
  63. package/dist/stage4-verifier.test.js.map +1 -1
  64. package/dist/store/lance-schema.d.ts +3 -3
  65. package/package.json +3 -1
@@ -0,0 +1,298 @@
1
+ /**
2
+ * Pack discovery substrate (ADR-097 § 5 Q5 + § 10, mmnto-ai/totem#1768).
3
+ *
4
+ * Reads `.totem/installed-packs.json` synchronously at engine boot,
5
+ * resolves each registered pack's registration callback module, and
6
+ * invokes the callback with a `PackRegistrationAPI` so the pack can
7
+ * register its ChunkStrategy + ast-grep Lang + WASM grammar entries
8
+ * before the engine seals.
9
+ *
10
+ * Sealing happens at the end of `loadInstalledPacks()` after every pack
11
+ * callback has returned. Once sealed, subsequent `register()` calls on
12
+ * either registry throw — see `chunker-registry.ts:seal()` and
13
+ * `ast-classifier.ts:sealLangRegistry()`.
14
+ *
15
+ * The seal is the only synchronization boundary between the registration
16
+ * phase and the runtime phase. CLI commands invoke `loadInstalledPacks()`
17
+ * immediately after config load and before any other engine surface, so
18
+ * pack registration is always complete before any chunker / language
19
+ * lookup happens.
20
+ *
21
+ * Failure-mode discipline (Tenet 4):
22
+ * - Missing manifest: silent (treated as no packs); user runs `totem sync`
23
+ * to generate.
24
+ * - Malformed manifest: hard error.
25
+ * - Pack require throws: hard error.
26
+ * - peerDependencies engine version mismatch: structured error per ADR-097
27
+ * Q6.
28
+ * - Pack callback throws: hard error.
29
+ */
30
+ import * as fs from 'node:fs';
31
+ import { createRequire } from 'node:module';
32
+ import * as path from 'node:path';
33
+ import * as semver from 'semver';
34
+ import { z } from 'zod';
35
+ import { registerLang as registerLangInRegistry, sealLangRegistry, } from './ast-classifier.js';
36
+ import { isSealed as isChunkerRegistrySealed, register as registerChunkerInRegistry, seal as sealChunkerRegistry, } from './chunkers/chunker-registry.js';
37
+ // ─── Schema ─────────────────────────────────────────
38
+ /**
39
+ * `.totem/installed-packs.json` substrate. Written by `totem sync`,
40
+ * consumed by `loadInstalledPacks()` at boot.
41
+ *
42
+ * `version: 1` is the load-bearing sentinel for forward compatibility:
43
+ * future schema changes bump the version, callers fail loud on unknown
44
+ * versions rather than silently mis-parsing.
45
+ */
46
+ export const InstalledPacksManifestSchema = z
47
+ .object({
48
+ version: z.literal(1),
49
+ packs: z.array(z
50
+ .object({
51
+ /** Pack package name as it appears in npm (e.g., `@totem/pack-rust-architecture`). */
52
+ name: z.string().min(1),
53
+ /**
54
+ * Absolute filesystem path to the pack's package root. Refined to
55
+ * `path.isAbsolute()` so a relative entry can't pass schema
56
+ * validation and then probe two different locations downstream
57
+ * (`existsSync` resolves from cwd, `require.resolve` from this
58
+ * module).
59
+ */
60
+ resolvedPath: z
61
+ .string()
62
+ .min(1)
63
+ .refine((value) => path.isAbsolute(value), 'resolvedPath must be an absolute path'),
64
+ /** The pack's `peerDependencies['@mmnto/totem']` semver range, verbatim. */
65
+ declaredEngineRange: z.string().min(1),
66
+ })
67
+ .strict()),
68
+ })
69
+ .strict()
70
+ // Duplicate pack names would let two callbacks run while `PACK_REGISTRY`
71
+ // silently keeps only the first entry — the second callback's chunker
72
+ // or language registrations surface later as a registry collision
73
+ // instead of a clear manifest-boundary error. Fail loud here.
74
+ .superRefine((manifest, ctx) => {
75
+ const seen = new Set();
76
+ manifest.packs.forEach((pack, index) => {
77
+ if (seen.has(pack.name)) {
78
+ ctx.addIssue({
79
+ code: z.ZodIssueCode.custom,
80
+ path: ['packs', index, 'name'],
81
+ message: `duplicate pack entry '${pack.name}'`,
82
+ });
83
+ return;
84
+ }
85
+ seen.add(pack.name);
86
+ });
87
+ });
88
+ // ─── Internal state ─────────────────────────────────
89
+ const PACK_REGISTRY = new Map();
90
+ let engineSealed = false;
91
+ // ─── Core: loadInstalledPacks ───────────────────────
92
+ /**
93
+ * Read `.totem/installed-packs.json` and run every registered pack's
94
+ * registration callback synchronously. After all callbacks return, seal
95
+ * both the chunker registry and the language registry.
96
+ *
97
+ * Idempotent: a second call after the first throws because the engine is
98
+ * already sealed (callers must not "re-load" packs at runtime). For
99
+ * tests, see `__resetForTests()`.
100
+ */
101
+ export function loadInstalledPacks(options = {}) {
102
+ if (engineSealed) {
103
+ throw new Error('loadInstalledPacks() called after engine seal — engine has already started serving requests. Pack registration is a boot-time-only operation.');
104
+ }
105
+ const projectRoot = options.projectRoot ?? process.cwd();
106
+ const totemDir = options.totemDir ?? '.totem';
107
+ const engineVersion = options.engineVersion ?? resolveEngineVersion();
108
+ const packsToRegister = options.inMemoryPacks ?? readManifestAndResolveCallbacks(projectRoot, totemDir);
109
+ // Engine version cross-check (ADR-097 Q6) — runs against every pack
110
+ // before any callback executes, so a single mismatch fails loud before
111
+ // touching the registries.
112
+ for (const { pack } of packsToRegister) {
113
+ assertEngineRangeSatisfied(pack, engineVersion);
114
+ }
115
+ // Run every callback. A throwing pack short-circuits registration —
116
+ // the engine is left unsealed so a subsequent retry (e.g., test reset)
117
+ // can recover, but the in-flight registration entries from prior packs
118
+ // remain. Callers running in production should treat any throw here
119
+ // as a hard error and not attempt to recover.
120
+ for (const { pack, callback } of packsToRegister) {
121
+ const api = {
122
+ registerChunkStrategy(name, chunkerCtor) {
123
+ registerChunkerInRegistry(name, chunkerCtor);
124
+ },
125
+ registerLanguage(extension, lang, wasmLoader) {
126
+ registerLangInRegistry(extension, lang, wasmLoader);
127
+ },
128
+ };
129
+ let callbackResult;
130
+ try {
131
+ callbackResult = callback(api);
132
+ }
133
+ catch (err) {
134
+ throw new Error(`Pack '${pack.name}' registration callback threw. The pack at '${pack.resolvedPath}' must be fixed or removed.`, { cause: err instanceof Error ? err : new Error(String(err)) });
135
+ }
136
+ // Per ADR-097 § 5 Q5 the registration callback contract is
137
+ // synchronous; an `async register(api)` would resolve AFTER the
138
+ // engine seals, leaving partial registry state. The
139
+ // `PackRegisterCallback` type already says `void`, but TypeScript
140
+ // can't enforce sync vs async at runtime — a JS-authored pack or
141
+ // one that drifts from the type can still return a Promise. Detect
142
+ // the thenable shape here and fail loud before the seal. Kept
143
+ // outside the try-catch above so the contract-violation error
144
+ // surfaces with its own message rather than getting wrapped as
145
+ // "callback threw."
146
+ if (callbackResult !== null &&
147
+ // totem-context: null is excluded by the `!== null` guard on the line above; rule matcher only sees the `=== 'object'` token in isolation
148
+ (typeof callbackResult === 'object' || typeof callbackResult === 'function') &&
149
+ 'then' in callbackResult &&
150
+ typeof callbackResult.then === 'function') {
151
+ throw new Error(`Pack '${pack.name}' registration callback returned a Promise — registration must be synchronous per ADR-097 § 5 Q5. The pack at '${pack.resolvedPath}' must export a synchronous \`register\` (not \`async register\`).`);
152
+ }
153
+ if (!PACK_REGISTRY.has(pack.name)) {
154
+ PACK_REGISTRY.set(pack.name, pack);
155
+ }
156
+ }
157
+ sealChunkerRegistry();
158
+ sealLangRegistry();
159
+ engineSealed = true;
160
+ return [...PACK_REGISTRY.values()];
161
+ }
162
+ /**
163
+ * Snapshot of currently-loaded packs. Empty until `loadInstalledPacks()`
164
+ * runs; populated thereafter and stable for the engine lifetime.
165
+ */
166
+ export function loadedPacks() {
167
+ return [...PACK_REGISTRY.values()];
168
+ }
169
+ /** True iff the engine has sealed (registration phase complete). */
170
+ export function isEngineSealed() {
171
+ return engineSealed;
172
+ }
173
+ // ─── Manifest read + callback resolution ────────────
174
+ function readManifestAndResolveCallbacks(projectRoot, totemDir) {
175
+ const manifestPath = path.join(projectRoot, totemDir, 'installed-packs.json');
176
+ let raw;
177
+ try {
178
+ raw = fs.readFileSync(manifestPath, 'utf-8');
179
+ }
180
+ catch (err) {
181
+ const code = err.code;
182
+ if (code === 'ENOENT') {
183
+ // Pre-sync repo or fresh checkout. Treat as no packs — user can
184
+ // run `totem sync` to populate.
185
+ return [];
186
+ }
187
+ throw new Error(`Failed to read installed-packs manifest at '${manifestPath}'. Re-run \`totem sync\` to regenerate.`, { cause: err instanceof Error ? err : new Error(String(err)) });
188
+ }
189
+ let parsedJson;
190
+ try {
191
+ parsedJson = JSON.parse(raw);
192
+ }
193
+ catch (err) {
194
+ throw new Error(`installed-packs manifest at '${manifestPath}' is not valid JSON. Re-run \`totem sync\` to regenerate.`, { cause: err instanceof Error ? err : new Error(String(err)) });
195
+ }
196
+ const result = InstalledPacksManifestSchema.safeParse(parsedJson);
197
+ if (!result.success) {
198
+ throw new Error(`installed-packs manifest at '${manifestPath}' failed schema validation: ${result.error.issues
199
+ .map((issue) => `${issue.path.join('.')}: ${issue.message}`)
200
+ .join('; ')}. Re-run \`totem sync\` to regenerate.`);
201
+ }
202
+ const require = createRequire(import.meta.url);
203
+ return result.data.packs.map((entry) => {
204
+ const callback = resolvePackCallback(entry.name, entry.resolvedPath, require);
205
+ const pack = {
206
+ name: entry.name,
207
+ resolvedPath: entry.resolvedPath,
208
+ declaredEngineRange: entry.declaredEngineRange,
209
+ };
210
+ return { pack, callback };
211
+ });
212
+ }
213
+ function resolvePackCallback(name, resolvedPath, require) {
214
+ if (!fs.existsSync(resolvedPath)) {
215
+ throw new Error(`Pack '${name}' is registered in installed-packs.json at '${resolvedPath}' but the path does not exist. Re-install the pack or re-run \`totem sync\`.`);
216
+ }
217
+ // Synchronous `require()` is mandated by ADR-097 § 5 Q5: pack
218
+ // registration runs at boot before the engine seal, and boot is
219
+ // synchronous. This means the pack's registration entry must be
220
+ // CommonJS-resolvable — either authored as CJS, or ESM packs must
221
+ // ship a CJS-compatible registration entry (e.g., a built
222
+ // `dist/register.cjs`). Pure-ESM registration entries will throw
223
+ // `ERR_REQUIRE_ESM` at boot. Async-boot support (`await import()`)
224
+ // would lift this constraint and is tracked separately.
225
+ let mod;
226
+ try {
227
+ mod = require(resolvedPath);
228
+ }
229
+ catch (err) {
230
+ throw new Error(`Pack '${name}' at '${resolvedPath}' could not be loaded.`, {
231
+ cause: err instanceof Error ? err : new Error(String(err)),
232
+ });
233
+ }
234
+ // Pack callbacks may default-export OR named-export `register`. Default
235
+ // export is the ADR-097 reference shape; `register` named export is the
236
+ // CommonJS-friendly alternative.
237
+ const candidate = mod.default ?? mod.register;
238
+ if (typeof candidate !== 'function') {
239
+ throw new Error(`Pack '${name}' at '${resolvedPath}' did not export a registration callback (expected default export or named \`register\` of type function).`);
240
+ }
241
+ return candidate;
242
+ }
243
+ // ─── Engine version cross-check (ADR-097 Q6) ────────
244
+ function assertEngineRangeSatisfied(pack, engineVersion) {
245
+ if (!semver.validRange(pack.declaredEngineRange)) {
246
+ throw new Error(`Pack '${pack.name}' declares peerDependencies['@mmnto/totem'] = '${pack.declaredEngineRange}', which is not a valid semver range. Fix the pack's package.json.`);
247
+ }
248
+ if (!semver.satisfies(engineVersion, pack.declaredEngineRange, { includePrerelease: true })) {
249
+ throw new Error(`Pack '${pack.name}' requires @mmnto/totem '${pack.declaredEngineRange}' but the running engine is ${engineVersion}. Upgrade the pack to a version compatible with this engine, or pin the engine to a version satisfied by the pack's range.`);
250
+ }
251
+ }
252
+ function resolveEngineVersion() {
253
+ // Resolve relative to this module's URL so the read works regardless
254
+ // of cwd. The package.json sits at packages/core/package.json — two
255
+ // levels up from packages/core/dist/pack-discovery.js when the build
256
+ // output runs, and one level up from packages/core/src/pack-discovery.ts
257
+ // during tsx test execution. Try both.
258
+ const require = createRequire(import.meta.url);
259
+ for (const candidate of ['../package.json', '../../package.json']) {
260
+ try {
261
+ const pkg = require(candidate);
262
+ if (typeof pkg.version === 'string')
263
+ return pkg.version;
264
+ }
265
+ catch (err) {
266
+ const code = err instanceof Error && 'code' in err ? err.code : undefined;
267
+ if (code === 'ENOENT' || code === 'MODULE_NOT_FOUND')
268
+ continue;
269
+ throw new Error(`Failed to resolve engine version from '${candidate}'. The file exists but could not be read or parsed; check permissions and JSON syntax.`, { cause: err instanceof Error ? err : new Error(String(err)) });
270
+ }
271
+ }
272
+ // Fall back to a sentinel that won't satisfy any reasonable range —
273
+ // surfaces the missing-version-resolution as a peerDeps mismatch rather
274
+ // than an undefined-behavior path. If a pack legitimately uses range
275
+ // '*' this will still pass.
276
+ return '0.0.0';
277
+ }
278
+ // ─── Test-only helpers ──────────────────────────────
279
+ /**
280
+ * Test-only: reset pack-discovery local state (`PACK_REGISTRY` map and
281
+ * `engineSealed` flag). NEVER call from production.
282
+ *
283
+ * **This does NOT reset downstream registries.** Tests that need a
284
+ * fresh chunker or language registry must additionally invoke
285
+ * `__resetForTests` from `chunker-registry.js` and `ast-classifier.js`
286
+ * — those modules own their own lifecycle. Forgetting either reset
287
+ * leaks built-in registrations across cases. The standard `afterEach`
288
+ * pattern in `pack-discovery.test.ts` calls all three.
289
+ */
290
+ export function __resetForTests() {
291
+ PACK_REGISTRY.clear();
292
+ engineSealed = false;
293
+ }
294
+ /** Test-only: inspect chunker registry seal state. */
295
+ export function __isChunkerRegistrySealedForTests() {
296
+ return isChunkerRegistrySealed();
297
+ }
298
+ //# sourceMappingURL=pack-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack-discovery.js","sourceRoot":"","sources":["../src/pack-discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EACL,YAAY,IAAI,sBAAsB,EACtC,gBAAgB,GAEjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,QAAQ,IAAI,uBAAuB,EACnC,QAAQ,IAAI,yBAAyB,EACrC,IAAI,IAAI,mBAAmB,GAC5B,MAAM,gCAAgC,CAAC;AAExC,uDAAuD;AAEvD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC;KAC1C,MAAM,CAAC;IACN,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACrB,KAAK,EAAE,CAAC,CAAC,KAAK,CACZ,CAAC;SACE,MAAM,CAAC;QACN,sFAAsF;QACtF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACvB;;;;;;WAMG;QACH,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,uCAAuC,CAAC;QACrF,4EAA4E;QAC5E,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;KACvC,CAAC;SACD,MAAM,EAAE,CACZ;CACF,CAAC;KACD,MAAM,EAAE;IACT,yEAAyE;IACzE,sEAAsE;IACtE,kEAAkE;IAClE,8DAA8D;KAC7D,WAAW,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE;IAC7B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QACrC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,GAAG,CAAC,QAAQ,CAAC;gBACX,IAAI,EAAE,CAAC,CAAC,YAAY,CAAC,MAAM;gBAC3B,IAAI,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC;gBAC9B,OAAO,EAAE,yBAAyB,IAAI,CAAC,IAAI,GAAG;aAC/C,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAuFL,uDAAuD;AAEvD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAsB,CAAC;AACpD,IAAI,YAAY,GAAG,KAAK,CAAC;AAEzB,uDAAuD;AAEvD;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAAqC,EAAE;IACxE,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,+IAA+I,CAChJ,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACzD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC;IAC9C,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,oBAAoB,EAAE,CAAC;IAEtE,MAAM,eAAe,GACnB,OAAO,CAAC,aAAa,IAAI,+BAA+B,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAElF,oEAAoE;IACpE,uEAAuE;IACvE,2BAA2B;IAC3B,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,eAAe,EAAE,CAAC;QACvC,0BAA0B,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IAClD,CAAC;IAED,oEAAoE;IACpE,uEAAuE;IACvE,uEAAuE;IACvE,oEAAoE;IACpE,8CAA8C;IAC9C,KAAK,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,eAAe,EAAE,CAAC;QACjD,MAAM,GAAG,GAAwB;YAC/B,qBAAqB,CAAC,IAAI,EAAE,WAAW;gBACrC,yBAAyB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YAC/C,CAAC;YACD,gBAAgB,CAAC,SAAS,EAAE,IAAI,EAAE,UAAU;gBAC1C,sBAAsB,CAAC,SAAS,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;YACtD,CAAC;SACF,CAAC;QACF,IAAI,cAAuB,CAAC;QAC5B,IAAI,CAAC;YACH,cAAc,GAAG,QAAQ,CAAC,GAAG,CAAY,CAAC;QAC5C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,SAAS,IAAI,CAAC,IAAI,+CAA+C,IAAI,CAAC,YAAY,6BAA6B,EAC/G,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAC/D,CAAC;QACJ,CAAC;QACD,2DAA2D;QAC3D,gEAAgE;QAChE,oDAAoD;QACpD,kEAAkE;QAClE,iEAAiE;QACjE,mEAAmE;QACnE,8DAA8D;QAC9D,8DAA8D;QAC9D,+DAA+D;QAC/D,oBAAoB;QACpB,IACE,cAAc,KAAK,IAAI;YACvB,0IAA0I;YAC1I,CAAC,OAAO,cAAc,KAAK,QAAQ,IAAI,OAAO,cAAc,KAAK,UAAU,CAAC;YAC5E,MAAM,IAAI,cAAc;YACxB,OAAQ,cAAoC,CAAC,IAAI,KAAK,UAAU,EAChE,CAAC;YACD,MAAM,IAAI,KAAK,CACb,SAAS,IAAI,CAAC,IAAI,kHAAkH,IAAI,CAAC,YAAY,oEAAoE,CAC1N,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,mBAAmB,EAAE,CAAC;IACtB,gBAAgB,EAAE,CAAC;IACnB,YAAY,GAAG,IAAI,CAAC;IAEpB,OAAO,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC;AACrC,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,cAAc;IAC5B,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,uDAAuD;AAEvD,SAAS,+BAA+B,CACtC,WAAmB,EACnB,QAAgB;IAEhB,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,sBAAsB,CAAC,CAAC;IAE9E,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;QACjD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,gEAAgE;YAChE,gCAAgC;YAChC,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,IAAI,KAAK,CACb,+CAA+C,YAAY,yCAAyC,EACpG,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAC/D,CAAC;IACJ,CAAC;IAED,IAAI,UAAmB,CAAC;IACxB,IAAI,CAAC;QACH,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,gCAAgC,YAAY,2DAA2D,EACvG,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAC/D,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,4BAA4B,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAClE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CACb,gCAAgC,YAAY,+BAA+B,MAAM,CAAC,KAAK,CAAC,MAAM;aAC3F,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;aAC3D,IAAI,CAAC,IAAI,CAAC,wCAAwC,CACtD,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACrC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAC9E,MAAM,IAAI,GAAe;YACvB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,mBAAmB,EAAE,KAAK,CAAC,mBAAmB;SAC/C,CAAC;QACF,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,mBAAmB,CAC1B,IAAY,EACZ,YAAoB,EACpB,OAAuB;IAEvB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CACb,SAAS,IAAI,+CAA+C,YAAY,8EAA8E,CACvJ,CAAC;IACJ,CAAC;IAED,8DAA8D;IAC9D,gEAAgE;IAChE,gEAAgE;IAChE,kEAAkE;IAClE,0DAA0D;IAC1D,iEAAiE;IACjE,mEAAmE;IACnE,wDAAwD;IACxD,IAAI,GAA8C,CAAC;IACnD,IAAI,CAAC;QACH,GAAG,GAAG,OAAO,CAAC,YAAY,CAA8C,CAAC;IAC3E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,SAAS,YAAY,wBAAwB,EAAE;YAC1E,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;SAC3D,CAAC,CAAC;IACL,CAAC;IAED,wEAAwE;IACxE,wEAAwE;IACxE,iCAAiC;IACjC,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,QAAQ,CAAC;IAC9C,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CACb,SAAS,IAAI,SAAS,YAAY,4GAA4G,CAC/I,CAAC;IACJ,CAAC;IAED,OAAO,SAAiC,CAAC;AAC3C,CAAC;AAED,uDAAuD;AAEvD,SAAS,0BAA0B,CAAC,IAAgB,EAAE,aAAqB;IACzE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CACb,SAAS,IAAI,CAAC,IAAI,kDAAkD,IAAI,CAAC,mBAAmB,oEAAoE,CACjK,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,IAAI,CAAC,mBAAmB,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC5F,MAAM,IAAI,KAAK,CACb,SAAS,IAAI,CAAC,IAAI,4BAA4B,IAAI,CAAC,mBAAmB,+BAA+B,aAAa,4HAA4H,CAC/O,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB;IAC3B,qEAAqE;IACrE,oEAAoE;IACpE,qEAAqE;IACrE,yEAAyE;IACzE,uCAAuC;IACvC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,KAAK,MAAM,SAAS,IAAI,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,EAAE,CAAC;QAClE,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAA0B,CAAC;YACxD,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ;gBAAE,OAAO,GAAG,CAAC,OAAO,CAAC;QAC1D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,GACR,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG,CAAC,CAAC,CAAE,GAA6B,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YAC1F,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,kBAAkB;gBAAE,SAAS;YAC/D,MAAM,IAAI,KAAK,CACb,0CAA0C,SAAS,wFAAwF,EAC3I,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAC/D,CAAC;QACJ,CAAC;IACH,CAAC;IACD,oEAAoE;IACpE,wEAAwE;IACxE,qEAAqE;IACrE,4BAA4B;IAC5B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,uDAAuD;AAEvD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe;IAC7B,aAAa,CAAC,KAAK,EAAE,CAAC;IACtB,YAAY,GAAG,KAAK,CAAC;AACvB,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,iCAAiC;IAC/C,OAAO,uBAAuB,EAAE,CAAC;AACnC,CAAC"}
@@ -0,0 +1,17 @@
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
+ export {};
17
+ //# sourceMappingURL=pack-discovery.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack-discovery.test.d.ts","sourceRoot":"","sources":["../src/pack-discovery.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}