sigmap 6.10.4 → 6.10.6

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/AGENTS.md CHANGED
@@ -56,40 +56,18 @@ Use this marker block for all appendable context files:
56
56
  | To query by topic | `sigmap --query "<topic>"` |
57
57
 
58
58
  Always run `sigmap ask` or `sigmap --query` before searching for files relevant to a task.
59
- ## changes (last 5 commits — 3 days ago)
60
59
  ## deps
61
60
  ```
62
61
  src/extractors/python_ast.py ← ast
63
62
  ```
64
63
 
65
- ## packages
66
-
67
- ### packages/core/index.js
68
- ```
69
- module.exports = { extract, rank, buildSigIndex, scan, score, adapt }
70
- function _resolveExtractor(language)
71
- function extract(src, language) → string[]
72
- function rank(query, sigIndex, opts) → { file: string, score: nu
73
- function buildSigIndex(cwd) → Map<string, string[]>
74
- function scan(sigs, filePath) → { safe: string[], redacte
75
- function score(cwd) → { * score: number, * grad
76
- function adapt(context, adapterName, opts = {}) → string
77
- ## changes (last 5 commits — 1 second ago)
64
+ ## changes (last 5 commits — 11 minutes ago)
78
65
  ```
79
- src/discovery/source-root-resolver.js ~_applySpecialRules ~_dedupeNested
80
- src/map/import-graph.js ~analyze
81
- packages/adapters/index.js ~getAdapter
82
- packages/adapters/willow.js +format +outputPath +generateAtomId +fetchWithTimeout
66
+ src/analysis/diagnostics.js +estimateTokens +formatFileDecision +computeFileMetrics +explainInclusion
67
+ src/map/import-graph.js +buildReverseGraph ~extractImports ~resolveJsPath ~detectCycles
83
68
  ```
84
69
 
85
- ## src
86
-
87
- ### src/discovery/sigmapignore.js
88
- ### packages/cli/index.js
89
- ```
90
- module.exports = { CLI_ENTRY, run }
91
- function run(argv, cwd) → void
92
- ```
70
+ ## packages
93
71
 
94
72
  ### packages/adapters/llm-full.js
95
73
  ```
@@ -121,168 +99,63 @@ code-fence ---
121
99
 
122
100
  ### packages/adapters/copilot.js
123
101
  ```
124
- module.exports = { loadIgnorePatterns, matchesIgnorePattern }
125
- function loadIgnorePatterns(cwd)
126
- function matchesIgnorePattern(dirName, patterns)
127
- ```
128
-
129
- ### src/discovery/source-root-registry.js
130
- ```
131
- module.exports = { REGISTRY }
132
- ```
133
-
134
- ### src/discovery/source-root-resolver.js
135
- ```
136
- module.exports = { resolveSourceRoots }
137
- function resolveSourceRoots(cwd, opts = {})
138
- function _detectMonorepo(cwd)
139
- function _enumerateCandidates(cwd, isMonorepo, ignorePatterns, excludeList)
140
- function _applySpecialRules(scored, cwd, primaryFw, fwEntry, frameworks)
141
- function _dedupeNested(scored)
142
- function _computeConfidence(frameworks, languages, scoredCount)
143
- ```
144
-
145
- ### src/discovery/source-root-scorer.js
146
- ```
147
- module.exports = { scoreCandidate, getRecentlyChangedDirs, ROOT_ENTRYPOINTS, JVM_PATH_PATTERN }
148
- function getRecentlyChangedDirs(cwd)
149
- function scoreCandidate(dirName, fullPath, context)
150
- function _countSourceFiles(dir, depth)
151
- ```
152
-
153
- ### src/eval/runner.js
154
- ```
155
- module.exports = { run, rank, loadTasks, buildSigIndex, formatTable, formatMetrics, tokenize }
156
- function buildSigIndex(cwd) → Map<string, string[]>
157
- function tokenize(text) → string[]
158
- function scoreFile(sigs, queryTokens) → number
159
- function rank(query, index, topK = 10) → { file: string, score: nu
160
- function estimateTokens(sigs) → number
161
- function loadTasks(tasksFile) → Array<{id:string, query:s
162
- function run(tasksFile, cwd, opts = {}) → { * tasks: Array<{id, que
163
- function formatTable(taskResults) → string
164
- function formatMetrics(metrics) → string
165
- ```
166
-
167
- ### src/eval/scorer.js
168
- ```
169
- module.exports = { hitAtK, reciprocalRank, precisionAtK, aggregate, firstRank }
170
- function firstRank(ranked, expected) → number
171
- function normalizePath(p) → string
172
- function hitAtK(ranked, expected, k = 5) → 0|1
173
- function reciprocalRank(ranked, expected) → number
174
- function precisionAtK(ranked, expected, k = 5) → number
175
- function aggregate(results, k = 5) → { * hitAt5: number, // fr
176
- function round(x)
177
- ```
178
-
179
- ### src/extractors/coverage.js
180
- ```
181
- module.exports = { buildTestIndex, isTested }
182
- function walkFiles(dir)
183
- function buildTestIndex(cwd, testDirs)
184
- function isTested(funcName, testIndex)
185
- ```
186
-
187
- ### src/extractors/cpp.js
188
- ```
189
- module.exports = { extract }
190
- function extract(src) → string[]
191
- function extractBlock(src, startIndex)
192
- function extractMembers(block)
193
- function normalizeParams(params)
194
- function normalizeType(type)
195
- ```
196
-
197
- ### src/extractors/csharp.js
198
- ```
199
- module.exports = { extract }
200
- function extract(src) → string[]
201
- function extractBlock(src, startIndex)
202
- function extractMembers(block)
203
- function normalizeParams(params)
204
- function normalizeType(type)
205
- ```
206
-
207
- ### src/extractors/css.js
208
- ```
209
- module.exports = { extract }
210
- function extract(src) → string[]
211
- ```
212
-
213
- ### src/extractors/dart.js
214
- ```
215
- module.exports = { extract }
216
- function extract(src) → string[]
217
- function extractBlock(src, startIndex)
218
- function extractMembers(block)
219
- function normalizeParams(params)
220
- ```
221
-
222
- ### src/extractors/deps.js
223
- ```
224
- module.exports = { extractPythonDeps, extractTSDeps, buildReverseDepMap }
225
- function extractPythonDeps(src) → string[]
226
- function extractTSDeps(src) → string[]
227
- function buildReverseDepMap(forwardMap) → Map<string, string[]>
228
- ```
229
-
230
- ### src/extractors/dockerfile.js
231
- ```
232
- module.exports = { extract }
233
- function extract(src) → string[]
102
+ module.exports = { name, format, outputPath, write }
103
+ function format(context, opts = {}) → string
104
+ function _confidenceMeta(opts)
105
+ function outputPath(cwd) → string
106
+ function write(context, cwd, opts = {})
234
107
  ```
235
108
 
236
- ### src/extractors/generic.js
109
+ ### packages/adapters/cursor.js
237
110
  ```
238
- module.exports = { extract }
239
- function extract(src)
111
+ module.exports = { name, format, outputPath }
112
+ function format(context, opts = {}) → string
113
+ function _confidenceMeta(opts)
114
+ function outputPath(cwd) → string
240
115
  ```
241
116
 
242
- ### src/extractors/go.js
117
+ ### packages/adapters/gemini.js
243
118
  ```
244
- module.exports = { extract }
245
- function extract(src) → string[]
246
- function extractBlock(src, startIndex)
247
- function extractInterfaceMethods(block)
248
- function normalizeParams(params)
119
+ module.exports = { name, format, outputPath, write }
120
+ function format(context, opts = {}) → string
121
+ function outputPath(cwd) → string
122
+ function write(context, cwd, opts = {})
123
+ function _confidenceMeta(opts)
249
124
  ```
250
125
 
251
- ### src/extractors/graphql.js
126
+ ### packages/adapters/openai.js
252
127
  ```
253
- module.exports = { extract }
254
- function extract(src) → string[]
128
+ module.exports = { name, format, outputPath }
129
+ function format(context, opts = {}) → string
130
+ function outputPath(cwd) → string
131
+ function _confidenceMeta(opts)
255
132
  ```
256
133
 
257
- ### src/extractors/html.js
134
+ ### packages/adapters/windsurf.js
258
135
  ```
259
- module.exports = { extract }
260
- function extract(src) → string[]
136
+ module.exports = { name, format, outputPath }
137
+ function format(context, opts = {}) → string
138
+ function _confidenceMeta(opts)
139
+ function outputPath(cwd) → string
261
140
  ```
262
141
 
263
- ### src/extractors/java.js
142
+ ### packages/adapters/claude.js
264
143
  ```
265
- module.exports = { extract }
266
- function extract(src) → string[]
267
- function extractBlock(src, startIndex)
268
- function extractMembers(block)
269
- function normalizeParams(params)
270
- function normalizeType(type)
144
+ module.exports = { name, format, outputPath, write }
145
+ function format(context, opts = {}) → string
146
+ function _confidenceMeta(opts)
147
+ function outputPath(cwd) → string
148
+ function write(context, cwd, opts = {})
271
149
  ```
272
150
 
273
- ### src/extractors/javascript.js
151
+ ### packages/adapters/codex.js
274
152
  ```
275
- module.exports = { extract }
276
- function extract(src) → string[]
277
- function extractBlock(src, startIndex)
278
- function extractClassMembers(block, returnHints)
279
- function buildReturnHints(src)
280
- function normalizeType(type)
281
- function formatReturnHint(type)
282
- function normalizeParams(params)
153
+ module.exports = { name, format, outputPath, write }
154
+ function format(context, opts = {}) → string
155
+ function outputPath(cwd) → string
156
+ function write(context, cwd, opts = {})
283
157
  ```
284
158
 
285
- ### src/extractors/kotlin.js
286
159
  ### packages/adapters/index.js
287
160
  ```
288
161
  module.exports = { getAdapter, listAdapters, adapt, outputsToAdapters }
@@ -315,216 +188,156 @@ function score(cwd) → { * score: number, * grad
315
188
  function adapt(context, adapterName, opts = {}) → string
316
189
  ```
317
190
 
318
- ### packages/adapters/willow.js
319
- ```
320
- module.exports = { name, format, outputPath, write }
321
- function format(context, opts = {}) → string
322
- function outputPath(cwd) → string
323
- function generateAtomId(filepath) → string
324
- async function fetchWithTimeout(url, opts, timeoutMs) → Promise<Response>
325
- async function postAtomWithRetry(atom, mcpUrl, timeoutMs, maxRetries) → Promise<boolean>
326
- async function write(context, cwd, opts = {}) → Promise<void>
327
- ```
328
-
329
- ### packages/adapters/index.js
330
- ```
331
- module.exports = { getAdapter, listAdapters, adapt, outputsToAdapters }
332
- function getAdapter(name) → { name: string, format: F
333
- function listAdapters() → string[]
334
- function adapt(context, adapterName, opts = {}) → string
335
- function outputsToAdapters(outputs) → string[]
336
- ```
337
-
338
191
  ## src
339
192
 
340
- ### src/retrieval/tokenizer.js
341
- ```
342
- module.exports = { extract }
343
- function extract(src) → string[]
344
- function extractBlock(src, startIndex)
345
- function extractMembers(block)
346
- function normalizeParams(params)
347
- ```
348
-
349
- ### src/extractors/markdown.js
350
- ```
351
- module.exports = { extract }
352
- function extract(src) → string[]
353
- ```
354
-
355
- ### src/extractors/patterns.js
356
- ```
357
- module.exports = { extract }
358
- function extract(src) → string[]
359
- ```
360
-
361
- ### src/extractors/php.js
193
+ ### src/mcp/tools.js
362
194
  ```
363
- module.exports = { extract }
364
- function extract(src) → string[]
365
- function extractBlock(src, startIndex)
366
- function extractMembers(block)
367
- function normalizeParams(params)
368
- function normalizeType(type)
195
+ module.exports = { TOOLS }
369
196
  ```
370
197
 
371
- ### src/extractors/prdiff.js
198
+ ### src/health/scorer.js
372
199
  ```
373
- module.exports = { diffSignatures, extractName }
374
- function diffSignatures(baseSigs, currentSigs) → {added:string[], removed:
375
- function extractName(sig)
200
+ module.exports = { score }
201
+ function score(cwd) → { * score: number, * grad
376
202
  ```
377
203
 
378
- ### src/extractors/properties.js
204
+ ### src/extractors/coverage.js
379
205
  ```
380
- module.exports = { extract }
381
- function extract(src) → string[]
206
+ module.exports = { buildTestIndex, isTested }
207
+ function walkFiles(dir)
208
+ function buildTestIndex(cwd, testDirs)
209
+ function isTested(funcName, testIndex)
382
210
  ```
383
211
 
384
- ### src/extractors/protobuf.js
212
+ ### src/extractors/css.js
385
213
  ```
386
214
  module.exports = { extract }
387
215
  function extract(src) → string[]
388
216
  ```
389
217
 
390
- ### src/extractors/python.js
218
+ ### src/extractors/sql.js
391
219
  ```
392
220
  module.exports = { extract }
393
221
  function extract(src) → string[]
394
- function extractClassMethods(stripped, startIndex)
395
- function tryExtractDataclassFields(stripped, classIndex)
396
- function tryExtractBaseModelFields(stripped, bodyStart)
397
- function extractClassConstants(stripped, startIndex)
398
- function extractReturnType(sigLine)
399
- function normalizeParams(params)
400
- function extractDocHint(src, fnName, fnSigLine)
222
+ function _cleanName(raw)
223
+ function _normalizeParams(raw)
401
224
  ```
402
225
 
403
- ### src/extractors/python_dataclass.js
226
+ ### src/extractors/graphql.js
404
227
  ```
405
228
  module.exports = { extract }
406
229
  function extract(src) → string[]
407
230
  ```
408
231
 
409
- ### src/extractors/ruby.js
232
+ ### src/extractors/protobuf.js
410
233
  ```
411
234
  module.exports = { extract }
412
235
  function extract(src) → string[]
413
- function normalizeParams(params)
414
- function extractReturnHint(stripped, index)
415
236
  ```
416
237
 
417
- ### src/extractors/rust.js
238
+ ### src/extractors/terraform.js
418
239
  ```
419
240
  module.exports = { extract }
420
241
  function extract(src) → string[]
421
- function extractBlock(src, startIndex)
422
- function extractMethods(block)
423
- function normalizeParams(params)
424
- function extractReturnType(afterParen)
425
242
  ```
426
243
 
427
- ### src/extractors/scala.js
244
+ ### src/extractors/markdown.js
428
245
  ```
429
246
  module.exports = { extract }
430
247
  function extract(src) → string[]
431
- function extractBlock(src, startIndex)
432
- function extractMembers(block)
433
- function normalizeParams(params)
434
- function normalizeType(type)
435
248
  ```
436
249
 
437
- ### src/extractors/shell.js
250
+ ### src/extractors/properties.js
438
251
  ```
439
252
  module.exports = { extract }
440
253
  function extract(src) → string[]
441
254
  ```
442
255
 
443
- ### src/extractors/sql.js
256
+ ### src/extractors/toml.js
444
257
  ```
445
258
  module.exports = { extract }
446
259
  function extract(src) → string[]
447
- function _cleanName(raw)
448
- function _normalizeParams(raw)
449
260
  ```
450
261
 
451
- ### src/extractors/svelte.js
262
+ ### src/extractors/xml.js
452
263
  ```
453
264
  module.exports = { extract }
454
265
  function extract(src) → string[]
455
- function normalizeParams(params)
456
- function normalizeType(type)
457
266
  ```
458
267
 
459
- ### src/extractors/swift.js
268
+ ### src/extractors/patterns.js
460
269
  ```
461
270
  module.exports = { extract }
462
271
  function extract(src) → string[]
463
- function extractBlock(src, startIndex)
464
- function extractMembers(block)
465
- function normalizeParams(params)
466
- function extractArrowType(str)
467
272
  ```
468
273
 
469
- ### src/extractors/terraform.js
274
+ ### src/extractors/python_dataclass.js
470
275
  ```
471
276
  module.exports = { extract }
472
277
  function extract(src) → string[]
473
278
  ```
474
279
 
475
- ### src/extractors/todos.js
476
- ```
477
- module.exports = { extractTodos }
478
- function extractTodos(src) → {line:number, tag:string,
479
- ```
480
-
481
- ### src/extractors/toml.js
280
+ ### src/extractors/typescript_react.js
482
281
  ```
483
282
  module.exports = { extract }
484
283
  function extract(src) → string[]
485
284
  ```
486
285
 
487
- ### src/extractors/typescript.js
286
+ ### src/extractors/vue_sfc.js
488
287
  ```
489
288
  module.exports = { extract }
490
289
  function extract(src) → string[]
491
- function extractBlock(src, startIndex)
492
- function extractInterfaceMembers(block)
493
- function extractClassMembers(block)
494
- function normalizeParams(params)
495
290
  ```
496
291
 
497
- ### src/extractors/typescript_react.js
292
+ ### src/extractors/generic.js
498
293
  ```
499
294
  module.exports = { extract }
500
- function extract(src) → string[]
295
+ function extract(src)
501
296
  ```
502
297
 
503
- ### src/extractors/vue.js
298
+ ### src/format/llm-txt.js
504
299
  ```
505
- module.exports = { extract }
506
- function extract(src) → string[]
507
- function normalizeParams(params)
508
- function normalizeType(type)
300
+ module.exports = { format, outputPath }
301
+ function outputPath(cwd)
302
+ function format(context, cwd, version)
509
303
  ```
510
304
 
511
- ### src/extractors/vue_sfc.js
305
+ ### src/format/llms-txt.js
512
306
  ```
513
- module.exports = { extract }
514
- function extract(src) → string[]
307
+ module.exports = { format, outputPath }
308
+ function outputPath(cwd)
309
+ function getShortCommit(cwd)
310
+ function detectVersion(cwd)
311
+ function format(context, cwd, writtenFiles, sigmapVersion)
515
312
  ```
516
313
 
517
- ### src/extractors/xml.js
518
314
  ### src/format/dashboard.js
519
315
  ```
520
- module.exports = { extract }
521
- function extract(src) → string[]
316
+ module.exports = { generateDashboardHtml, renderHistoryCharts, computeExtractorCoverage, percentile, overBudgetStreak }
317
+ function toNumber(v)
318
+ function percentile(values, p)
319
+ function overBudgetStreak(entries)
320
+ function loadConfig(cwd)
321
+ function shouldExclude(rel, excludeSet)
322
+ function detectLanguage(filePath)
323
+ function walkFiles(dir, maxDepth, depth, out, excludeSet)
324
+ function computeExtractorCoverage(cwd)
325
+ function readBenchmarkTrend(cwd)
326
+ function lineChartSvg(values, title, ySuffix)
327
+ function barChartSvg(perLanguage)
328
+ function sparkline(values)
329
+ function buildDashboardData(cwd, health)
330
+ function generateDashboardHtml(cwd, health)
331
+ function renderHistoryCharts(cwd, health)
522
332
  ```
523
333
 
524
- ### src/extractors/yaml.js
334
+ ### src/judge/judge-engine.js
525
335
  ```
526
- module.exports = { extract }
527
- function extract(src) → string[]
336
+ module.exports = { groundedness, judge }
337
+ function tokenize(text)
338
+ function groundedness(response, context)
339
+ function extractContextFiles(context, cwd)
340
+ function judge(response, context, opts = {})
528
341
  ```
529
342
 
530
343
  ### src/format/benchmark-report.js
@@ -554,83 +367,53 @@ function generateBenchmarkReportHtml(reports, opts = {})
554
367
  function writeBenchmarkReport(cwd, opts = {})
555
368
  ```
556
369
 
557
- ### src/format/cache.js
558
- ```
559
- module.exports = { formatCache, formatCachePayload }
560
- function formatCache(content) → string
561
- function formatCachePayload(content, model) → string
562
- ```
563
-
564
- ### src/format/dashboard.js
565
- ```
566
- module.exports = { generateDashboardHtml, renderHistoryCharts, computeExtractorCoverage, percentile, overBudgetStreak }
567
- function toNumber(v)
568
- function percentile(values, p)
569
- function overBudgetStreak(entries)
570
- function loadConfig(cwd)
571
- function shouldExclude(rel, excludeSet)
572
- function detectLanguage(filePath)
573
- function walkFiles(dir, maxDepth, depth, out, excludeSet)
574
- function computeExtractorCoverage(cwd)
575
- function readBenchmarkTrend(cwd)
576
- function lineChartSvg(values, title, ySuffix)
577
- function barChartSvg(perLanguage)
578
- function sparkline(values)
579
- function buildDashboardData(cwd, health)
580
- function generateDashboardHtml(cwd, health)
581
- function renderHistoryCharts(cwd, health)
582
- ```
583
-
584
- ### src/format/llm-txt.js
585
- ```
586
- module.exports = { format, outputPath }
587
- function outputPath(cwd)
588
- function format(context, cwd, version)
589
- ```
590
-
591
- ### src/format/llms-txt.js
370
+ ### src/analysis/coverage-score.js
592
371
  ```
593
- module.exports = { format, outputPath }
594
- function outputPath(cwd)
595
- function getShortCommit(cwd)
596
- function detectVersion(cwd)
597
- function format(context, cwd, writtenFiles, sigmapVersion)
372
+ module.exports = { coverageScore, CODE_EXTS }
373
+ function coverageScore(cwd, fileEntries, config)
374
+ function _walk(dir, excludeSet, out)
598
375
  ```
599
376
 
600
- ### src/graph/builder.js
377
+ ### src/cache/sig-cache.js
601
378
  ```
602
- module.exports = { build, buildFromCwd, extractFileDeps }
603
- function resolveJsPath(dir, importStr, fileSet) → string|null
604
- function extractFileDeps(filePath, content, fileSet) → string[]
605
- function build(files, cwd) → { forward: Map<string,str
606
- function buildFromCwd(cwd, opts) → { forward: Map<string,str
379
+ module.exports = { loadCache, saveCache, getChangedFiles, updateCacheEntries }
380
+ function cachePath(cwd)
381
+ function loadCache(cwd, currentVersion) → Map<string, { mtime: numb
382
+ function saveCache(cwd, currentVersion, cache)
383
+ function getChangedFiles(files, cache) → { changed: string[], unch
384
+ function updateCacheEntries(cache, extracted)
607
385
  ```
608
386
 
609
- ### src/graph/impact.js
387
+ ### src/mcp/handlers.js
610
388
  ```
611
- module.exports = { getImpact, analyzeImpact, formatImpact, formatImpactJSON }
612
- function bfs(startFile, reverseGraph, maxDepth) → { direct: Set<string>, tr
613
- function isTestFile(f)
614
- function isRouteFile(f)
615
- function getImpact(changedFile, graph, opts) → { * changed: string, * di
616
- function analyzeImpact(changedFiles, cwd, opts) → { file: string, impact: o
617
- function formatImpact(result) → string
618
- function formatImpactJSON(result) → object
389
+ module.exports = { readContext, searchSignatures, getMap, createCheckpoint, getRouting, explainFile, listModules, queryContext, getImpact }
390
+ function readContext(args, cwd)
391
+ function searchSignatures(args, cwd)
392
+ function getMap(args, cwd)
393
+ function createCheckpoint(args, cwd)
394
+ function getRouting(args, cwd)
395
+ function explainFile(args, cwd)
396
+ function listModules(args, cwd)
397
+ function queryContext(args, cwd)
398
+ function getImpact(args, cwd)
619
399
  ```
620
400
 
621
- ### src/health/scorer.js
401
+ ### src/tracking/logger.js
622
402
  ```
623
- module.exports = { score }
624
- function score(cwd) → { * score: number, * grad
403
+ module.exports = { logRun, readLog, summarize }
404
+ function logRun(entry, cwd)
405
+ function readLog(cwd) → object[]
406
+ function summarize(entries) → object
625
407
  ```
626
408
 
627
- ### src/judge/judge-engine.js
409
+ ### src/extractors/typescript.js
628
410
  ```
629
- module.exports = { groundedness, judge }
630
- function tokenize(text)
631
- function groundedness(response, context)
632
- function extractContextFiles(context, cwd)
633
- function judge(response, context, opts = {})
411
+ module.exports = { extract }
412
+ function extract(src) → string[]
413
+ function extractBlock(src, startIndex)
414
+ function extractInterfaceMembers(block)
415
+ function extractClassMembers(block)
416
+ function normalizeParams(params)
634
417
  ```
635
418
 
636
419
  ### src/learning/weights.js
@@ -650,52 +433,31 @@ function exportWeights(cwd, outputPath)
650
433
  function importWeights(cwd, importPath, replace)
651
434
  ```
652
435
 
653
- ### src/map/class-hierarchy.js
654
- ```
655
- module.exports = { analyze }
656
- function analyze(files, cwd)
657
- ```
658
-
659
- ### src/map/import-graph.js
436
+ ### src/config/loader.js
660
437
  ```
661
- module.exports = { analyze }
662
- function extractImports(filePath, content, fileSet)
663
- function resolveJsPath(dir, importStr, fileSet)
664
- function detectCycles(graph)
665
- function analyze(files, cwd)
438
+ module.exports = { loadConfig, loadBaseConfig }
439
+ function loadBaseConfig(extendsVal, cwd)
440
+ function detectAutoSrcDirs(cwd, excludeList) → string[]
441
+ function _legacyDetectAutoSrcDirs(cwd, excludeList) → string[]
442
+ function loadConfig(cwd) → object
443
+ function deepClone(obj)
666
444
  ```
667
445
 
668
- ### src/map/route-table.js
446
+ ### src/discovery/framework-detector.js
669
447
  ```
670
- module.exports = { analyze }
671
- function shouldSkipFile(rel)
672
- function analyze(files, cwd)
448
+ module.exports = { detectFrameworks }
449
+ function detectFrameworks(cwd)
450
+ function _readDeps(cwd)
451
+ function _readFile(p)
452
+ function _existsAnywhere(cwd, filename, maxDepth)
453
+ function _walkFind(dir, name, depth)
673
454
  ```
674
455
 
675
- ### src/mcp/handlers.js
676
456
  ### src/discovery/sigmapignore.js
677
457
  ```
678
- module.exports = { readContext, searchSignatures, getMap, createCheckpoint, getRouting, explainFile, listModules, queryContext, getImpact }
679
- function readContext(args, cwd)
680
- function searchSignatures(args, cwd)
681
- function getMap(args, cwd)
682
- function createCheckpoint(args, cwd)
683
- function getRouting(args, cwd)
684
- function explainFile(args, cwd)
685
- function listModules(args, cwd)
686
- function queryContext(args, cwd)
687
- function getImpact(args, cwd)
688
- ```
689
-
690
- ### src/mcp/tools.js
691
- ```
692
- module.exports = { TOOLS }
693
- ```
694
-
695
- ### src/plan/planner.js
696
- ```
697
- module.exports = { createPlan }
698
- function createPlan(goal, cwd, config)
458
+ module.exports = { loadIgnorePatterns, matchesIgnorePattern }
459
+ function loadIgnorePatterns(cwd)
460
+ function matchesIgnorePattern(dirName, patterns)
699
461
  ```
700
462
 
701
463
  ### src/retrieval/ranker.js
@@ -713,34 +475,10 @@ function formatRankJSON(results, query) → object
713
475
  function detectIntent(query)
714
476
  ```
715
477
 
716
- ### src/retrieval/tokenizer.js
717
- ```
718
- module.exports = { tokenize, STOP_WORDS }
719
- function tokenize(text, opts) → string[]
720
- ```
721
-
722
- ### src/routing/classifier.js
723
- ```
724
- module.exports = { classify, classifyAll }
725
- function classify(filePath, sigs) → 'fast'|'balanced'|'powerf
726
- function classifyAll(fileEntries, cwd) → { fast: string[], balance
727
- ```
728
-
729
- ### src/routing/hints.js
730
- ```
731
- module.exports = { TIERS, formatRoutingSection }
732
- function formatRoutingSection(groups) → string
733
- ```
734
-
735
- ### src/security/patterns.js
736
- ```
737
- module.exports = { PATTERNS }
738
- ```
739
-
740
- ### src/security/scanner.js
478
+ ### src/plan/planner.js
741
479
  ```
742
- module.exports = { scan }
743
- function scan(signatures, filePath) → { safe: string[], redacte
480
+ module.exports = { createPlan }
481
+ function createPlan(goal, cwd, config)
744
482
  ```
745
483
 
746
484
  ### src/session/memory.js
@@ -753,28 +491,19 @@ function mergeSessionContext(scores, session, currentIntent)
753
491
  function clearSession(cwd)
754
492
  ```
755
493
 
756
- ### src/tracking/logger.js
494
+ ### src/config/defaults.js
757
495
  ```
758
- module.exports = { logRun, readLog, summarize }
759
- function logRun(entry, cwd)
760
- function readLog(cwd) → object[]
761
- function summarize(entries) → object
496
+ module.exports = { DEFAULTS }
762
497
  ```
763
498
 
764
- ### src/eval/analyzer.js
499
+ ### src/discovery/source-root-scorer.js
765
500
  ```
766
- module.exports = { analyzeFiles, formatAnalysisTable, formatAnalysisJSON }
767
- function isDockerfile(name)
768
- function getExtractorName(filePath)
769
- function tokenCount(sigs)
770
- function hasCoverage(filePath, cwd)
771
- function loadExtractor(name, cwd)
772
- function analyzeFiles(files, cwd, opts) → object[]
773
- function formatAnalysisTable(stats, showSlow) → string
774
- function formatAnalysisJSON(stats) → object
501
+ module.exports = { scoreCandidate, getRecentlyChangedDirs, ROOT_ENTRYPOINTS, JVM_PATH_PATTERN }
502
+ function getRecentlyChangedDirs(cwd)
503
+ function scoreCandidate(dirName, fullPath, context)
504
+ function _countSourceFiles(dir, depth)
775
505
  ```
776
506
 
777
- ### src/discovery/language-detector.js
778
507
  ### src/eval/usefulness-scorer.js
779
508
  ```
780
509
  module.exports = { scoreUsefulness, computeUsefulnessStats }
@@ -791,45 +520,9 @@ function _getMatchLength(name, token)
791
520
  function scopeToPackage(filePath, packageDir)
792
521
  ```
793
522
 
794
- ### src/discovery/language-detector.js
795
- ```
796
- module.exports = { detectLanguages }
797
- function detectLanguages(cwd)
798
- function _walkDepth(dir, depth, extCount)
799
- ```
800
-
801
523
  ### src/discovery/source-root-registry.js
802
524
  ```
803
525
  module.exports = { REGISTRY }
804
- ### src/discovery/language-detector.js
805
- ```
806
- module.exports = { detectLanguages }
807
- function detectLanguages(cwd)
808
- function _walkDepth(dir, depth, extCount)
809
- ```
810
-
811
- ### src/extractors/gdscript.js
812
- ```
813
- module.exports = { extract }
814
- function extract(src) → string[]
815
- function extractInnerMembers(stripped, startIndex)
816
- function normalizeParams(params)
817
- ### src/discovery/source-root-registry.js
818
- ```
819
- module.exports = { REGISTRY }
820
- ```
821
-
822
- ### src/eval/analyzer.js
823
- ```
824
- module.exports = { analyzeFiles, formatAnalysisTable, formatAnalysisJSON }
825
- function isDockerfile(name)
826
- function getExtractorName(filePath)
827
- function tokenCount(sigs)
828
- function hasCoverage(filePath, cwd)
829
- function loadExtractor(name, cwd)
830
- function analyzeFiles(files, cwd, opts) → object[]
831
- function formatAnalysisTable(stats, showSlow) → string
832
- function formatAnalysisJSON(stats) → object
833
526
  ```
834
527
 
835
528
  ### src/extractors/python.js
@@ -884,12 +577,51 @@ function _dedupeNested(scored)
884
577
  function _computeConfidence(frameworks, languages, scoredCount)
885
578
  ```
886
579
 
580
+ ### src/extractors/gdscript.js
581
+ ```
582
+ module.exports = { extract }
583
+ function extract(src) → string[]
584
+ function extractInnerMembers(stripped, startIndex)
585
+ function normalizeParams(params)
586
+ ```
587
+
588
+ ### src/discovery/language-detector.js
589
+ ```
590
+ module.exports = { detectLanguages }
591
+ function detectLanguages(cwd)
592
+ function _walkDepth(dir, depth, extCount)
593
+ ```
594
+
595
+ ### src/eval/analyzer.js
596
+ ```
597
+ module.exports = { analyzeFiles, formatAnalysisTable, formatAnalysisJSON }
598
+ function isDockerfile(name)
599
+ function getExtractorName(filePath)
600
+ function tokenCount(sigs)
601
+ function hasCoverage(filePath, cwd)
602
+ function loadExtractor(name, cwd)
603
+ function analyzeFiles(files, cwd, opts) → object[]
604
+ function formatAnalysisTable(stats, showSlow) → string
605
+ function formatAnalysisJSON(stats) → object
606
+ ```
607
+
608
+ ### src/analysis/diagnostics.js
609
+ ```
610
+ module.exports = { formatFileDecision, computeFileMetrics, explainInclusion, explainExclusion, estimateTokens }
611
+ function estimateTokens(text)
612
+ function formatFileDecision(entry, decision, reason, score = null)
613
+ function computeFileMetrics(entry)
614
+ function explainInclusion(fileEntries, budgetLimit)
615
+ function explainExclusion(dropped, reason)
616
+ ```
617
+
887
618
  ### src/map/import-graph.js
888
619
  ```
889
- module.exports = { analyze, extractImports }
620
+ module.exports = { analyze, extractImports, buildReverseGraph, resolveJsPath, detectCycles }
890
621
  function extractImports(filePath, content, fileSet)
891
622
  function resolveJsPath(dir, importStr, fileSet)
892
623
  function detectCycles(graph)
624
+ function buildReverseGraph(graph)
893
625
  function analyze(files, cwd)
894
626
  ```
895
627
 
package/CHANGELOG.md CHANGED
@@ -10,6 +10,14 @@ Format: [Semantic Versioning](https://semver.org/)
10
10
 
11
11
  ---
12
12
 
13
+ ## [6.10.5] — 2026-05-11
14
+
15
+ ### Added
16
+
17
+ - **Branching strategy tests** — Added regression tests verifying the develop-first branching workflow to ensure all PRs target develop before release merges to main.
18
+
19
+ ---
20
+
13
21
  ## [6.10.4] — 2026-05-11
14
22
 
15
23
  ### Fixed
package/gen-context.js CHANGED
@@ -5607,7 +5607,7 @@ __factories["./src/mcp/server"] = function(module, exports) {
5607
5607
 
5608
5608
  const SERVER_INFO = {
5609
5609
  name: 'sigmap',
5610
- version: '6.10.4',
5610
+ version: '6.10.6',
5611
5611
  description: 'SigMap MCP server — code signatures on demand',
5612
5612
  };
5613
5613
 
@@ -8234,7 +8234,7 @@ const path = require('path');
8234
8234
  const os = require('os');
8235
8235
  const { execSync } = require('child_process');
8236
8236
 
8237
- const VERSION = '6.10.4';
8237
+ const VERSION = '6.10.6';
8238
8238
  const MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
8239
8239
 
8240
8240
  function requireSourceOrBundled(key) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sigmap",
3
- "version": "6.10.4",
3
+ "version": "6.10.6",
4
4
  "description": "Zero-dependency AI context engine — 97% token reduction. No npm install. Runs on Node 18+.",
5
5
  "main": "gen-context.js",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sigmap-cli",
3
- "version": "6.10.4",
3
+ "version": "6.10.6",
4
4
  "description": "SigMap CLI wrapper — thin adapter for programmatic CLI invocation",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sigmap-core",
3
- "version": "6.10.4",
3
+ "version": "6.10.6",
4
4
  "description": "SigMap core library — zero-dependency code signature extraction, retrieval, and security scanning",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -0,0 +1,86 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Diagnostic utilities for understanding file inclusion/exclusion decisions.
5
+ *
6
+ * Provides detailed per-file diagnostics showing:
7
+ * - Why files are included or excluded
8
+ * - Ranking scores and signals
9
+ * - Budget constraints and priorities
10
+ */
11
+
12
+ const path = require('path');
13
+
14
+ function estimateTokens(text) {
15
+ return Math.ceil(text.length / 4);
16
+ }
17
+
18
+ function formatFileDecision(entry, decision, reason, score = null) {
19
+ const rel = path.relative(process.cwd(), entry.filePath);
20
+ const tokens = estimateTokens(entry.sigs.join('\n'));
21
+ let line = `${decision === 'included' ? '✓' : '✗'} ${rel}`;
22
+ line += ` [${tokens} tokens]`;
23
+ if (score !== null) line += ` [score: ${score.toFixed(2)}]`;
24
+ if (reason) line += ` — ${reason}`;
25
+ return line;
26
+ }
27
+
28
+ function computeFileMetrics(entry) {
29
+ const loc = entry.content ? entry.content.split('\n').length : 1;
30
+ const sigCount = entry.sigs ? entry.sigs.length : 0;
31
+ const signalQuality = loc > 0 ? sigCount / loc : 0;
32
+ const tokens = estimateTokens(entry.sigs.join('\n'));
33
+
34
+ return {
35
+ lineOfCode: loc,
36
+ sigCount: sigCount,
37
+ signalQuality: signalQuality.toFixed(3),
38
+ tokens: tokens,
39
+ relevance: (sigCount / Math.max(loc, 1)).toFixed(3),
40
+ };
41
+ }
42
+
43
+ function explainInclusion(fileEntries, budgetLimit) {
44
+ const lines = [];
45
+
46
+ lines.push('## File Inclusion Diagnostics\n');
47
+ lines.push(`Budget: ${budgetLimit} tokens`);
48
+ lines.push(`Files: ${fileEntries.length} scanned\n`);
49
+
50
+ let totalTokens = 0;
51
+ const withMetrics = fileEntries.map((e) => {
52
+ const metrics = computeFileMetrics(e);
53
+ totalTokens += metrics.tokens;
54
+ return { entry: e, metrics };
55
+ });
56
+
57
+ lines.push(`Total token requirement: ${totalTokens} tokens`);
58
+ lines.push(`Budget headroom: ${budgetLimit * 0.9} tokens (90% of ${budgetLimit})\n`);
59
+
60
+ if (totalTokens > budgetLimit * 0.9) {
61
+ lines.push('⚠ Over budget — files will be dropped\n');
62
+ lines.push('### Per-file metrics:');
63
+ for (const { entry, metrics } of withMetrics) {
64
+ const rel = path.relative(process.cwd(), entry.filePath);
65
+ lines.push(`- ${rel}`);
66
+ lines.push(` - Size: ${metrics.tokens} tokens, ${metrics.lineOfCode} lines`);
67
+ lines.push(` - Sigs: ${metrics.sigCount}, quality: ${metrics.signalQuality}`);
68
+ }
69
+ } else {
70
+ lines.push('✓ All files fit within budget\n');
71
+ }
72
+
73
+ return lines.join('\n');
74
+ }
75
+
76
+ function explainExclusion(dropped, reason) {
77
+ return `Excluded ${dropped.length} files: ${reason}`;
78
+ }
79
+
80
+ module.exports = {
81
+ formatFileDecision,
82
+ computeFileMetrics,
83
+ explainInclusion,
84
+ explainExclusion,
85
+ estimateTokens,
86
+ };
@@ -41,10 +41,10 @@ function extractImports(filePath, content, fileSet) {
41
41
  }
42
42
 
43
43
  if (PY_EXTS.has(ext)) {
44
- // from .module import ... / from ..pkg import ...
45
- const re = /^[ \t]*from\s+(\.+[\w.]*)\s+import/gm;
44
+ // Relative imports: from .module import ... / from ..pkg import ...
45
+ const reRel = /^[ \t]*from\s+(\.+[\w.]*)\s+import/gm;
46
46
  let m;
47
- while ((m = re.exec(content)) !== null) {
47
+ while ((m = reRel.exec(content)) !== null) {
48
48
  const dotCount = (m[1].match(/^\.+/) || [''])[0].length;
49
49
  const modPart = m[1].slice(dotCount).replace(/\./g, '/');
50
50
  let base = dir;
@@ -52,6 +52,24 @@ function extractImports(filePath, content, fileSet) {
52
52
  const candidate = modPart ? path.join(base, modPart + '.py') : null;
53
53
  if (candidate && fileSet.has(candidate)) found.push(candidate);
54
54
  }
55
+
56
+ // Absolute imports: from package.module import ... (infer from project structure)
57
+ const reAbs = /^[ \t]*from\s+([\w.]+)\s+import/gm;
58
+ while ((m = reAbs.exec(content)) !== null) {
59
+ const modulePath = m[1].replace(/\./g, '/');
60
+ const candidates = [
61
+ path.join(dir, modulePath + '.py'),
62
+ path.join(dir, modulePath, '__init__.py'),
63
+ path.resolve(dir, '..', modulePath + '.py'),
64
+ path.resolve(dir, '..', modulePath, '__init__.py'),
65
+ ];
66
+ for (const c of candidates) {
67
+ if (fileSet.has(c)) {
68
+ found.push(c);
69
+ break;
70
+ }
71
+ }
72
+ }
55
73
  }
56
74
 
57
75
  return [...new Set(found)];
@@ -62,12 +80,17 @@ function resolveJsPath(dir, importStr, fileSet) {
62
80
  const candidates = [
63
81
  base,
64
82
  base + '.ts', base + '.tsx',
65
- base + '.js', base + '.jsx',
66
- base + '/index.ts', base + '/index.js',
83
+ base + '.js', base + '.jsx', base + '.mjs', base + '.cjs',
84
+ base + '/index.ts', base + '/index.tsx',
85
+ base + '/index.js', base + '/index.jsx', base + '/index.mjs',
67
86
  ];
68
87
  for (const c of candidates) {
69
88
  if (fileSet.has(c)) return c;
70
89
  }
90
+
91
+ // Fallback: check if base itself is already a valid file (handles .ts/.js already in path)
92
+ if (fileSet.has(base)) return base;
93
+
71
94
  return null;
72
95
  }
73
96
 
@@ -102,6 +125,20 @@ function detectCycles(graph) {
102
125
  return cycles;
103
126
  }
104
127
 
128
+ // ---------------------------------------------------------------------------
129
+ // Build reverse graph (for caller detection)
130
+ // ---------------------------------------------------------------------------
131
+ function buildReverseGraph(graph) {
132
+ const reverse = new Map();
133
+ for (const [file, deps] of graph.entries()) {
134
+ for (const dep of deps) {
135
+ if (!reverse.has(dep)) reverse.set(dep, []);
136
+ reverse.get(dep).push(file);
137
+ }
138
+ }
139
+ return reverse;
140
+ }
141
+
105
142
  // ---------------------------------------------------------------------------
106
143
  // Public API
107
144
  // ---------------------------------------------------------------------------
@@ -145,4 +182,4 @@ function analyze(files, cwd) {
145
182
  return lines.join('\n');
146
183
  }
147
184
 
148
- module.exports = { analyze, extractImports };
185
+ module.exports = { analyze, extractImports, buildReverseGraph, resolveJsPath, detectCycles };
package/src/mcp/server.js CHANGED
@@ -18,7 +18,7 @@ const { readContext, searchSignatures, getMap, createCheckpoint, getRouting, exp
18
18
 
19
19
  const SERVER_INFO = {
20
20
  name: 'sigmap',
21
- version: '6.10.4',
21
+ version: '6.10.6',
22
22
  description: 'SigMap MCP server — code signatures on demand',
23
23
  };
24
24