agentmap 0.1.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 (42) hide show
  1. package/README.md +129 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +36 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/extract/definitions.d.ts +6 -0
  7. package/dist/extract/definitions.d.ts.map +1 -0
  8. package/dist/extract/definitions.js +207 -0
  9. package/dist/extract/definitions.js.map +1 -0
  10. package/dist/extract/marker.d.ts +7 -0
  11. package/dist/extract/marker.d.ts.map +1 -0
  12. package/dist/extract/marker.js +144 -0
  13. package/dist/extract/marker.js.map +1 -0
  14. package/dist/index.d.ts +11 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +23 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/map/builder.d.ts +10 -0
  19. package/dist/map/builder.d.ts.map +1 -0
  20. package/dist/map/builder.js +53 -0
  21. package/dist/map/builder.js.map +1 -0
  22. package/dist/map/yaml.d.ts +6 -0
  23. package/dist/map/yaml.d.ts.map +1 -0
  24. package/dist/map/yaml.js +17 -0
  25. package/dist/map/yaml.js.map +1 -0
  26. package/dist/parser/index.d.ts +15 -0
  27. package/dist/parser/index.d.ts.map +1 -0
  28. package/dist/parser/index.js +46 -0
  29. package/dist/parser/index.js.map +1 -0
  30. package/dist/parser/languages.d.ts +19 -0
  31. package/dist/parser/languages.d.ts.map +1 -0
  32. package/dist/parser/languages.js +80 -0
  33. package/dist/parser/languages.js.map +1 -0
  34. package/dist/scanner.d.ts +6 -0
  35. package/dist/scanner.d.ts.map +1 -0
  36. package/dist/scanner.js +139 -0
  37. package/dist/scanner.js.map +1 -0
  38. package/dist/types.d.ts +62 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +4 -0
  41. package/dist/types.js.map +1 -0
  42. package/package.json +54 -0
package/README.md ADDED
@@ -0,0 +1,129 @@
1
+ # mappamundi
2
+
3
+ A compact, YAML-based inventory of your codebase, intended to be prepended to a coding agent's context at session start.
4
+
5
+ ## Purpose
6
+
7
+ - Give the agent a fast, structured overview of files and responsibilities
8
+ - Provide jump targets via top-level `defs` (functions/classes with line numbers)
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install mappamundi
14
+ ```
15
+
16
+ ## CLI Usage
17
+
18
+ ```bash
19
+ # Map current directory
20
+ npx mappamundi
21
+
22
+ # Map specific directory
23
+ npx mappamundi ./src
24
+
25
+ # Write to file
26
+ npx mappamundi -o map.yaml
27
+
28
+ # Ignore patterns
29
+ npx mappamundi --ignore "dist/**" --ignore "**/test/**"
30
+ ```
31
+
32
+ ### Options
33
+
34
+ ```
35
+ -o, --output <file> Write output to file (default: stdout)
36
+ -i, --ignore <pattern> Ignore pattern (can be repeated)
37
+ -h, --help Show help
38
+ -v, --version Show version
39
+ ```
40
+
41
+ ## Library Usage
42
+
43
+ ```typescript
44
+ import { generateMap, generateMapYaml } from 'mappamundi'
45
+
46
+ // Get as object
47
+ const map = await generateMap({ dir: './src' })
48
+
49
+ // Get as YAML string
50
+ const yaml = await generateMapYaml({ dir: './src' })
51
+
52
+ // With ignore patterns
53
+ const yaml = await generateMapYaml({
54
+ dir: './src',
55
+ ignore: ['**/test/**', '**/*.spec.ts']
56
+ })
57
+ ```
58
+
59
+ ## Marking Files
60
+
61
+ Only files with the `@mappamundi` marker comment are included. Add it to the top of files you want in the map:
62
+
63
+ ```typescript
64
+ // @mappamundi
65
+ // CLI entrypoint.
66
+ // Parses args, wires deps, calls into lib/.
67
+
68
+ export function main() { ... }
69
+ ```
70
+
71
+ ```python
72
+ # @mappamundi
73
+ # Parsing + normalization utilities.
74
+
75
+ def parse_input(): ...
76
+ ```
77
+
78
+ Block comments also work:
79
+
80
+ ```typescript
81
+ /**
82
+ * @mappamundi
83
+ * Core data structures.
84
+ */
85
+ ```
86
+
87
+ ## Output Format
88
+
89
+ ```yaml
90
+ my-project:
91
+ src:
92
+ main.py:
93
+ desc: |
94
+ CLI entrypoint.
95
+ Parses args, wires deps, calls into lib/.
96
+ defs:
97
+ main: 12
98
+ parse_args: 34
99
+ App: 58
100
+ lib:
101
+ parse.py:
102
+ desc: |
103
+ Parsing + normalization utilities.
104
+ defs:
105
+ parse_input: 10
106
+ ASTNode: 41
107
+ ```
108
+
109
+ ### Format Rules
110
+
111
+ - Directories are YAML mappings
112
+ - Files have optional `desc` (description) and `defs` (definitions)
113
+ - `desc` uses YAML literal block scalar (`|`) for multi-line text
114
+ - `defs` maps symbol names to 1-based line numbers
115
+ - Only top-level `function` and `class` definitions are included
116
+
117
+ ## Supported Languages
118
+
119
+ | Language | Extensions |
120
+ |------------|---------------------------|
121
+ | TypeScript | .ts .tsx .mts .cts |
122
+ | JavaScript | .js .jsx .mjs .cjs |
123
+ | Python | .py .pyi |
124
+ | Rust | .rs |
125
+ | Go | .go |
126
+
127
+ ## License
128
+
129
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env node
2
+ // @mappamundi
3
+ // CLI entrypoint for generating codebase maps.
4
+ import { writeFile } from 'fs/promises';
5
+ import { resolve } from 'path';
6
+ import { cac } from 'cac';
7
+ import { generateMapYaml } from './index.js';
8
+ const cli = cac('agentmap');
9
+ cli
10
+ .command('[dir]', 'Generate a YAML map of the codebase')
11
+ .option('-o, --output <file>', 'Write output to file (default: stdout)')
12
+ .option('-i, --ignore <pattern>', 'Ignore pattern (can be repeated)', { type: [] })
13
+ .action(async (dir, options) => {
14
+ const targetDir = resolve(dir ?? '.');
15
+ try {
16
+ const yaml = await generateMapYaml({
17
+ dir: targetDir,
18
+ ignore: options.ignore,
19
+ });
20
+ if (options.output) {
21
+ await writeFile(options.output, yaml, 'utf8');
22
+ console.error(`Wrote map to ${options.output}`);
23
+ }
24
+ else {
25
+ console.log(yaml);
26
+ }
27
+ }
28
+ catch (err) {
29
+ console.error('Error:', err instanceof Error ? err.message : err);
30
+ process.exit(1);
31
+ }
32
+ });
33
+ cli.help();
34
+ cli.version('0.1.0');
35
+ cli.parse();
36
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,cAAc;AACd,+CAA+C;AAE/C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAC9B,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAE5C,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,CAAA;AAE3B,GAAG;KACA,OAAO,CAAC,OAAO,EAAE,qCAAqC,CAAC;KACvD,MAAM,CAAC,qBAAqB,EAAE,wCAAwC,CAAC;KACvE,MAAM,CAAC,wBAAwB,EAAE,kCAAkC,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;KAClF,MAAM,CAAC,KAAK,EAAE,GAAuB,EAAE,OAA+C,EAAE,EAAE;IACzF,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAA;IAErC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC;YACjC,GAAG,EAAE,SAAS;YACd,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAA;QAEF,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;YAC7C,OAAO,CAAC,KAAK,CAAC,gBAAgB,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;QACjD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACnB,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC,CAAC,CAAA;AAEJ,GAAG,CAAC,IAAI,EAAE,CAAA;AACV,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;AAEpB,GAAG,CAAC,KAAK,EAAE,CAAA"}
@@ -0,0 +1,6 @@
1
+ import type { Definition, Language, SyntaxNode } from '../types.js';
2
+ /**
3
+ * Extract top-level definitions from a syntax tree
4
+ */
5
+ export declare function extractDefinitions(rootNode: SyntaxNode, language: Language): Definition[];
6
+ //# sourceMappingURL=definitions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/extract/definitions.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAwBnE;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,UAAU,EACpB,QAAQ,EAAE,QAAQ,GACjB,UAAU,EAAE,CAmDd"}
@@ -0,0 +1,207 @@
1
+ // @mappamundi
2
+ // Extract top-level function and class definitions using tree-sitter.
3
+ /**
4
+ * Node types that represent functions per language
5
+ */
6
+ const FUNCTION_TYPES = {
7
+ typescript: ['function_declaration', 'method_definition'],
8
+ javascript: ['function_declaration', 'method_definition'],
9
+ python: ['function_definition'],
10
+ rust: ['function_item'],
11
+ go: ['function_declaration', 'method_declaration'],
12
+ };
13
+ /**
14
+ * Node types that represent classes per language
15
+ */
16
+ const CLASS_TYPES = {
17
+ typescript: ['class_declaration', 'abstract_class_declaration'],
18
+ javascript: ['class_declaration'],
19
+ python: ['class_definition'],
20
+ rust: ['struct_item', 'enum_item', 'impl_item', 'trait_item'],
21
+ go: ['type_declaration'],
22
+ };
23
+ /**
24
+ * Extract top-level definitions from a syntax tree
25
+ */
26
+ export function extractDefinitions(rootNode, language) {
27
+ const definitions = [];
28
+ const functionTypes = FUNCTION_TYPES[language];
29
+ const classTypes = CLASS_TYPES[language];
30
+ // Walk immediate children of root (top-level only)
31
+ for (let i = 0; i < rootNode.childCount; i++) {
32
+ const node = rootNode.child(i);
33
+ if (!node)
34
+ continue;
35
+ // Handle export statements (unwrap to get actual declaration)
36
+ const actualNode = unwrapExport(node);
37
+ // Check for function
38
+ if (functionTypes.includes(actualNode.type)) {
39
+ const name = extractName(actualNode, language);
40
+ if (name) {
41
+ definitions.push({
42
+ name,
43
+ line: actualNode.startPosition.row + 1, // 1-based
44
+ type: 'function',
45
+ });
46
+ }
47
+ }
48
+ // Check for class
49
+ if (classTypes.includes(actualNode.type)) {
50
+ const name = extractName(actualNode, language);
51
+ if (name) {
52
+ definitions.push({
53
+ name,
54
+ line: actualNode.startPosition.row + 1, // 1-based
55
+ type: 'class',
56
+ });
57
+ }
58
+ }
59
+ // Handle variable declarations with arrow functions (TS/JS)
60
+ if (language === 'typescript' || language === 'javascript') {
61
+ const arrowFn = extractArrowFunction(actualNode);
62
+ if (arrowFn) {
63
+ definitions.push({
64
+ name: arrowFn.name,
65
+ line: arrowFn.line,
66
+ type: 'function',
67
+ });
68
+ }
69
+ }
70
+ }
71
+ return definitions;
72
+ }
73
+ /**
74
+ * Unwrap export statement to get the actual declaration
75
+ */
76
+ function unwrapExport(node) {
77
+ if (node.type === 'export_statement') {
78
+ // Find the declaration child
79
+ for (let i = 0; i < node.childCount; i++) {
80
+ const child = node.child(i);
81
+ if (!child)
82
+ continue;
83
+ // Skip 'export' keyword and other tokens
84
+ if (child.type !== 'export' && !child.type.includes('comment')) {
85
+ return child;
86
+ }
87
+ }
88
+ }
89
+ return node;
90
+ }
91
+ /**
92
+ * Extract the name from a definition node
93
+ */
94
+ function extractName(node, language) {
95
+ // Try to find 'name' field first
96
+ const nameNode = node.childForFieldName('name');
97
+ if (nameNode) {
98
+ return nameNode.text;
99
+ }
100
+ // Language-specific fallbacks
101
+ switch (language) {
102
+ case 'typescript':
103
+ case 'javascript':
104
+ return extractJSName(node);
105
+ case 'python':
106
+ return extractPythonName(node);
107
+ case 'rust':
108
+ return extractRustName(node);
109
+ case 'go':
110
+ return extractGoName(node);
111
+ }
112
+ return null;
113
+ }
114
+ function extractJSName(node) {
115
+ // Look for identifier or type_identifier child
116
+ for (let i = 0; i < node.childCount; i++) {
117
+ const child = node.child(i);
118
+ if (!child)
119
+ continue;
120
+ if (child.type === 'identifier' || child.type === 'type_identifier') {
121
+ return child.text;
122
+ }
123
+ if (child.type === 'property_identifier') {
124
+ return child.text;
125
+ }
126
+ }
127
+ return null;
128
+ }
129
+ function extractPythonName(node) {
130
+ for (let i = 0; i < node.childCount; i++) {
131
+ const child = node.child(i);
132
+ if (child?.type === 'identifier') {
133
+ return child.text;
134
+ }
135
+ }
136
+ return null;
137
+ }
138
+ function extractRustName(node) {
139
+ // For impl blocks, try to get the type name
140
+ if (node.type === 'impl_item') {
141
+ const typeNode = node.childForFieldName('type');
142
+ if (typeNode) {
143
+ // Get the type identifier
144
+ const ident = typeNode.type === 'type_identifier'
145
+ ? typeNode
146
+ : findChild(typeNode, 'type_identifier');
147
+ return ident?.text ?? null;
148
+ }
149
+ }
150
+ for (let i = 0; i < node.childCount; i++) {
151
+ const child = node.child(i);
152
+ if (child?.type === 'identifier' || child?.type === 'type_identifier') {
153
+ return child.text;
154
+ }
155
+ }
156
+ return null;
157
+ }
158
+ function extractGoName(node) {
159
+ // For type declarations, look in type_spec
160
+ if (node.type === 'type_declaration') {
161
+ const spec = findChild(node, 'type_spec');
162
+ if (spec) {
163
+ const nameNode = spec.childForFieldName('name');
164
+ return nameNode?.text ?? null;
165
+ }
166
+ }
167
+ for (let i = 0; i < node.childCount; i++) {
168
+ const child = node.child(i);
169
+ if (child?.type === 'identifier' || child?.type === 'field_identifier') {
170
+ return child.text;
171
+ }
172
+ }
173
+ return null;
174
+ }
175
+ /**
176
+ * Extract arrow function assigned to const/let
177
+ */
178
+ function extractArrowFunction(node) {
179
+ if (node.type !== 'lexical_declaration')
180
+ return null;
181
+ for (let i = 0; i < node.childCount; i++) {
182
+ const declarator = node.child(i);
183
+ if (declarator?.type !== 'variable_declarator')
184
+ continue;
185
+ const nameNode = declarator.childForFieldName('name');
186
+ const valueNode = declarator.childForFieldName('value');
187
+ if (nameNode && valueNode?.type === 'arrow_function') {
188
+ return {
189
+ name: nameNode.text,
190
+ line: node.startPosition.row + 1,
191
+ };
192
+ }
193
+ }
194
+ return null;
195
+ }
196
+ /**
197
+ * Find a child node by type
198
+ */
199
+ function findChild(node, type) {
200
+ for (let i = 0; i < node.childCount; i++) {
201
+ const child = node.child(i);
202
+ if (child?.type === type)
203
+ return child;
204
+ }
205
+ return null;
206
+ }
207
+ //# sourceMappingURL=definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/extract/definitions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { MarkerResult } from '../types.js';
2
+ /**
3
+ * Check if file has @mappamundi marker and extract description.
4
+ * Only reads first ~30KB of file for performance.
5
+ */
6
+ export declare function extractMarker(filepath: string): Promise<MarkerResult>;
7
+ //# sourceMappingURL=marker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marker.d.ts","sourceRoot":"","sources":["../../src/extract/marker.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAmB/C;;;GAGG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAgC3E"}
@@ -0,0 +1,144 @@
1
+ // @mappamundi
2
+ // Extract @mappamundi marker and description from file header.
3
+ import { open } from 'fs/promises';
4
+ const MARKER = '@mappamundi';
5
+ const MAX_BYTES = 30_000; // ~300 lines worth
6
+ /**
7
+ * Read the first N bytes of a file
8
+ */
9
+ async function readHead(filepath, maxBytes) {
10
+ const handle = await open(filepath, 'r');
11
+ try {
12
+ const buffer = Buffer.alloc(maxBytes);
13
+ const { bytesRead } = await handle.read(buffer, 0, maxBytes, 0);
14
+ return buffer.toString('utf8', 0, bytesRead);
15
+ }
16
+ finally {
17
+ await handle.close();
18
+ }
19
+ }
20
+ /**
21
+ * Check if file has @mappamundi marker and extract description.
22
+ * Only reads first ~30KB of file for performance.
23
+ */
24
+ export async function extractMarker(filepath) {
25
+ const head = await readHead(filepath, MAX_BYTES);
26
+ const lines = head.split('\n');
27
+ // Find the marker line
28
+ let markerLineIndex = -1;
29
+ for (let i = 0; i < lines.length; i++) {
30
+ const line = lines[i].trim();
31
+ // Skip empty lines at start
32
+ if (line === '')
33
+ continue;
34
+ // Check if this line contains the marker
35
+ if (line.includes(MARKER)) {
36
+ markerLineIndex = i;
37
+ break;
38
+ }
39
+ // If we hit a non-comment, non-empty line before finding marker, stop
40
+ if (!isCommentLine(line)) {
41
+ return { found: false };
42
+ }
43
+ }
44
+ if (markerLineIndex === -1) {
45
+ return { found: false };
46
+ }
47
+ // Extract description from lines after marker
48
+ const description = extractDescription(lines, markerLineIndex);
49
+ return {
50
+ found: true,
51
+ description: description || undefined,
52
+ };
53
+ }
54
+ /**
55
+ * Check if a line is a comment
56
+ */
57
+ function isCommentLine(line) {
58
+ const trimmed = line.trim();
59
+ return (trimmed.startsWith('//') ||
60
+ trimmed.startsWith('#') ||
61
+ trimmed.startsWith('/*') ||
62
+ trimmed.startsWith('*') ||
63
+ trimmed.startsWith('"""') ||
64
+ trimmed.startsWith("'''") ||
65
+ trimmed.endsWith('*/') ||
66
+ trimmed.endsWith('"""') ||
67
+ trimmed.endsWith("'''"));
68
+ }
69
+ /**
70
+ * Extract description text from comment lines after marker
71
+ */
72
+ function extractDescription(lines, markerLineIndex) {
73
+ const descLines = [];
74
+ // Check if marker is on its own line or has text after it
75
+ const markerLine = lines[markerLineIndex];
76
+ const markerText = extractTextAfterMarker(markerLine);
77
+ if (markerText) {
78
+ descLines.push(markerText);
79
+ }
80
+ // Continue reading comment lines after marker
81
+ for (let i = markerLineIndex + 1; i < lines.length; i++) {
82
+ const line = lines[i];
83
+ const trimmed = line.trim();
84
+ // Empty line in comments is ok, include it
85
+ if (trimmed === '') {
86
+ // But stop if we've already collected some description
87
+ if (descLines.length > 0) {
88
+ // Check if next non-empty line is still a comment
89
+ let nextNonEmpty = i + 1;
90
+ while (nextNonEmpty < lines.length && lines[nextNonEmpty].trim() === '') {
91
+ nextNonEmpty++;
92
+ }
93
+ if (nextNonEmpty < lines.length && !isCommentLine(lines[nextNonEmpty].trim())) {
94
+ break;
95
+ }
96
+ }
97
+ continue;
98
+ }
99
+ // Stop at non-comment line
100
+ if (!isCommentLine(trimmed)) {
101
+ break;
102
+ }
103
+ // Stop at end of block comment
104
+ if (trimmed === '*/' || trimmed === '"""' || trimmed === "'''") {
105
+ break;
106
+ }
107
+ // Extract text from comment line
108
+ const text = stripCommentPrefix(trimmed);
109
+ if (text !== null) {
110
+ descLines.push(text);
111
+ }
112
+ }
113
+ return descLines.join('\n').trim();
114
+ }
115
+ /**
116
+ * Extract text after @mappamundi marker on the same line
117
+ */
118
+ function extractTextAfterMarker(line) {
119
+ const idx = line.indexOf(MARKER);
120
+ if (idx === -1)
121
+ return '';
122
+ const after = line.slice(idx + MARKER.length).trim();
123
+ return after;
124
+ }
125
+ /**
126
+ * Strip comment prefix from a line
127
+ */
128
+ function stripCommentPrefix(line) {
129
+ // Handle various comment styles
130
+ if (line.startsWith('///'))
131
+ return line.slice(3).trim();
132
+ if (line.startsWith('//'))
133
+ return line.slice(2).trim();
134
+ if (line.startsWith('##'))
135
+ return line.slice(2).trim();
136
+ if (line.startsWith('#'))
137
+ return line.slice(1).trim();
138
+ if (line.startsWith('*'))
139
+ return line.slice(1).trim();
140
+ if (line.startsWith('/*'))
141
+ return line.slice(2).trim();
142
+ return line;
143
+ }
144
+ //# sourceMappingURL=marker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marker.js","sourceRoot":"","sources":["../../src/extract/marker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { GenerateOptions, MapNode } from './types.js';
2
+ export type { DefEntry, Definition, FileEntry, FileResult, GenerateOptions, Language, MapNode, MarkerResult, } from './types.js';
3
+ /**
4
+ * Generate a map object from a directory
5
+ */
6
+ export declare function generateMap(options?: GenerateOptions): Promise<MapNode>;
7
+ /**
8
+ * Generate a YAML string map from a directory
9
+ */
10
+ export declare function generateMapYaml(options?: GenerateOptions): Promise<string>;
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAE1D,YAAY,EACV,QAAQ,EACR,UAAU,EACV,SAAS,EACT,UAAU,EACV,eAAe,EACf,QAAQ,EACR,OAAO,EACP,YAAY,GACb,MAAM,YAAY,CAAA;AAEnB;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,OAAO,CAAC,CAKjF;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAGpF"}
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ // @mappamundi
2
+ // Library exports for programmatic usage.
3
+ import { resolve } from 'path';
4
+ import { scanDirectory } from './scanner.js';
5
+ import { buildMap, getRootName } from './map/builder.js';
6
+ import { toYaml } from './map/yaml.js';
7
+ /**
8
+ * Generate a map object from a directory
9
+ */
10
+ export async function generateMap(options = {}) {
11
+ const dir = resolve(options.dir ?? '.');
12
+ const results = await scanDirectory({ ...options, dir });
13
+ const rootName = getRootName(dir);
14
+ return buildMap(results, rootName);
15
+ }
16
+ /**
17
+ * Generate a YAML string map from a directory
18
+ */
19
+ export async function generateMapYaml(options = {}) {
20
+ const map = await generateMap(options);
21
+ return toYaml(map);
22
+ }
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,0CAA0C;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AActC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,UAA2B,EAAE;IAC7D,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAA;IACvC,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,CAAC,CAAA;IACxD,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;IACjC,OAAO,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,UAA2B,EAAE;IACjE,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAA;IACtC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAA;AACpB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { FileResult, MapNode } from '../types.js';
2
+ /**
3
+ * Build a nested map object from file results
4
+ */
5
+ export declare function buildMap(results: FileResult[], rootName: string): MapNode;
6
+ /**
7
+ * Get the root name from a directory path
8
+ */
9
+ export declare function getRootName(dir: string): string;
10
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/map/builder.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAa,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAEjE;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CASzE;AAoCD;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM/C"}
@@ -0,0 +1,53 @@
1
+ // @mappamundi
2
+ // Build the nested map object from file results.
3
+ import { basename } from 'path';
4
+ /**
5
+ * Build a nested map object from file results
6
+ */
7
+ export function buildMap(results, rootName) {
8
+ const root = {};
9
+ for (const result of results) {
10
+ insertFile(root, result);
11
+ }
12
+ // Wrap in root name
13
+ return { [rootName]: root };
14
+ }
15
+ /**
16
+ * Insert a file result into the map at its path location
17
+ */
18
+ function insertFile(root, result) {
19
+ const parts = result.relativePath.split('/');
20
+ let current = root;
21
+ // Navigate/create directory structure
22
+ for (let i = 0; i < parts.length - 1; i++) {
23
+ const dir = parts[i];
24
+ if (!current[dir]) {
25
+ current[dir] = {};
26
+ }
27
+ current = current[dir];
28
+ }
29
+ // Create file entry
30
+ const filename = parts[parts.length - 1];
31
+ const entry = {};
32
+ if (result.description) {
33
+ entry.desc = result.description;
34
+ }
35
+ if (result.definitions.length > 0) {
36
+ entry.defs = {};
37
+ for (const def of result.definitions) {
38
+ entry.defs[def.name] = def.line;
39
+ }
40
+ }
41
+ current[filename] = entry;
42
+ }
43
+ /**
44
+ * Get the root name from a directory path
45
+ */
46
+ export function getRootName(dir) {
47
+ // Handle trailing slashes
48
+ const cleaned = dir.replace(/\/+$/, '');
49
+ // Get basename, or use 'root' for current directory
50
+ const name = basename(cleaned);
51
+ return name === '.' || name === '' ? 'root' : name;
52
+ }
53
+ //# sourceMappingURL=builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/map/builder.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,iDAAiD;AAEjD,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;AAG/B;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAqB,EAAE,QAAgB;IAC9D,MAAM,IAAI,GAAY,EAAE,CAAA;IAExB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IAC1B,CAAC;IAED,oBAAoB;IACpB,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAA;AAC7B,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,IAAa,EAAE,MAAkB;IACnD,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC5C,IAAI,OAAO,GAAG,IAAI,CAAA;IAElB,sCAAsC;IACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACpB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAA;QACnB,CAAC;QACD,OAAO,GAAG,OAAO,CAAC,GAAG,CAAY,CAAA;IACnC,CAAC;IAED,oBAAoB;IACpB,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IACxC,MAAM,KAAK,GAAc,EAAE,CAAA;IAE3B,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,WAAW,CAAA;IACjC,CAAC;IAED,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAA;QACf,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,CAAA;QACjC,CAAC;IACH,CAAC;IAED,OAAO,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAA;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,0BAA0B;IAC1B,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IACvC,oDAAoD;IACpD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAA;IAC9B,OAAO,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAA;AACpD,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { MapNode } from '../types.js';
2
+ /**
3
+ * Convert map object to YAML string
4
+ */
5
+ export declare function toYaml(map: MapNode): string;
6
+ //# sourceMappingURL=yaml.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yaml.d.ts","sourceRoot":"","sources":["../../src/map/yaml.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAE1C;;GAEG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAS3C"}
@@ -0,0 +1,17 @@
1
+ // @mappamundi
2
+ // Format map object to YAML string.
3
+ import yaml from 'js-yaml';
4
+ /**
5
+ * Convert map object to YAML string
6
+ */
7
+ export function toYaml(map) {
8
+ return yaml.dump(map, {
9
+ indent: 2,
10
+ lineWidth: -1, // Don't wrap lines
11
+ noRefs: true, // Don't use YAML references
12
+ sortKeys: true, // Consistent ordering
13
+ quotingType: '"',
14
+ forceQuotes: false,
15
+ });
16
+ }
17
+ //# sourceMappingURL=yaml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yaml.js","sourceRoot":"","sources":["../../src/map/yaml.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,oCAAoC;AAEpC,OAAO,IAAI,MAAM,SAAS,CAAA;AAG1B;;GAEG;AACH,MAAM,UAAU,MAAM,CAAC,GAAY;IACjC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;QACpB,MAAM,EAAE,CAAC;QACT,SAAS,EAAE,CAAC,CAAC,EAAG,mBAAmB;QACnC,MAAM,EAAE,IAAI,EAAI,4BAA4B;QAC5C,QAAQ,EAAE,IAAI,EAAE,sBAAsB;QACtC,WAAW,EAAE,GAAG;QAChB,WAAW,EAAE,KAAK;KACnB,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { Language, SyntaxTree } from '../types.js';
2
+ /**
3
+ * Initialize the tree-sitter parser
4
+ */
5
+ export declare function initParser(): Promise<void>;
6
+ /**
7
+ * Parse source code and return the syntax tree
8
+ */
9
+ export declare function parseCode(code: string, language: Language): Promise<SyntaxTree>;
10
+ /**
11
+ * Reset the parser (for testing)
12
+ */
13
+ export declare function resetParser(): void;
14
+ export { detectLanguage, loadGrammar, LANGUAGE_EXTENSIONS } from './languages.js';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAMvD;;GAEG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAIhD;AAYD;;GAEG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,UAAU,CAAC,CAKrB;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAMlC;AAED,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1,46 @@
1
+ // @mappamundi
2
+ // Tree-sitter parser initialization and code parsing.
3
+ import Parser from 'web-tree-sitter';
4
+ import { loadGrammar } from './languages.js';
5
+ let initialized = false;
6
+ let sharedParser = null;
7
+ /**
8
+ * Initialize the tree-sitter parser
9
+ */
10
+ export async function initParser() {
11
+ if (initialized)
12
+ return;
13
+ await Parser.init();
14
+ initialized = true;
15
+ }
16
+ /**
17
+ * Get the shared parser instance
18
+ */
19
+ async function getParser() {
20
+ if (sharedParser)
21
+ return sharedParser;
22
+ await initParser();
23
+ sharedParser = new Parser();
24
+ return sharedParser;
25
+ }
26
+ /**
27
+ * Parse source code and return the syntax tree
28
+ */
29
+ export async function parseCode(code, language) {
30
+ const parser = await getParser();
31
+ const grammar = await loadGrammar(language);
32
+ parser.setLanguage(grammar);
33
+ return parser.parse(code);
34
+ }
35
+ /**
36
+ * Reset the parser (for testing)
37
+ */
38
+ export function resetParser() {
39
+ if (sharedParser) {
40
+ sharedParser.delete();
41
+ sharedParser = null;
42
+ }
43
+ initialized = false;
44
+ }
45
+ export { detectLanguage, loadGrammar, LANGUAGE_EXTENSIONS } from './languages.js';
46
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,sDAAsD;AAEtD,OAAO,MAAM,MAAM,iBAAiB,CAAA;AAEpC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAE5C,IAAI,WAAW,GAAG,KAAK,CAAA;AACvB,IAAI,YAAY,GAAkB,IAAI,CAAA;AAEtC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,WAAW;QAAE,OAAM;IACvB,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;IACnB,WAAW,GAAG,IAAI,CAAA;AACpB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,SAAS;IACtB,IAAI,YAAY;QAAE,OAAO,YAAY,CAAA;IACrC,MAAM,UAAU,EAAE,CAAA;IAClB,YAAY,GAAG,IAAI,MAAM,EAAE,CAAA;IAC3B,OAAO,YAAY,CAAA;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,IAAY,EACZ,QAAkB;IAElB,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAA;IAChC,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,CAAA;IAC3C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;IAC3B,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,IAAI,YAAY,EAAE,CAAC;QACjB,YAAY,CAAC,MAAM,EAAE,CAAA;QACrB,YAAY,GAAG,IAAI,CAAA;IACrB,CAAC;IACD,WAAW,GAAG,KAAK,CAAA;AACrB,CAAC;AAED,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1,19 @@
1
+ import Parser from 'web-tree-sitter';
2
+ import type { Language } from '../types.js';
3
+ /**
4
+ * File extension to language mapping
5
+ */
6
+ export declare const LANGUAGE_EXTENSIONS: Record<string, Language>;
7
+ /**
8
+ * Detect language from file path extension
9
+ */
10
+ export declare function detectLanguage(filepath: string): Language | null;
11
+ /**
12
+ * Load a tree-sitter grammar for the given language
13
+ */
14
+ export declare function loadGrammar(language: Language): Promise<Parser.Language>;
15
+ /**
16
+ * Clear grammar cache (for testing)
17
+ */
18
+ export declare function clearGrammarCache(): void;
19
+ //# sourceMappingURL=languages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"languages.d.ts","sourceRoot":"","sources":["../../src/parser/languages.ts"],"names":[],"mappings":"AAGA,OAAO,MAAM,MAAM,iBAAiB,CAAA;AACpC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAK3C;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAaxD,CAAA;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAGhE;AAoCD;;GAEG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAU9E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
@@ -0,0 +1,80 @@
1
+ // @mappamundi
2
+ // Language detection and grammar loading for tree-sitter.
3
+ import Parser from 'web-tree-sitter';
4
+ import { createRequire } from 'module';
5
+ const require = createRequire(import.meta.url);
6
+ /**
7
+ * File extension to language mapping
8
+ */
9
+ export const LANGUAGE_EXTENSIONS = {
10
+ '.ts': 'typescript',
11
+ '.tsx': 'typescript',
12
+ '.mts': 'typescript',
13
+ '.cts': 'typescript',
14
+ '.js': 'javascript',
15
+ '.jsx': 'javascript',
16
+ '.mjs': 'javascript',
17
+ '.cjs': 'javascript',
18
+ '.py': 'python',
19
+ '.pyi': 'python',
20
+ '.rs': 'rust',
21
+ '.go': 'go',
22
+ };
23
+ /**
24
+ * Detect language from file path extension
25
+ */
26
+ export function detectLanguage(filepath) {
27
+ const ext = filepath.slice(filepath.lastIndexOf('.'));
28
+ return LANGUAGE_EXTENSIONS[ext] ?? null;
29
+ }
30
+ /**
31
+ * Get the WASM grammar path for a language
32
+ */
33
+ function getGrammarPath(language) {
34
+ switch (language) {
35
+ case 'typescript':
36
+ return require.resolve('tree-sitter-typescript/tree-sitter-tsx.wasm');
37
+ case 'javascript':
38
+ return require.resolve('tree-sitter-javascript/tree-sitter-javascript.wasm');
39
+ case 'python':
40
+ return require.resolve('tree-sitter-python/tree-sitter-python.wasm');
41
+ case 'rust':
42
+ return require.resolve('tree-sitter-rust/tree-sitter-rust.wasm');
43
+ case 'go':
44
+ return require.resolve('tree-sitter-go/tree-sitter-go.wasm');
45
+ }
46
+ }
47
+ /**
48
+ * Cache for loaded grammars
49
+ */
50
+ const grammarCache = new Map();
51
+ /**
52
+ * Ensure Parser is initialized before loading grammars
53
+ */
54
+ let parserInitialized = false;
55
+ async function ensureParserInit() {
56
+ if (!parserInitialized) {
57
+ await Parser.init();
58
+ parserInitialized = true;
59
+ }
60
+ }
61
+ /**
62
+ * Load a tree-sitter grammar for the given language
63
+ */
64
+ export async function loadGrammar(language) {
65
+ await ensureParserInit();
66
+ const cached = grammarCache.get(language);
67
+ if (cached)
68
+ return cached;
69
+ const path = getGrammarPath(language);
70
+ const grammar = await Parser.Language.load(path);
71
+ grammarCache.set(language, grammar);
72
+ return grammar;
73
+ }
74
+ /**
75
+ * Clear grammar cache (for testing)
76
+ */
77
+ export function clearGrammarCache() {
78
+ grammarCache.clear();
79
+ }
80
+ //# sourceMappingURL=languages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"languages.js","sourceRoot":"","sources":["../../src/parser/languages.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,0DAA0D;AAE1D,OAAO,MAAM,MAAM,iBAAiB,CAAA;AAEpC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AAEtC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAE9C;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAA6B;IAC3D,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,KAAK,EAAE,QAAQ;IACf,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,IAAI;CACZ,CAAA;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAA;IACrD,OAAO,mBAAmB,CAAC,GAAG,CAAC,IAAI,IAAI,CAAA;AACzC,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,QAAkB;IACxC,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,YAAY;YACf,OAAO,OAAO,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAA;QACvE,KAAK,YAAY;YACf,OAAO,OAAO,CAAC,OAAO,CAAC,oDAAoD,CAAC,CAAA;QAC9E,KAAK,QAAQ;YACX,OAAO,OAAO,CAAC,OAAO,CAAC,4CAA4C,CAAC,CAAA;QACtE,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,OAAO,CAAC,wCAAwC,CAAC,CAAA;QAClE,KAAK,IAAI;YACP,OAAO,OAAO,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAA;IAChE,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,YAAY,GAAG,IAAI,GAAG,EAA6B,CAAA;AAEzD;;GAEG;AACH,IAAI,iBAAiB,GAAG,KAAK,CAAA;AAC7B,KAAK,UAAU,gBAAgB;IAC7B,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;QACnB,iBAAiB,GAAG,IAAI,CAAA;IAC1B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAkB;IAClD,MAAM,gBAAgB,EAAE,CAAA;IAExB,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACzC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAA;IAEzB,MAAM,IAAI,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;IACrC,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAChD,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IACnC,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,YAAY,CAAC,KAAK,EAAE,CAAA;AACtB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { FileResult, GenerateOptions } from './types.js';
2
+ /**
3
+ * Scan directory and process files with @mappamundi marker
4
+ */
5
+ export declare function scanDirectory(options?: GenerateOptions): Promise<FileResult[]>;
6
+ //# sourceMappingURL=scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAyE7D;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAuCxF"}
@@ -0,0 +1,139 @@
1
+ // @mappamundi
2
+ // Scan directory for files with @mappamundi marker.
3
+ import { execSync } from 'child_process';
4
+ import fg from 'fast-glob';
5
+ import picomatch from 'picomatch';
6
+ import { readFile } from 'fs/promises';
7
+ import { join, normalize } from 'path';
8
+ import { extractMarker } from './extract/marker.js';
9
+ import { extractDefinitions } from './extract/definitions.js';
10
+ import { parseCode, detectLanguage, LANGUAGE_EXTENSIONS } from './parser/index.js';
11
+ /**
12
+ * Supported file extensions (from LANGUAGE_EXTENSIONS)
13
+ */
14
+ const SUPPORTED_EXTENSIONS = new Set(Object.keys(LANGUAGE_EXTENSIONS));
15
+ /**
16
+ * Check if a file has a supported extension
17
+ */
18
+ function isSupportedFile(filepath) {
19
+ const ext = filepath.slice(filepath.lastIndexOf('.'));
20
+ return SUPPORTED_EXTENSIONS.has(ext);
21
+ }
22
+ /**
23
+ * Check if running inside a git repository
24
+ */
25
+ function isGitRepo(dir) {
26
+ try {
27
+ execSync('git rev-parse --git-dir', { cwd: dir, stdio: 'ignore' });
28
+ return true;
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ }
34
+ /**
35
+ * Get files using git ls-files
36
+ * Uses --cached --others to get tracked + untracked files
37
+ * Uses --exclude-standard to respect .gitignore
38
+ */
39
+ function getGitFiles(dir) {
40
+ const maxBuffer = 1024 * 10000000;
41
+ try {
42
+ // Get tracked and untracked files (respecting .gitignore)
43
+ const stdout = execSync('git ls-files --cached --others --exclude-standard', {
44
+ cwd: dir,
45
+ maxBuffer,
46
+ encoding: 'utf8',
47
+ });
48
+ // Get deleted files to exclude
49
+ const deleted = execSync('git ls-files --deleted', {
50
+ cwd: dir,
51
+ maxBuffer,
52
+ encoding: 'utf8',
53
+ });
54
+ const paths = stdout.split(/\r?\n/).map(x => x.trim()).filter(Boolean);
55
+ const deletedPaths = new Set(deleted.split(/\r?\n/).map(x => x.trim()).filter(Boolean));
56
+ return paths
57
+ .filter(p => !deletedPaths.has(p))
58
+ .map(normalize);
59
+ }
60
+ catch {
61
+ return [];
62
+ }
63
+ }
64
+ /**
65
+ * Get files using fast-glob (fallback when not in git repo)
66
+ */
67
+ async function getGlobFiles(dir) {
68
+ const patterns = Object.keys(LANGUAGE_EXTENSIONS).map(ext => `**/*${ext}`);
69
+ return fg(patterns, {
70
+ cwd: dir,
71
+ ignore: ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.git/**'],
72
+ absolute: false,
73
+ dot: false,
74
+ });
75
+ }
76
+ /**
77
+ * Scan directory and process files with @mappamundi marker
78
+ */
79
+ export async function scanDirectory(options = {}) {
80
+ const dir = options.dir ?? process.cwd();
81
+ const ignorePatterns = options.ignore ?? [];
82
+ // Get file list - prefer git, fallback to glob
83
+ let files;
84
+ if (isGitRepo(dir)) {
85
+ files = getGitFiles(dir);
86
+ }
87
+ else {
88
+ files = await getGlobFiles(dir);
89
+ }
90
+ // Filter by supported extensions
91
+ files = files.filter(isSupportedFile);
92
+ // Filter by ignore patterns
93
+ if (ignorePatterns.length > 0) {
94
+ const isIgnored = picomatch(ignorePatterns);
95
+ files = files.filter(f => !isIgnored(f));
96
+ }
97
+ // Process each file
98
+ const results = [];
99
+ for (const relativePath of files) {
100
+ const fullPath = join(dir, relativePath);
101
+ try {
102
+ const result = await processFile(fullPath, relativePath);
103
+ if (result) {
104
+ results.push(result);
105
+ }
106
+ }
107
+ catch (err) {
108
+ // Skip files that fail to process
109
+ console.error(`Warning: Failed to process ${relativePath}:`, err);
110
+ }
111
+ }
112
+ return results;
113
+ }
114
+ /**
115
+ * Process a single file - check for marker and extract definitions
116
+ */
117
+ async function processFile(fullPath, relativePath) {
118
+ // Check for marker first (only reads first 30KB)
119
+ const marker = await extractMarker(fullPath);
120
+ if (!marker.found) {
121
+ return null;
122
+ }
123
+ // Detect language
124
+ const language = detectLanguage(relativePath);
125
+ if (!language) {
126
+ return null;
127
+ }
128
+ // Read full file for parsing
129
+ const code = await readFile(fullPath, 'utf8');
130
+ // Parse and extract definitions
131
+ const tree = await parseCode(code, language);
132
+ const definitions = extractDefinitions(tree.rootNode, language);
133
+ return {
134
+ relativePath,
135
+ description: marker.description,
136
+ definitions,
137
+ };
138
+ }
139
+ //# sourceMappingURL=scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import type Parser from 'web-tree-sitter';
2
+ /**
3
+ * Supported programming languages
4
+ */
5
+ export type Language = 'typescript' | 'javascript' | 'python' | 'rust' | 'go';
6
+ /**
7
+ * Symbol definitions mapping: name -> 1-based line number
8
+ */
9
+ export interface DefEntry {
10
+ [symbolName: string]: number;
11
+ }
12
+ /**
13
+ * A file entry in the map
14
+ */
15
+ export interface FileEntry {
16
+ desc?: string;
17
+ defs?: DefEntry;
18
+ }
19
+ /**
20
+ * Recursive map node - either a directory (with children) or a file entry
21
+ */
22
+ export interface MapNode {
23
+ [name: string]: MapNode | FileEntry;
24
+ }
25
+ /**
26
+ * Result of extracting marker and description from a file
27
+ */
28
+ export interface MarkerResult {
29
+ found: boolean;
30
+ description?: string;
31
+ }
32
+ /**
33
+ * A definition extracted from source code
34
+ */
35
+ export interface Definition {
36
+ name: string;
37
+ line: number;
38
+ type: 'function' | 'class';
39
+ }
40
+ /**
41
+ * Result of processing a single file
42
+ */
43
+ export interface FileResult {
44
+ relativePath: string;
45
+ description?: string;
46
+ definitions: Definition[];
47
+ }
48
+ /**
49
+ * Options for generating the map
50
+ */
51
+ export interface GenerateOptions {
52
+ /** Directory to scan (default: cwd) */
53
+ dir?: string;
54
+ /** Glob patterns to ignore */
55
+ ignore?: string[];
56
+ }
57
+ /**
58
+ * Re-export parser types
59
+ */
60
+ export type SyntaxNode = Parser.SyntaxNode;
61
+ export type SyntaxTree = Parser.Tree;
62
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAA;AAEzC;;GAEG;AACH,MAAM,MAAM,QAAQ,GAChB,YAAY,GACZ,YAAY,GACZ,QAAQ,GACR,MAAM,GACN,IAAI,CAAA;AAER;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAA;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,QAAQ,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,OAAO,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,UAAU,GAAG,OAAO,CAAA;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,UAAU,EAAE,CAAA;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,8BAA8B;IAC9B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAA;AAC1C,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAA"}
package/dist/types.js ADDED
@@ -0,0 +1,4 @@
1
+ // @mappamundi
2
+ // Core type definitions for the codebase map.
3
+ export {};
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,8CAA8C"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "agentmap",
3
+ "version": "0.1.0",
4
+ "description": "Generate a YAML map of your codebase for AI agent context",
5
+ "type": "module",
6
+ "bin": {
7
+ "agentmap": "./dist/cli.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsc",
22
+ "dev": "tsc --watch",
23
+ "cli": "tsx src/cli.ts",
24
+ "prepublishOnly": "npm run build"
25
+ },
26
+ "dependencies": {
27
+ "cac": "^6.7.14",
28
+ "fast-glob": "^3.3.2",
29
+ "js-yaml": "^4.1.0",
30
+ "picomatch": "^4.0.2",
31
+ "tree-sitter-go": "^0.23.4",
32
+ "tree-sitter-javascript": "^0.23.1",
33
+ "tree-sitter-python": "^0.23.6",
34
+ "tree-sitter-rust": "^0.23.2",
35
+ "tree-sitter-typescript": "^0.23.2",
36
+ "web-tree-sitter": "^0.24.4"
37
+ },
38
+ "devDependencies": {
39
+ "@types/js-yaml": "^4.0.9",
40
+ "@types/node": "^22.10.2",
41
+ "@types/picomatch": "^3.0.1",
42
+ "typescript": "^5.7.2"
43
+ },
44
+ "keywords": [
45
+ "ai",
46
+ "agent",
47
+ "codebase",
48
+ "map",
49
+ "yaml",
50
+ "treesitter",
51
+ "ast"
52
+ ],
53
+ "license": "MIT"
54
+ }