agentmap 0.8.0 → 0.9.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 (83) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/README.md +24 -0
  3. package/dist/cli.js +37 -12
  4. package/dist/cli.js.map +1 -1
  5. package/dist/extract/definitions.js +12 -12
  6. package/dist/extract/definitions.js.map +1 -1
  7. package/dist/extract/definitions.test.js +30 -259
  8. package/dist/extract/definitions.test.js.map +1 -1
  9. package/dist/extract/git-status.d.ts +7 -2
  10. package/dist/extract/git-status.d.ts.map +1 -1
  11. package/dist/extract/git-status.js +12 -18
  12. package/dist/extract/git-status.js.map +1 -1
  13. package/dist/extract/markdown.js +1 -1
  14. package/dist/extract/markdown.test.js +3 -3
  15. package/dist/extract/markdown.test.js.map +1 -1
  16. package/dist/extract/marker.js +1 -1
  17. package/dist/extract/marker.test.js +4 -4
  18. package/dist/extract/marker.test.js.map +1 -1
  19. package/dist/index.d.ts +4 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +5 -4
  22. package/dist/index.js.map +1 -1
  23. package/dist/logger.d.ts +10 -0
  24. package/dist/logger.d.ts.map +1 -0
  25. package/dist/logger.js +41 -0
  26. package/dist/logger.js.map +1 -0
  27. package/dist/map/builder.d.ts.map +1 -1
  28. package/dist/map/builder.js +23 -12
  29. package/dist/map/builder.js.map +1 -1
  30. package/dist/map/builder.test.d.ts +2 -0
  31. package/dist/map/builder.test.d.ts.map +1 -0
  32. package/dist/map/builder.test.js +66 -0
  33. package/dist/map/builder.test.js.map +1 -0
  34. package/dist/map/truncate.d.ts +7 -3
  35. package/dist/map/truncate.d.ts.map +1 -1
  36. package/dist/map/truncate.js +80 -11
  37. package/dist/map/truncate.js.map +1 -1
  38. package/dist/scanner.d.ts.map +1 -1
  39. package/dist/scanner.js +164 -65
  40. package/dist/scanner.js.map +1 -1
  41. package/dist/scanner.test.d.ts +2 -0
  42. package/dist/scanner.test.d.ts.map +1 -0
  43. package/dist/scanner.test.js +84 -0
  44. package/dist/scanner.test.js.map +1 -0
  45. package/dist/test-helpers/git-test-helpers.d.ts +13 -0
  46. package/dist/test-helpers/git-test-helpers.d.ts.map +1 -0
  47. package/dist/test-helpers/git-test-helpers.js +48 -0
  48. package/dist/test-helpers/git-test-helpers.js.map +1 -0
  49. package/dist/types.d.ts +15 -1
  50. package/dist/types.d.ts.map +1 -1
  51. package/package.json +15 -3
  52. package/src/cli.ts +164 -0
  53. package/src/extract/definitions.test.ts +2040 -0
  54. package/src/extract/definitions.ts +379 -0
  55. package/src/extract/git-status.test.ts +507 -0
  56. package/src/extract/git-status.ts +359 -0
  57. package/src/extract/markdown.test.ts +159 -0
  58. package/src/extract/markdown.ts +202 -0
  59. package/src/extract/marker.test.ts +566 -0
  60. package/src/extract/marker.ts +398 -0
  61. package/src/extract/submodules.test.ts +95 -0
  62. package/src/extract/submodules.ts +269 -0
  63. package/src/extract/utils.ts +27 -0
  64. package/src/index.ts +106 -0
  65. package/src/languages/cpp.ts +129 -0
  66. package/src/languages/go.ts +72 -0
  67. package/src/languages/index.ts +231 -0
  68. package/src/languages/javascript.ts +33 -0
  69. package/src/languages/python.ts +41 -0
  70. package/src/languages/rust.ts +72 -0
  71. package/src/languages/typescript.ts +74 -0
  72. package/src/languages/zig.ts +106 -0
  73. package/src/logger.ts +55 -0
  74. package/src/map/builder.test.ts +72 -0
  75. package/src/map/builder.ts +175 -0
  76. package/src/map/truncate.ts +188 -0
  77. package/src/map/yaml.ts +66 -0
  78. package/src/parser/index.ts +53 -0
  79. package/src/parser/languages.ts +64 -0
  80. package/src/scanner.test.ts +95 -0
  81. package/src/scanner.ts +364 -0
  82. package/src/test-helpers/git-test-helpers.ts +62 -0
  83. package/src/types.ts +191 -0
@@ -1,11 +1,40 @@
1
- // Truncate definitions in map to limit context size.
1
+ // Truncate definitions and descriptions in map to limit context size.
2
2
  const DEFAULT_MAX_DEFS = 25;
3
+ const DEFAULT_MAX_DESC_CHARS = 300;
3
4
  /**
4
5
  * Check if a def value indicates exported or extern
5
6
  */
6
7
  function isExportedDef(value) {
7
8
  return value.includes('exported') || value.includes('extern');
8
9
  }
10
+ /**
11
+ * Truncate description by character count, rounding up to include the full line
12
+ * that crosses the limit (in excess).
13
+ */
14
+ function truncateDescriptionByChars(description, maxChars) {
15
+ if (description.length <= maxChars)
16
+ return description;
17
+ const lines = description.split('\n');
18
+ // Single-line fallback: hard-truncate at maxChars
19
+ if (lines.length === 1) {
20
+ return description.slice(0, maxChars) + '...';
21
+ }
22
+ let charCount = 0;
23
+ for (let i = 0; i < lines.length; i++) {
24
+ // +1 for the newline separator (except first line)
25
+ charCount += lines[i].length + (i > 0 ? 1 : 0);
26
+ if (charCount >= maxChars) {
27
+ // Include this line (in excess), then stop
28
+ const kept = lines.slice(0, i + 1);
29
+ const remaining = lines.length - kept.length;
30
+ if (remaining > 0) {
31
+ kept.push(`... and ${remaining} more lines`);
32
+ }
33
+ return kept.join('\n');
34
+ }
35
+ }
36
+ return description;
37
+ }
9
38
  /**
10
39
  * Check if a value is a FileEntry (has description or defs)
11
40
  */
@@ -23,12 +52,53 @@ function isSubmoduleEntry(value) {
23
52
  return false;
24
53
  return 'submodule' in value;
25
54
  }
55
+ /**
56
+ * Recursively truncate a submodule node while preserving its metadata keys.
57
+ */
58
+ function truncateSubmoduleNode(entry, options) {
59
+ const result = { submodule: entry.submodule };
60
+ if (entry.dirty) {
61
+ result.dirty = entry.dirty;
62
+ }
63
+ for (const [key, value] of Object.entries(entry)) {
64
+ if (key === 'submodule' || key === 'dirty') {
65
+ continue;
66
+ }
67
+ if (isFileEntry(value)) {
68
+ result[key] = truncateFileEntry(value, options);
69
+ }
70
+ else if (isSubmoduleEntry(value)) {
71
+ result[key] = truncateSubmoduleNode(value, options);
72
+ }
73
+ else if (value && typeof value === 'object') {
74
+ result[key] = truncateMap(value, options);
75
+ }
76
+ }
77
+ return result;
78
+ }
79
+ /**
80
+ * Truncate a file entry: cap description by chars and defs by count.
81
+ */
82
+ function truncateFileEntry(entry, options) {
83
+ let result = entry;
84
+ // Truncate description by character count
85
+ const maxDescChars = options.maxDescChars ?? DEFAULT_MAX_DESC_CHARS;
86
+ if (result.description && result.description.length > maxDescChars) {
87
+ result = { ...result, description: truncateDescriptionByChars(result.description, maxDescChars) };
88
+ }
89
+ // Truncate defs
90
+ result = truncateDefs(result, options.maxDefs);
91
+ return result;
92
+ }
26
93
  /**
27
94
  * Truncate definitions in a file entry to maxDefs
28
95
  * If file has exported symbols, shows only exports field instead
29
96
  * Otherwise uses current truncation behavior
30
97
  */
31
- export function truncateDefs(entry, maxDefs = DEFAULT_MAX_DEFS) {
98
+ export function truncateDefs(entry, maxDefsOrOptions) {
99
+ const maxDefs = typeof maxDefsOrOptions === 'number'
100
+ ? maxDefsOrOptions
101
+ : (maxDefsOrOptions?.maxDefs ?? DEFAULT_MAX_DEFS);
32
102
  if (!entry.defs)
33
103
  return entry;
34
104
  const defNames = Object.keys(entry.defs);
@@ -65,23 +135,22 @@ export function truncateDefs(entry, maxDefs = DEFAULT_MAX_DEFS) {
65
135
  return { ...entry, defs: truncated };
66
136
  }
67
137
  /**
68
- * Recursively truncate defs in all files in the map
138
+ * Recursively truncate defs and descriptions in all files in the map
69
139
  */
70
- export function truncateMap(node, maxDefs = DEFAULT_MAX_DEFS) {
140
+ export function truncateMap(node, maxDefsOrOptions) {
141
+ const options = typeof maxDefsOrOptions === 'number'
142
+ ? { maxDefs: maxDefsOrOptions }
143
+ : (maxDefsOrOptions ?? {});
71
144
  const result = {};
72
145
  for (const [key, value] of Object.entries(node)) {
73
146
  if (isFileEntry(value)) {
74
- result[key] = truncateDefs(value, maxDefs);
147
+ result[key] = truncateFileEntry(value, options);
75
148
  }
76
149
  else if (isSubmoduleEntry(value)) {
77
- // Submodule entries pass through unchanged (no defs to truncate)
78
- result[key] = value;
150
+ result[key] = truncateSubmoduleNode(value, options);
79
151
  }
80
152
  else if (value && typeof value === 'object') {
81
- result[key] = truncateMap(value, maxDefs);
82
- }
83
- else {
84
- result[key] = value;
153
+ result[key] = truncateMap(value, options);
85
154
  }
86
155
  }
87
156
  return result;
@@ -1 +1 @@
1
- {"version":3,"file":"truncate.js","sourceRoot":"","sources":["../../src/map/truncate.ts"],"names":[],"mappings":"AAAA,qDAAqD;AAIrD,MAAM,gBAAgB,GAAG,EAAE,CAAA;AAE3B;;GAEG;AACH,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;AAC/D,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IACrD,MAAM,GAAG,GAAG,KAAgC,CAAA;IAC5C,OAAO,aAAa,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,CAAA;AAC9C,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IACrD,OAAO,WAAW,IAAK,KAAiC,CAAA;AAC1D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAgB,EAAE,UAAkB,gBAAgB;IAC/E,IAAI,CAAC,KAAK,CAAC,IAAI;QAAE,OAAO,KAAK,CAAA;IAE7B,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACxC,IAAI,QAAQ,CAAC,MAAM,IAAI,OAAO;QAAE,OAAO,KAAK,CAAA;IAE5C,6CAA6C;IAC7C,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,IAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAE/E,wDAAwD;IACxD,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAa,EAAE,CAAA;QAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAE1D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;YAC7B,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClC,CAAC;QAED,4CAA4C;QAC5C,IAAI,aAAa,CAAC,MAAM,GAAG,OAAO,EAAE,CAAC;YACnC,MAAM,SAAS,GAAG,aAAa,CAAC,MAAM,GAAG,OAAO,CAAA;YAChD,OAAO,CAAC,UAAU,SAAS,IAAI,CAAC,GAAG,GAAG,SAAS,eAAe,CAAA;QAChE,CAAC;QAED,sCAAsC;QACtC,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAA;QAC/B,OAAO,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAA;IAC7B,CAAC;IAED,qDAAqD;IACrD,MAAM,SAAS,GAAa,EAAE,CAAA;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;QACxB,SAAS,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACpC,CAAC;IAED,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,GAAG,OAAO,CAAA;IAC3C,+CAA+C;IAC/C,SAAS,CAAC,UAAU,SAAS,IAAI,CAAC,GAAG,GAAG,SAAS,mBAAmB,CAAA;IAEpE,OAAO,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,IAAa,EAAE,UAAkB,gBAAgB;IAC3E,MAAM,MAAM,GAAY,EAAE,CAAA;IAE1B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;QAC5C,CAAC;aAAM,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;YACnC,iEAAiE;YACjE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;QACrB,CAAC;aAAM,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9C,MAAM,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,KAAgB,EAAE,OAAO,CAAC,CAAA;QACtD,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;QACrB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC"}
1
+ {"version":3,"file":"truncate.js","sourceRoot":"","sources":["../../src/map/truncate.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAA2B,aAAa,EAAE,MAAM,YAAY,CAAA;AAuDrG;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,UAAU,EAAE,CAAA;IACnB,UAAU,EAAE,aAAa,EAAE,CAAA;CAC5B;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,UAAU,CAAC,CA+FtF"}
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAA2B,aAAa,EAAE,MAAM,YAAY,CAAA;AAsHrG;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,UAAU,EAAE,CAAA;IACnB,UAAU,EAAE,aAAa,EAAE,CAAA;CAC5B;AAuJD;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,UAAU,CAAC,CAetF"}
package/dist/scanner.js CHANGED
@@ -1,5 +1,6 @@
1
- // Scan directory for files with header comments/docstrings.
1
+ // Scan directory for files with header comments/docstrings and recurse into submodules.
2
2
  import { execSync } from 'child_process';
3
+ import { realpathSync } from 'fs';
3
4
  import pLimit from 'p-limit';
4
5
  import picomatch from 'picomatch';
5
6
  import { readFile } from 'fs/promises';
@@ -8,6 +9,7 @@ import { extractMarkerFromCode, extractMarkdownDescription } from './extract/mar
8
9
  import { extractDefinitions } from './extract/definitions.js';
9
10
  import { getAllDiffData, applyDiffToDefinitions } from './extract/git-status.js';
10
11
  import { getSubmodules, getSubmodulePaths } from './extract/submodules.js';
12
+ import { createConsoleLogger } from './logger.js';
11
13
  import { parseCode, detectLanguage, LANGUAGE_EXTENSIONS } from './parser/index.js';
12
14
  /**
13
15
  * Maximum number of files to process (safety limit)
@@ -33,116 +35,213 @@ function isReadmeFile(filepath) {
33
35
  return filename === 'readme.md' || filename === 'readme';
34
36
  }
35
37
  /**
36
- * Get tracked files using git ls-files
37
- * Only returns files that are tracked by git (committed or staged)
38
+ * Get tracked files using git ls-files -z -s.
39
+ * NUL-delimited for safe cross-platform parsing of any filename.
40
+ * Filters out symlinks (mode 120000).
41
+ * Returns path + blob SHA for duplicate detection.
42
+ *
43
+ * Format per entry: "<mode> <sha> <stage>\t<path>\0"
38
44
  */
39
45
  function getGitFiles(dir) {
40
46
  const maxBuffer = 1024 * 10000000;
41
47
  try {
42
- // Get only tracked files
43
- const stdout = execSync('git ls-files', {
48
+ const stdout = execSync('git ls-files -z -s', {
44
49
  cwd: dir,
45
50
  maxBuffer,
46
51
  encoding: 'utf8',
47
52
  });
48
- return stdout
49
- .split(/\r?\n/)
50
- .map(x => x.trim())
51
- .filter(Boolean)
52
- .map(normalize);
53
+ const results = [];
54
+ // Split on NUL byte, filter empty trailing entry
55
+ const entries = stdout.split('\0').filter(Boolean);
56
+ for (const entry of entries) {
57
+ // Format: "<mode> <sha> <stage>\t<path>"
58
+ const tabIdx = entry.indexOf('\t');
59
+ if (tabIdx === -1)
60
+ continue;
61
+ const meta = entry.slice(0, tabIdx);
62
+ const path = entry.slice(tabIdx + 1);
63
+ const spaceIdx = meta.indexOf(' ');
64
+ if (spaceIdx === -1)
65
+ continue;
66
+ const mode = meta.slice(0, spaceIdx);
67
+ const sha = meta.slice(spaceIdx + 1, meta.indexOf(' ', spaceIdx + 1));
68
+ // Skip symlinks (mode 120000)
69
+ if (mode === '120000')
70
+ continue;
71
+ results.push({ path: normalize(path), sha });
72
+ }
73
+ return results;
53
74
  }
54
75
  catch {
55
76
  return [];
56
77
  }
57
78
  }
58
79
  /**
59
- * Scan directory and process files with header comments
80
+ * Build a map of blob SHA shortest path for duplicate detection.
81
+ * Files sharing the same blob SHA are exact duplicates in git.
60
82
  */
61
- export async function scanDirectory(options = {}) {
62
- const dir = options.dir ?? process.cwd();
63
- // Filter out null/undefined/empty patterns (cac can pass [null] when option not used)
64
- const ignorePatterns = (options.ignore ?? []).filter((p) => !!p);
65
- const filterPatterns = (options.filter ?? []).filter((p) => !!p);
66
- const includeDiff = options.diff ?? false;
67
- const includeSubmodules = options.submodules !== false; // default true
68
- // Detect submodules first (needed for both map entries and diff filtering)
69
- let submodules = [];
70
- let submodulePathSet = new Set();
71
- if (includeSubmodules) {
72
- submodules = getSubmodules(dir);
73
- submodulePathSet = new Set(submodules.map(s => s.path));
83
+ function buildDuplicateMap(files, pathPrefix) {
84
+ // Group paths by SHA
85
+ const shaToEntries = new Map();
86
+ for (const { path, sha } of files) {
87
+ const prefixed = joinRelativePath(pathPrefix, path);
88
+ const existing = shaToEntries.get(sha);
89
+ if (existing) {
90
+ existing.push(prefixed);
91
+ }
92
+ else {
93
+ shaToEntries.set(sha, [prefixed]);
94
+ }
95
+ }
96
+ // For each group with >1 file, shortest path is the original
97
+ const duplicateOf = new Map();
98
+ for (const paths of shaToEntries.values()) {
99
+ if (paths.length < 2)
100
+ continue;
101
+ paths.sort((a, b) => a.length - b.length || a.localeCompare(b));
102
+ const original = paths[0];
103
+ for (let i = 1; i < paths.length; i++) {
104
+ duplicateOf.set(paths[i], original);
105
+ }
106
+ }
107
+ return duplicateOf;
108
+ }
109
+ function normalizeRelativePath(path) {
110
+ return path.replace(/\\/g, '/');
111
+ }
112
+ function joinRelativePath(prefix, path) {
113
+ const normalizedPath = normalizeRelativePath(path);
114
+ return prefix ? `${prefix}/${normalizedPath}` : normalizedPath;
115
+ }
116
+ function getCanonicalRepoDir(dir) {
117
+ try {
118
+ return realpathSync(dir);
119
+ }
120
+ catch {
121
+ return dir;
74
122
  }
75
- else {
76
- // Even when not showing submodules, detect paths for diff filtering
77
- submodulePathSet = getSubmodulePaths(dir);
123
+ }
124
+ async function scanRepo(options) {
125
+ const canonicalRepoDir = getCanonicalRepoDir(options.repoDir);
126
+ if (options.visitedRepoDirs.has(canonicalRepoDir)) {
127
+ return { files: [], submodules: [] };
128
+ }
129
+ options.visitedRepoDirs.add(canonicalRepoDir);
130
+ let submodules = [];
131
+ const directSubmodules = options.includeSubmodules ? getSubmodules(options.repoDir) : [];
132
+ const directSubmodulePathSet = options.includeSubmodules
133
+ ? new Set(directSubmodules.map(submodule => submodule.path))
134
+ : getSubmodulePaths(options.repoDir);
135
+ if (options.includeSubmodules) {
136
+ submodules = directSubmodules.map(submodule => ({
137
+ ...submodule,
138
+ path: joinRelativePath(options.pathPrefix, submodule.path),
139
+ }));
78
140
  }
79
- // Build a normalized set for filtering (handles Windows backslash paths)
80
141
  const normalizedSubmodulePaths = new Set();
81
- for (const p of submodulePathSet) {
82
- normalizedSubmodulePaths.add(normalize(p));
83
- }
84
- // Get file list from git (caller should ensure we're in a git repo)
85
- let files = getGitFiles(dir);
86
- // Filter out submodule gitlink entries (they appear as paths in ls-files)
87
- // Use normalized paths to handle Windows backslash vs forward slash differences
88
- files = files.filter(f => !normalizedSubmodulePaths.has(f));
89
- // Filter by supported extensions or README files
90
- files = files.filter(f => isSupportedFile(f) || isReadmeFile(f));
91
- // Filter by filter patterns (only include matching files)
92
- if (filterPatterns.length > 0) {
93
- const isIncluded = picomatch(filterPatterns);
94
- files = files.filter(f => isIncluded(f));
95
- }
96
- // Filter by ignore patterns
97
- if (ignorePatterns.length > 0) {
98
- const isIgnored = picomatch(ignorePatterns);
99
- files = files.filter(f => !isIgnored(f));
100
- }
101
- // Safety check: bail if too many files to avoid scanning huge directories
102
- if (files.length > MAX_FILES) {
103
- console.error(`Warning: Too many files (${files.length} > ${MAX_FILES}), skipping scan`);
142
+ for (const path of directSubmodulePathSet) {
143
+ normalizedSubmodulePaths.add(normalize(path));
144
+ }
145
+ const allGitFiles = getGitFiles(options.repoDir);
146
+ // Build duplicate map before filtering (needs all files to detect dupes)
147
+ const duplicateOf = buildDuplicateMap(allGitFiles, options.pathPrefix);
148
+ let gitFiles = allGitFiles.filter(f => !normalizedSubmodulePaths.has(f.path));
149
+ gitFiles = gitFiles.filter(f => isSupportedFile(f.path) || isReadmeFile(f.path));
150
+ gitFiles = gitFiles.filter(f => {
151
+ const relativePath = joinRelativePath(options.pathPrefix, f.path);
152
+ if (options.isIncluded && !options.isIncluded(relativePath)) {
153
+ return false;
154
+ }
155
+ if (options.isIgnored && options.isIgnored(relativePath)) {
156
+ return false;
157
+ }
158
+ return true;
159
+ });
160
+ if (gitFiles.length > MAX_FILES) {
161
+ options.logger?.warn(`Warning: Too many files (${gitFiles.length} > ${MAX_FILES}), skipping scan`);
104
162
  return { files: [], submodules };
105
163
  }
106
- // Get git diff data if needed (isolated from main processing)
107
164
  let fileStats = null;
108
165
  let fileDiffs = null;
109
- if (includeDiff) {
166
+ if (options.includeDiff) {
110
167
  try {
111
- const diffData = getAllDiffData(dir, submodulePathSet);
168
+ const diffData = getAllDiffData(options.repoDir, directSubmodulePathSet, options.logger);
112
169
  fileStats = diffData.fileStats;
113
170
  fileDiffs = diffData.fileDiffs;
114
171
  }
115
172
  catch {
116
- // Diff failed - continue without diff info
117
173
  fileStats = null;
118
174
  fileDiffs = null;
119
175
  }
120
176
  }
121
- // Process files in parallel with concurrency limit
122
177
  const limit = pLimit(20);
123
- const resultPromises = files.map(relativePath => {
124
- const fullPath = join(dir, relativePath);
125
- // Normalize path for lookup (handle Windows backslashes)
126
- const normalizedPath = relativePath.replace(/\\/g, '/');
178
+ const resultPromises = gitFiles.map(({ path: relativePath }) => {
179
+ const fullPath = join(options.repoDir, relativePath);
180
+ const normalizedPath = normalizeRelativePath(relativePath);
181
+ const prefixedRelativePath = joinRelativePath(options.pathPrefix, relativePath);
127
182
  const fileDiff = fileDiffs?.get(normalizedPath);
128
183
  const stats = fileStats?.get(normalizedPath);
184
+ const dupOriginal = duplicateOf.get(prefixedRelativePath);
129
185
  return limit(async () => {
130
186
  try {
131
- return await processFile(fullPath, relativePath, fileDiff, stats);
187
+ // If this file is a duplicate, return a stub pointing to the original
188
+ if (dupOriginal) {
189
+ return {
190
+ relativePath: prefixedRelativePath,
191
+ duplicateOf: dupOriginal,
192
+ definitions: [],
193
+ };
194
+ }
195
+ return await processFile(fullPath, prefixedRelativePath, fileDiff, stats);
132
196
  }
133
- catch (err) {
134
- // Skip files that fail to process
135
- console.error(`Warning: Failed to process ${relativePath}:`, err);
197
+ catch {
136
198
  return null;
137
199
  }
138
200
  });
139
201
  });
202
+ const nestedResults = options.includeSubmodules
203
+ ? await Promise.all(directSubmodules.map(async (submodule) => {
204
+ if (!submodule.initialized) {
205
+ return { files: [], submodules: [] };
206
+ }
207
+ return scanRepo({
208
+ ...options,
209
+ repoDir: join(options.repoDir, submodule.path),
210
+ pathPrefix: joinRelativePath(options.pathPrefix, submodule.path),
211
+ });
212
+ }))
213
+ : [];
140
214
  const results = await Promise.all(resultPromises);
215
+ for (const nested of nestedResults) {
216
+ submodules.push(...nested.submodules);
217
+ }
141
218
  return {
142
- files: results.filter((r) => r !== null),
219
+ files: [
220
+ ...results.filter((result) => result !== null),
221
+ ...nestedResults.flatMap(result => result.files),
222
+ ],
143
223
  submodules,
144
224
  };
145
225
  }
226
+ /**
227
+ * Scan directory and process files with header comments
228
+ */
229
+ export async function scanDirectory(options = {}) {
230
+ const dir = options.dir ?? process.cwd();
231
+ const logger = options.logger ?? createConsoleLogger();
232
+ const ignorePatterns = (options.ignore ?? []).filter((p) => !!p);
233
+ const filterPatterns = (options.filter ?? []).filter((p) => !!p);
234
+ return scanRepo({
235
+ repoDir: dir,
236
+ pathPrefix: '',
237
+ includeDiff: options.diff ?? false,
238
+ includeSubmodules: options.submodules !== false,
239
+ logger,
240
+ isIncluded: filterPatterns.length > 0 ? picomatch(filterPatterns) : undefined,
241
+ isIgnored: ignorePatterns.length > 0 ? picomatch(ignorePatterns) : undefined,
242
+ visitedRepoDirs: new Set(),
243
+ });
244
+ }
146
245
  /**
147
246
  * Process a single file - check for marker and extract definitions
148
247
  */
@@ -1 +1 @@
1
- {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=scanner.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.test.d.ts","sourceRoot":"","sources":["../src/scanner.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,84 @@
1
+ // Tests for recursive scanning across initialized git submodules.
2
+ import { describe, expect, test } from 'bun:test';
3
+ import { scanDirectory } from './scanner.js';
4
+ import { addSubmodule, commitAll, createRepo, deinitSubmodule, updateSubmodulesRecursive, writeTrackedFile } from './test-helpers/git-test-helpers.js';
5
+ describe('scanDirectory submodule recursion', () => {
6
+ test('includes files from initialized nested submodules under prefixed paths', async () => {
7
+ const nestedRepo = createRepo('agentmap-submodule-nested-');
8
+ writeTrackedFile(nestedRepo, 'README.md', '# Nested repo\n\nNested submodule README.');
9
+ commitAll(nestedRepo, 'Add nested repo README');
10
+ const childRepo = createRepo('agentmap-submodule-child-');
11
+ writeTrackedFile(childRepo, 'README.md', '# Child repo\n\nChild submodule README.');
12
+ commitAll(childRepo, 'Add child repo README');
13
+ addSubmodule(childRepo, nestedRepo.dir, 'deps/nested-lib');
14
+ commitAll(childRepo, 'Add nested submodule');
15
+ const rootRepo = createRepo('agentmap-submodule-root-');
16
+ writeTrackedFile(rootRepo, 'README.md', '# Root repo\n\nRoot repo README.');
17
+ commitAll(rootRepo, 'Add root README');
18
+ addSubmodule(rootRepo, childRepo.dir, 'vendor/child-lib');
19
+ commitAll(rootRepo, 'Add child submodule');
20
+ updateSubmodulesRecursive(rootRepo);
21
+ const result = await scanDirectory({ dir: rootRepo.dir });
22
+ expect(result.files.map(file => file.relativePath).sort()).toMatchInlineSnapshot(`
23
+ [
24
+ "README.md",
25
+ "vendor/child-lib/README.md",
26
+ "vendor/child-lib/deps/nested-lib/README.md",
27
+ ]
28
+ `);
29
+ expect(result.submodules.map(submodule => ({
30
+ path: submodule.path,
31
+ initialized: submodule.initialized,
32
+ dirty: submodule.dirty,
33
+ commitLength: submodule.commit.length,
34
+ }))).toMatchInlineSnapshot(`
35
+ [
36
+ {
37
+ "commitLength": 7,
38
+ "dirty": false,
39
+ "initialized": true,
40
+ "path": "vendor/child-lib",
41
+ },
42
+ {
43
+ "commitLength": 7,
44
+ "dirty": false,
45
+ "initialized": true,
46
+ "path": "vendor/child-lib/deps/nested-lib",
47
+ },
48
+ ]
49
+ `);
50
+ });
51
+ test('keeps uninitialized submodules as metadata-only nodes', async () => {
52
+ const childRepo = createRepo('agentmap-submodule-uninit-child-');
53
+ writeTrackedFile(childRepo, 'README.md', '# Child repo\n\nChild submodule README.');
54
+ commitAll(childRepo, 'Add child repo README');
55
+ const rootRepo = createRepo('agentmap-submodule-uninit-root-');
56
+ writeTrackedFile(rootRepo, 'README.md', '# Root repo\n\nRoot repo README.');
57
+ commitAll(rootRepo, 'Add root README');
58
+ addSubmodule(rootRepo, childRepo.dir, 'vendor/child-lib');
59
+ commitAll(rootRepo, 'Add child submodule');
60
+ deinitSubmodule(rootRepo, 'vendor/child-lib');
61
+ const result = await scanDirectory({ dir: rootRepo.dir });
62
+ expect(result.files.map(file => file.relativePath).sort()).toMatchInlineSnapshot(`
63
+ [
64
+ "README.md",
65
+ ]
66
+ `);
67
+ expect(result.submodules.map(submodule => ({
68
+ path: submodule.path,
69
+ initialized: submodule.initialized,
70
+ dirty: submodule.dirty,
71
+ commitLength: submodule.commit.length,
72
+ }))).toMatchInlineSnapshot(`
73
+ [
74
+ {
75
+ "commitLength": 7,
76
+ "dirty": false,
77
+ "initialized": false,
78
+ "path": "vendor/child-lib",
79
+ },
80
+ ]
81
+ `);
82
+ });
83
+ });
84
+ //# sourceMappingURL=scanner.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.test.js","sourceRoot":"","sources":["../src/scanner.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export interface TempRepo {
2
+ dir: string;
3
+ }
4
+ export declare function createTempDir(prefix: string): string;
5
+ export declare function initRepo(dir: string): TempRepo;
6
+ export declare function createRepo(prefix: string): TempRepo;
7
+ export declare function writeTrackedFile(repo: TempRepo, relativePath: string, content: string): void;
8
+ export declare function commitAll(repo: TempRepo, message: string): void;
9
+ export declare function shortHead(repo: TempRepo): string;
10
+ export declare function addSubmodule(repo: TempRepo, sourceDir: string, targetPath: string): void;
11
+ export declare function updateSubmodulesRecursive(repo: TempRepo): void;
12
+ export declare function deinitSubmodule(repo: TempRepo, targetPath: string): void;
13
+ //# sourceMappingURL=git-test-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-test-helpers.d.ts","sourceRoot":"","sources":["../../src/test-helpers/git-test-helpers.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAA;CACZ;AAUD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAK9C;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAInD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAI5F;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAG/D;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAEhD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAExF;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAE9D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAExE"}