ghagga 3.2.0 → 3.3.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 (37) hide show
  1. package/dist/commands/index-cmd.d.ts +49 -0
  2. package/dist/commands/index-cmd.d.ts.map +1 -0
  3. package/dist/commands/index-cmd.js +367 -0
  4. package/dist/commands/index-cmd.js.map +1 -0
  5. package/dist/commands/index-cmd.test.d.ts +17 -0
  6. package/dist/commands/index-cmd.test.d.ts.map +1 -0
  7. package/dist/commands/index-cmd.test.js +541 -0
  8. package/dist/commands/index-cmd.test.js.map +1 -0
  9. package/dist/commands/indexer-registry.d.ts +93 -0
  10. package/dist/commands/indexer-registry.d.ts.map +1 -0
  11. package/dist/commands/indexer-registry.js +342 -0
  12. package/dist/commands/indexer-registry.js.map +1 -0
  13. package/dist/commands/indexer-registry.test.d.ts +10 -0
  14. package/dist/commands/indexer-registry.test.d.ts.map +1 -0
  15. package/dist/commands/indexer-registry.test.js +538 -0
  16. package/dist/commands/indexer-registry.test.js.map +1 -0
  17. package/dist/commands/review-blast-radius.test.d.ts +13 -0
  18. package/dist/commands/review-blast-radius.test.d.ts.map +1 -0
  19. package/dist/commands/review-blast-radius.test.js +179 -0
  20. package/dist/commands/review-blast-radius.test.js.map +1 -0
  21. package/dist/commands/review.d.ts +112 -1
  22. package/dist/commands/review.d.ts.map +1 -1
  23. package/dist/commands/review.js +264 -2
  24. package/dist/commands/review.js.map +1 -1
  25. package/dist/commands/review.test.js +290 -0
  26. package/dist/commands/review.test.js.map +1 -1
  27. package/dist/commands/triage.d.ts +14 -0
  28. package/dist/commands/triage.d.ts.map +1 -0
  29. package/dist/commands/triage.js +153 -0
  30. package/dist/commands/triage.js.map +1 -0
  31. package/dist/commands/triage.test.d.ts +8 -0
  32. package/dist/commands/triage.test.d.ts.map +1 -0
  33. package/dist/commands/triage.test.js +184 -0
  34. package/dist/commands/triage.test.js.map +1 -0
  35. package/dist/index.js +35 -0
  36. package/dist/index.js.map +1 -1
  37. package/package.json +4 -3
@@ -0,0 +1,541 @@
1
+ /**
2
+ * Tests for `ghagga index` — registry-dispatcher dependency graph indexing.
3
+ *
4
+ * Mocked: `detectMarkerDirectories` (from `./indexer-registry.js`) — the
5
+ * dispatcher tests only exercise detect/availability/degrade/zero-index/
6
+ * merge/output-isolation/cap wiring, mirroring the mocking style of the
7
+ * previous Go-only tests (mocked `toolchainCheck`/`run`, not real
8
+ * toolchains). Per-language mapping correctness is covered separately by
9
+ * `packages/core`'s SCIP mapper fixture tests.
10
+ *
11
+ * Nested marker detection: `detectMarkerDirectories` returns
12
+ * `Array<{entry, dir}>` pairs (not a flat entry list) — the dispatcher runs
13
+ * each pair independently and merges with `pathPrefix = relative(repoPath,
14
+ * dir)`, so tests here exercise per-pair (not just per-language) dispatch.
15
+ */
16
+ import { join, resolve } from 'node:path';
17
+ import { GRAPH_VERSION } from 'ghagga-core';
18
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
19
+ // ─── Mocks ─────────────────────────────────────────────────────
20
+ const mockWriteFileSync = vi.fn();
21
+ const mockMkdirSync = vi.fn();
22
+ const mockExistsSync = vi.fn();
23
+ vi.mock('node:fs', async (importOriginal) => {
24
+ const actual = await importOriginal();
25
+ return {
26
+ ...actual,
27
+ writeFileSync: (...args) => mockWriteFileSync(...args),
28
+ mkdirSync: (...args) => mockMkdirSync(...args),
29
+ existsSync: (...args) => mockExistsSync(...args),
30
+ };
31
+ });
32
+ // `resolveGitHead` shells out via `execFileSync('git', ['rev-parse', 'HEAD'])`.
33
+ // Mocked so tests never depend on the real git state of the checkout the
34
+ // suite runs in (and to deterministically exercise the non-git fallback).
35
+ const mockExecFileSync = vi.fn();
36
+ vi.mock('node:child_process', async (importOriginal) => {
37
+ const actual = await importOriginal();
38
+ return {
39
+ ...actual,
40
+ execFileSync: (...args) => mockExecFileSync(...args),
41
+ };
42
+ });
43
+ vi.mock('../ui/tui.js', () => ({
44
+ log: {
45
+ info: vi.fn(),
46
+ success: vi.fn(),
47
+ warn: vi.fn(),
48
+ error: vi.fn(),
49
+ step: vi.fn(),
50
+ message: vi.fn(),
51
+ },
52
+ }));
53
+ const mockDetectMarkerDirectories = vi.fn();
54
+ vi.mock('./indexer-registry.js', async () => {
55
+ const { join: joinPath } = await import('node:path');
56
+ return {
57
+ detectMarkerDirectories: (...args) => mockDetectMarkerDirectories(...args),
58
+ // Real production shape (`.ghagga/scip/<name>.scip`), not mocked away —
59
+ // the dispatcher's output-path-per-run disambiguation is what's under
60
+ // test here, so this must behave like the real helper.
61
+ scipOutputPath: (dir, bin) => joinPath(dir, '.ghagga', 'scip', `${bin}.scip`),
62
+ };
63
+ });
64
+ // process.exit throws so we can assert on it without killing the test runner
65
+ const mockExit = vi.spyOn(process, 'exit').mockImplementation(((code) => {
66
+ throw new Error(`process.exit(${code})`);
67
+ }));
68
+ // ─── Imports (after mocks) ──────────────────────────────────────
69
+ import * as tui from '../ui/tui.js';
70
+ import { indexCommand, slugifyRelPath } from './index-cmd.js';
71
+ const FIXTURE_DIR = resolve(import.meta.dirname, '../../../../packages/core/test/fixtures/scip-go-sample');
72
+ const FIXTURE_SCIP_PATH = join(FIXTURE_DIR, 'index.scip');
73
+ function parseGraphFixture(contents) {
74
+ return JSON.parse(contents);
75
+ }
76
+ function makeEntry(overrides) {
77
+ return {
78
+ markers: ['some-marker'],
79
+ toolchainCheck: () => true,
80
+ run: () => {
81
+ throw new Error('run() not stubbed for this test');
82
+ },
83
+ installHint: `install ${overrides.bin}`,
84
+ maturity: 'stable',
85
+ ...overrides,
86
+ };
87
+ }
88
+ describe('slugifyRelPath', () => {
89
+ it('does NOT collide on distinct relPaths that sanitize to the same prefix', () => {
90
+ // 'apps/a_b' and 'apps_a/b' both sanitize to 'apps_a_b' if only the
91
+ // separator-joined prefix is used — the hash suffix must disambiguate.
92
+ expect(slugifyRelPath('apps/a_b')).not.toBe(slugifyRelPath('apps_a/b'));
93
+ });
94
+ it('is deterministic: same input produces the same output across calls', () => {
95
+ const relPath = 'apps/ml-service';
96
+ expect(slugifyRelPath(relPath)).toBe(slugifyRelPath(relPath));
97
+ });
98
+ it('produces a filesystem-safe slug', () => {
99
+ const slug = slugifyRelPath('apps/a_b');
100
+ expect(slug).toMatch(/^[a-zA-Z0-9_.-]+$/);
101
+ });
102
+ });
103
+ describe('indexCommand', () => {
104
+ beforeEach(() => {
105
+ vi.clearAllMocks();
106
+ mockExistsSync.mockReturnValue(false);
107
+ mockExecFileSync.mockReturnValue('abc123def456\n');
108
+ });
109
+ describe('single detected+available marker directory', () => {
110
+ it('runs the indexer against the marker dir, parses the produced .scip, and writes a valid v1 graph.json', async () => {
111
+ const runSpy = vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH);
112
+ const entry = makeEntry({ bin: 'scip-go', languages: ['go'], run: runSpy });
113
+ mockDetectMarkerDirectories.mockReturnValue([{ entry, dir: FIXTURE_DIR }]);
114
+ await indexCommand(FIXTURE_DIR, {});
115
+ expect(runSpy).toHaveBeenCalledWith(FIXTURE_DIR, expect.stringContaining('scip-go.scip'));
116
+ expect(mockWriteFileSync).toHaveBeenCalledTimes(2);
117
+ const [outPath, contents] = mockWriteFileSync.mock.calls[0];
118
+ expect(String(outPath)).toContain('.ghagga/graph.json');
119
+ const graph = JSON.parse(contents);
120
+ expect(graph.version).toBe(GRAPH_VERSION);
121
+ expect(Object.keys(graph.nodes).length).toBeGreaterThan(0);
122
+ expect(tui.log.success).toHaveBeenCalled();
123
+ });
124
+ });
125
+ describe('per-marker-directory dispatch (Phase 3)', () => {
126
+ it('dispatches one run per {entry, dir} pair, not just once per unique language', async () => {
127
+ const nestedDir = join(FIXTURE_DIR, 'apps', 'backend');
128
+ const runSpy = vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH);
129
+ const entry = makeEntry({ bin: 'scip-go', languages: ['go'], run: runSpy });
130
+ mockDetectMarkerDirectories.mockReturnValue([
131
+ { entry, dir: FIXTURE_DIR },
132
+ { entry, dir: nestedDir },
133
+ ]);
134
+ await indexCommand(FIXTURE_DIR, {});
135
+ expect(runSpy).toHaveBeenCalledTimes(2);
136
+ expect(runSpy).toHaveBeenCalledWith(FIXTURE_DIR, expect.any(String));
137
+ expect(runSpy).toHaveBeenCalledWith(nestedDir, expect.any(String));
138
+ expect(tui.log.success).toHaveBeenCalled();
139
+ });
140
+ });
141
+ describe('per-pair degradation (D6)', () => {
142
+ it('missing toolchain: warns once per entry, skips ALL its dirs, continues with the rest', async () => {
143
+ const runSpy = vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH);
144
+ const availableEntry = makeEntry({ bin: 'scip-go', languages: ['go'], run: runSpy });
145
+ const missingRunSpy = vi.fn();
146
+ const missingEntry = makeEntry({
147
+ bin: 'rust-analyzer',
148
+ languages: ['rust'],
149
+ toolchainCheck: () => false,
150
+ installHint: 'install rust-analyzer via rustup',
151
+ run: missingRunSpy,
152
+ });
153
+ const nestedDir = join(FIXTURE_DIR, 'services');
154
+ mockDetectMarkerDirectories.mockReturnValue([
155
+ { entry: missingEntry, dir: FIXTURE_DIR },
156
+ { entry: missingEntry, dir: nestedDir },
157
+ { entry: availableEntry, dir: FIXTURE_DIR },
158
+ ]);
159
+ await indexCommand(FIXTURE_DIR, {});
160
+ expect(runSpy).toHaveBeenCalled();
161
+ expect(missingRunSpy).not.toHaveBeenCalled();
162
+ expect(tui.log.warn).toHaveBeenCalled();
163
+ const warnMessages = tui.log.warn.mock.calls.map((c) => c[0]);
164
+ // Only ONE toolchain-missing warning for the entry, not one per dir.
165
+ const toolchainWarnings = warnMessages.filter((m) => m.includes('rust') && m.includes('rustup'));
166
+ expect(toolchainWarnings).toHaveLength(1);
167
+ expect(mockWriteFileSync).toHaveBeenCalledTimes(2);
168
+ expect(tui.log.success).toHaveBeenCalled();
169
+ });
170
+ it('runtime failure in ONE marker directory: warns, skips only that pair, continues with the rest (spec: one Go dir fails, other Go dir + other languages still indexed)', async () => {
171
+ const nestedDir = join(FIXTURE_DIR, 'apps', 'backend-2');
172
+ const goodRun = vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH);
173
+ const failingRun = vi.fn().mockImplementation(() => {
174
+ throw new Error('scip-go crashed: segfault');
175
+ });
176
+ const goEntry = makeEntry({
177
+ bin: 'scip-go',
178
+ languages: ['go'],
179
+ run: (dir, outPath) => dir === nestedDir ? failingRun(dir, outPath) : goodRun(dir, outPath),
180
+ });
181
+ mockDetectMarkerDirectories.mockReturnValue([
182
+ { entry: goEntry, dir: FIXTURE_DIR },
183
+ { entry: goEntry, dir: nestedDir },
184
+ ]);
185
+ await indexCommand(FIXTURE_DIR, {});
186
+ expect(goodRun).toHaveBeenCalled();
187
+ expect(failingRun).toHaveBeenCalled();
188
+ expect(tui.log.warn).toHaveBeenCalled();
189
+ const warnMessages = tui.log.warn.mock.calls.map((c) => c[0]);
190
+ expect(warnMessages.some((m) => m.includes('segfault'))).toBe(true);
191
+ expect(mockWriteFileSync).toHaveBeenCalledTimes(2);
192
+ expect(tui.log.success).toHaveBeenCalled();
193
+ });
194
+ });
195
+ describe('zero indexed', () => {
196
+ it('no --fallback-regex: exits non-zero listing what was tried and why each failed', async () => {
197
+ const missingEntry = makeEntry({
198
+ bin: 'rust-analyzer',
199
+ languages: ['rust'],
200
+ toolchainCheck: () => false,
201
+ });
202
+ const crashingEntry = makeEntry({
203
+ bin: 'scip-php',
204
+ languages: ['php'],
205
+ run: () => {
206
+ throw new Error('boom');
207
+ },
208
+ });
209
+ mockDetectMarkerDirectories.mockReturnValue([
210
+ { entry: missingEntry, dir: FIXTURE_DIR },
211
+ { entry: crashingEntry, dir: FIXTURE_DIR },
212
+ ]);
213
+ await expect(indexCommand(FIXTURE_DIR, {})).rejects.toThrow('process.exit(1)');
214
+ expect(mockExit).toHaveBeenCalledWith(1);
215
+ expect(mockWriteFileSync).not.toHaveBeenCalled();
216
+ expect(tui.log.error).toHaveBeenCalled();
217
+ const message = tui.log.error.mock.calls[0][0];
218
+ expect(message).toContain('rust');
219
+ expect(message).toContain('php');
220
+ });
221
+ it('no detected marker directories at all, no --fallback-regex: exits non-zero', async () => {
222
+ mockDetectMarkerDirectories.mockReturnValue([]);
223
+ await expect(indexCommand(FIXTURE_DIR, {})).rejects.toThrow('process.exit(1)');
224
+ expect(mockExit).toHaveBeenCalledWith(1);
225
+ expect(mockWriteFileSync).not.toHaveBeenCalled();
226
+ });
227
+ it('with --fallback-regex: uses the regex builder and writes graph.json', async () => {
228
+ const missingEntry = makeEntry({
229
+ bin: 'rust-analyzer',
230
+ languages: ['rust'],
231
+ toolchainCheck: () => false,
232
+ });
233
+ mockDetectMarkerDirectories.mockReturnValue([{ entry: missingEntry, dir: FIXTURE_DIR }]);
234
+ await indexCommand(FIXTURE_DIR, { fallbackRegex: true });
235
+ expect(mockWriteFileSync).toHaveBeenCalledTimes(2);
236
+ const [outPath, contents] = mockWriteFileSync.mock.calls[0];
237
+ expect(String(outPath)).toContain('.ghagga/graph.json');
238
+ const graph = JSON.parse(contents);
239
+ expect(graph.version).toBe(GRAPH_VERSION);
240
+ expect(tui.log.warn).toHaveBeenCalled();
241
+ });
242
+ });
243
+ describe('output path option', () => {
244
+ it('writes to a custom --out path relative to the target repo', async () => {
245
+ const runSpy = vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH);
246
+ const entry = makeEntry({ bin: 'scip-go', languages: ['go'], run: runSpy });
247
+ mockDetectMarkerDirectories.mockReturnValue([{ entry, dir: FIXTURE_DIR }]);
248
+ await indexCommand(FIXTURE_DIR, { out: 'custom/graph.json' });
249
+ const [outPath] = mockWriteFileSync.mock.calls[0];
250
+ expect(String(outPath)).toBe(resolve(FIXTURE_DIR, 'custom/graph.json'));
251
+ });
252
+ });
253
+ describe('--marker-depth option', () => {
254
+ it('threads a valid --marker-depth through to detectMarkerDirectories as maxDepth', async () => {
255
+ const runSpy = vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH);
256
+ const entry = makeEntry({ bin: 'scip-go', languages: ['go'], run: runSpy });
257
+ mockDetectMarkerDirectories.mockReturnValue([{ entry, dir: FIXTURE_DIR }]);
258
+ await indexCommand(FIXTURE_DIR, { markerDepth: '2' });
259
+ expect(mockDetectMarkerDirectories).toHaveBeenCalledWith(FIXTURE_DIR, { maxDepth: 2 });
260
+ });
261
+ it('defaults to maxDepth: undefined (detectMarkerDirectories falls back to DEFAULT_MARKER_DEPTH=4) when --marker-depth is absent', async () => {
262
+ const runSpy = vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH);
263
+ const entry = makeEntry({ bin: 'scip-go', languages: ['go'], run: runSpy });
264
+ mockDetectMarkerDirectories.mockReturnValue([{ entry, dir: FIXTURE_DIR }]);
265
+ await indexCommand(FIXTURE_DIR, {});
266
+ expect(mockDetectMarkerDirectories).toHaveBeenCalledWith(FIXTURE_DIR, {
267
+ maxDepth: undefined,
268
+ });
269
+ });
270
+ it.each([
271
+ '0',
272
+ '-1',
273
+ 'abc',
274
+ '2.5',
275
+ '',
276
+ ])('rejects an invalid --marker-depth %j with a clear error and exits non-zero, without walking', async (invalid) => {
277
+ await expect(indexCommand(FIXTURE_DIR, { markerDepth: invalid })).rejects.toThrow('process.exit(1)');
278
+ expect(tui.log.error).toHaveBeenCalledWith(expect.stringContaining('--marker-depth'));
279
+ expect(mockDetectMarkerDirectories).not.toHaveBeenCalled();
280
+ });
281
+ });
282
+ describe('multi-language merge + output isolation (D2, D4)', () => {
283
+ it('reads each pair.run() return path independently — the dispatcher does not assume a single shared output path', async () => {
284
+ // Two entries, each returning its OWN isolated .scip path — here we
285
+ // prove the DISPATCHER calls run(dir, outPath) per pair and reads
286
+ // each returned path independently rather than clobbering a shared
287
+ // variable. Both point at the same real fixture bytes, which is
288
+ // fine: this test exercises path-independence, not per-language
289
+ // mapping correctness (covered in packages/core's SCIP fixture tests).
290
+ const entryA = makeEntry({
291
+ bin: 'scip-go',
292
+ languages: ['go'],
293
+ run: vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH),
294
+ });
295
+ const entryB = makeEntry({
296
+ bin: 'scip-go-2',
297
+ languages: ['java'],
298
+ run: vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH),
299
+ });
300
+ mockDetectMarkerDirectories.mockReturnValue([
301
+ { entry: entryA, dir: FIXTURE_DIR },
302
+ { entry: entryB, dir: FIXTURE_DIR },
303
+ ]);
304
+ await indexCommand(FIXTURE_DIR, {});
305
+ expect(entryA.run).toHaveBeenCalledWith(FIXTURE_DIR, expect.any(String));
306
+ expect(entryB.run).toHaveBeenCalledWith(FIXTURE_DIR, expect.any(String));
307
+ // Both entries' distinct returned scipPaths were read independently —
308
+ // the dispatcher never reused/mutated a single shared variable.
309
+ expect(mockWriteFileSync).toHaveBeenCalledTimes(2);
310
+ const [, contents] = mockWriteFileSync.mock.calls[0];
311
+ const graph = JSON.parse(contents);
312
+ expect(graph.version).toBe(GRAPH_VERSION);
313
+ expect(Object.keys(graph.nodes).length).toBeGreaterThan(0);
314
+ });
315
+ it('D3 HIGHEST-RISK: two marker directories of the SAME indexer bin (two scip-python dirs) get DISTINCT output paths — no clobber', async () => {
316
+ const mlService = join(FIXTURE_DIR, 'apps', 'ml-service');
317
+ const aiAssistant = join(FIXTURE_DIR, 'services', 'ai-assistant');
318
+ const seenOutPaths = [];
319
+ const runSpy = vi.fn().mockImplementation((_dir, outPath) => {
320
+ seenOutPaths.push(outPath);
321
+ return Promise.resolve(FIXTURE_SCIP_PATH);
322
+ });
323
+ const pythonEntry = makeEntry({ bin: 'scip-python', languages: ['python'], run: runSpy });
324
+ mockDetectMarkerDirectories.mockReturnValue([
325
+ { entry: pythonEntry, dir: mlService },
326
+ { entry: pythonEntry, dir: aiAssistant },
327
+ ]);
328
+ await indexCommand(FIXTURE_DIR, {});
329
+ expect(runSpy).toHaveBeenCalledTimes(2);
330
+ expect(seenOutPaths).toHaveLength(2);
331
+ // The two calls' outPaths must be DISTINCT — the whole point of D3.
332
+ expect(seenOutPaths[0]).not.toBe(seenOutPaths[1]);
333
+ // Both must be disambiguated variants of the SAME bin name, not two
334
+ // unrelated paths — proves the collision was avoided BY DESIGN
335
+ // (dir-slug suffix), not by accident.
336
+ for (const p of seenOutPaths) {
337
+ expect(p).toContain('scip-python');
338
+ }
339
+ expect(mockWriteFileSync).toHaveBeenCalledTimes(2);
340
+ expect(tui.log.success).toHaveBeenCalled();
341
+ });
342
+ });
343
+ describe('scip-typescript root-umbrella collapse (D6, empirical spike)', () => {
344
+ it('collapses multiple TS/JS marker-dir pairs into a SINGLE root-cwd run', async () => {
345
+ const runSpy = vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH);
346
+ const tsEntry = makeEntry({
347
+ bin: 'scip-typescript',
348
+ languages: ['typescript', 'javascript'],
349
+ run: runSpy,
350
+ });
351
+ const appsWeb = join(FIXTURE_DIR, 'apps', 'web');
352
+ const packagesUtils = join(FIXTURE_DIR, 'packages', 'utils');
353
+ mockDetectMarkerDirectories.mockReturnValue([
354
+ { entry: tsEntry, dir: appsWeb },
355
+ { entry: tsEntry, dir: packagesUtils },
356
+ ]);
357
+ await indexCommand(FIXTURE_DIR, {});
358
+ // Exactly ONE run, at repo root — NOT one per nested TS marker dir.
359
+ expect(runSpy).toHaveBeenCalledTimes(1);
360
+ expect(runSpy).toHaveBeenCalledWith(FIXTURE_DIR, expect.any(String));
361
+ expect(tui.log.success).toHaveBeenCalled();
362
+ });
363
+ it('does not affect non-TypeScript entries dispatched in the same run', async () => {
364
+ const tsRunSpy = vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH);
365
+ const goRunSpy = vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH);
366
+ const tsEntry = makeEntry({
367
+ bin: 'scip-typescript',
368
+ languages: ['typescript', 'javascript'],
369
+ run: tsRunSpy,
370
+ });
371
+ const goEntry = makeEntry({ bin: 'scip-go', languages: ['go'], run: goRunSpy });
372
+ const appsWeb = join(FIXTURE_DIR, 'apps', 'web');
373
+ const appsBackend = join(FIXTURE_DIR, 'apps', 'backend');
374
+ mockDetectMarkerDirectories.mockReturnValue([
375
+ { entry: tsEntry, dir: appsWeb },
376
+ { entry: goEntry, dir: appsBackend },
377
+ ]);
378
+ await indexCommand(FIXTURE_DIR, {});
379
+ expect(tsRunSpy).toHaveBeenCalledTimes(1);
380
+ expect(tsRunSpy).toHaveBeenCalledWith(FIXTURE_DIR, expect.any(String));
381
+ expect(goRunSpy).toHaveBeenCalledTimes(1);
382
+ expect(goRunSpy).toHaveBeenCalledWith(appsBackend, expect.any(String));
383
+ });
384
+ it('a single TS marker-dir pair still runs (collapse is a no-op, not a skip)', async () => {
385
+ const runSpy = vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH);
386
+ const tsEntry = makeEntry({
387
+ bin: 'scip-typescript',
388
+ languages: ['typescript', 'javascript'],
389
+ run: runSpy,
390
+ });
391
+ mockDetectMarkerDirectories.mockReturnValue([{ entry: tsEntry, dir: FIXTURE_DIR }]);
392
+ await indexCommand(FIXTURE_DIR, {});
393
+ expect(runSpy).toHaveBeenCalledTimes(1);
394
+ expect(runSpy).toHaveBeenCalledWith(FIXTURE_DIR, expect.any(String));
395
+ });
396
+ });
397
+ describe('run-count cap (D5)', () => {
398
+ it('caps runs at the configured maximum and warns naming the skipped marker directories', async () => {
399
+ const runSpy = vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH);
400
+ const entry = makeEntry({ bin: 'scip-go', languages: ['go'], run: runSpy });
401
+ // 30 distinct marker dirs, well over the DEFAULT_MAX_NESTED_RUNS (25).
402
+ const pairs = Array.from({ length: 30 }, (_, i) => ({
403
+ entry,
404
+ dir: join(FIXTURE_DIR, `dir-${i}`),
405
+ }));
406
+ mockDetectMarkerDirectories.mockReturnValue(pairs);
407
+ await indexCommand(FIXTURE_DIR, {});
408
+ expect(runSpy).toHaveBeenCalledTimes(25);
409
+ expect(tui.log.warn).toHaveBeenCalled();
410
+ const warnMessages = tui.log.warn.mock.calls.map((c) => c[0]);
411
+ const capWarning = warnMessages.find((m) => m.includes('cap') || m.includes('25'));
412
+ expect(capWarning).toBeDefined();
413
+ // Names at least one of the dropped directories.
414
+ expect(capWarning).toMatch(/dir-(2[5-9])/);
415
+ });
416
+ it('sorts stable-maturity entries before heavy/experimental when capping', async () => {
417
+ const stableRun = vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH);
418
+ const experimentalRun = vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH);
419
+ const stableEntry = makeEntry({
420
+ bin: 'scip-go',
421
+ languages: ['go'],
422
+ maturity: 'stable',
423
+ run: stableRun,
424
+ });
425
+ const experimentalEntry = makeEntry({
426
+ bin: 'scip-dotnet',
427
+ languages: ['csharp'],
428
+ maturity: 'experimental',
429
+ run: experimentalRun,
430
+ });
431
+ // 20 experimental pairs registered FIRST, then 10 stable pairs — if
432
+ // sort-before-cap works, all 10 stable pairs still run even though
433
+ // they were declared after 20 experimental ones (cap is 25).
434
+ const experimentalPairs = Array.from({ length: 20 }, (_, i) => ({
435
+ entry: experimentalEntry,
436
+ dir: join(FIXTURE_DIR, `exp-${i}`),
437
+ }));
438
+ const stablePairs = Array.from({ length: 10 }, (_, i) => ({
439
+ entry: stableEntry,
440
+ dir: join(FIXTURE_DIR, `stable-${i}`),
441
+ }));
442
+ mockDetectMarkerDirectories.mockReturnValue([...experimentalPairs, ...stablePairs]);
443
+ await indexCommand(FIXTURE_DIR, {});
444
+ expect(stableRun).toHaveBeenCalledTimes(10);
445
+ expect(experimentalRun).toHaveBeenCalledTimes(15);
446
+ });
447
+ it('NEVER drops a root-level marker, even when nested stable markers alone exceed the cap', async () => {
448
+ const rootRun = vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH);
449
+ const nestedRun = vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH);
450
+ // Root-level `heavy` marker (e.g. a root pom.xml) — before the fix,
451
+ // this sorts AFTER every `stable` nested pair and gets capped away.
452
+ const rootEntry = makeEntry({
453
+ bin: 'scip-java',
454
+ languages: ['java'],
455
+ maturity: 'heavy',
456
+ run: rootRun,
457
+ });
458
+ const nestedEntry = makeEntry({
459
+ bin: 'scip-go',
460
+ languages: ['go'],
461
+ maturity: 'stable',
462
+ run: nestedRun,
463
+ });
464
+ // 25 nested stable pairs — exactly at DEFAULT_MAX_NESTED_RUNS — plus
465
+ // the one root-level heavy pair.
466
+ const nestedPairs = Array.from({ length: 25 }, (_, i) => ({
467
+ entry: nestedEntry,
468
+ dir: join(FIXTURE_DIR, `dir-${i}`),
469
+ }));
470
+ mockDetectMarkerDirectories.mockReturnValue([
471
+ { entry: rootEntry, dir: FIXTURE_DIR },
472
+ ...nestedPairs,
473
+ ]);
474
+ await indexCommand(FIXTURE_DIR, {});
475
+ // The root marker ALWAYS runs — never dropped by the cap.
476
+ expect(rootRun).toHaveBeenCalledTimes(1);
477
+ expect(rootRun).toHaveBeenCalledWith(FIXTURE_DIR, expect.any(String));
478
+ // The cap applies only to the nested pairs: budget = 25 - 1 root = 24.
479
+ expect(nestedRun).toHaveBeenCalledTimes(24);
480
+ });
481
+ });
482
+ describe('metadata.json (design v2 D1/B-003)', () => {
483
+ it('writes metadata.json AFTER graph.json, with languages derived from graph.nodes (not dispatch)', async () => {
484
+ const runSpy = vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH);
485
+ const entry = makeEntry({ bin: 'scip-go', languages: ['go'], run: runSpy });
486
+ mockDetectMarkerDirectories.mockReturnValue([{ entry, dir: FIXTURE_DIR }]);
487
+ mockExecFileSync.mockReturnValue('deadbeef1234\n');
488
+ await indexCommand(FIXTURE_DIR, {});
489
+ expect(mockWriteFileSync).toHaveBeenCalledTimes(2);
490
+ const [graphPath] = mockWriteFileSync.mock.calls[0];
491
+ const [metadataPath, metadataContents] = mockWriteFileSync.mock.calls[1];
492
+ expect(String(graphPath)).toContain('.ghagga/graph.json');
493
+ expect(String(metadataPath)).toContain('.ghagga/metadata.json');
494
+ const graph = parseGraphFixture(mockWriteFileSync.mock.calls[0][1]);
495
+ const metadata = JSON.parse(metadataContents);
496
+ expect(metadata.lastIndexedCommit).toBe('deadbeef1234');
497
+ expect(metadata.schemaVersion).toBe(GRAPH_VERSION);
498
+ expect(metadata.graphVersion).toBe(graph.version);
499
+ expect(metadata.fileCount).toBe(Object.keys(graph.nodes).length);
500
+ // Derived from graph.nodes contents, NOT dispatch's indexedLanguages —
501
+ // both happen to include 'go' here, but the derivation source matters
502
+ // (see the regex-fallback case below, where indexedLanguages is []).
503
+ const graphLanguages = [...new Set(Object.values(graph.nodes).map((n) => n.language))];
504
+ expect(metadata.languages.sort()).toEqual(graphLanguages.sort());
505
+ expect(metadata.builtVia).toBe('scip');
506
+ });
507
+ it('git HEAD resolution failure (non-git repo) degrades to an empty lastIndexedCommit, does not throw', async () => {
508
+ const runSpy = vi.fn().mockResolvedValue(FIXTURE_SCIP_PATH);
509
+ const entry = makeEntry({ bin: 'scip-go', languages: ['go'], run: runSpy });
510
+ mockDetectMarkerDirectories.mockReturnValue([{ entry, dir: FIXTURE_DIR }]);
511
+ mockExecFileSync.mockImplementation(() => {
512
+ throw new Error('not a git repository');
513
+ });
514
+ await indexCommand(FIXTURE_DIR, {});
515
+ const [, metadataContents] = mockWriteFileSync.mock.calls[1];
516
+ const metadata = JSON.parse(metadataContents);
517
+ expect(metadata.lastIndexedCommit).toBe('');
518
+ });
519
+ it('regex fallback: metadata.languages is derived from graph.nodes, not the empty dispatch indexedLanguages (CRITICAL-1)', async () => {
520
+ const missingEntry = makeEntry({
521
+ bin: 'rust-analyzer',
522
+ languages: ['rust'],
523
+ toolchainCheck: () => false,
524
+ });
525
+ mockDetectMarkerDirectories.mockReturnValue([{ entry: missingEntry, dir: FIXTURE_DIR }]);
526
+ await indexCommand(FIXTURE_DIR, { fallbackRegex: true });
527
+ expect(mockWriteFileSync).toHaveBeenCalledTimes(2);
528
+ const [, metadataContents] = mockWriteFileSync.mock.calls[1];
529
+ const metadata = JSON.parse(metadataContents);
530
+ // Regex-fallback's dispatch indexedLanguages is [] — but the graph's
531
+ // nodes carry real languages, so metadata.languages must NOT be empty
532
+ // when the built graph actually has nodes of a known language.
533
+ const graph = parseGraphFixture(mockWriteFileSync.mock.calls[0][1]);
534
+ const graphLanguages = [...new Set(Object.values(graph.nodes).map((n) => n.language))];
535
+ expect(metadata.languages.sort()).toEqual(graphLanguages.sort());
536
+ expect(metadata.skippedLanguages).toContain('rust');
537
+ expect(metadata.builtVia).toBe('regex');
538
+ });
539
+ });
540
+ });
541
+ //# sourceMappingURL=index-cmd.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-cmd.test.js","sourceRoot":"","sources":["../../src/commands/index-cmd.test.ts"],"names":[],"mappings":"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"}