@didnhdj/fnmap 0.1.14 → 0.2.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.
package/README.md CHANGED
@@ -13,6 +13,9 @@
13
13
  - 🎯 **Git Integration**: Process only changed files for efficient workflows
14
14
  - ⚙️ **Flexible Configuration**: Support for multiple configuration methods
15
15
  - 🔌 **Pre-commit Hook**: Integrate seamlessly with git hooks
16
+ - 📦 **Programmatic API**: Use as a library to process code strings directly
17
+ - 🎨 **Smart Filtering**: Automatically skip type definition files and type-only files
18
+ - 🌍 **Cross-Platform**: Normalized path handling for Windows, macOS, and Linux
16
19
 
17
20
  ## Installation
18
21
 
@@ -34,7 +37,7 @@ npm install --save-dev @didnhdj/fnmap
34
37
  fnmap --init
35
38
  ```
36
39
 
37
- This creates a `.fnmaprc` configuration file in your project root.
40
+ This creates a `.fnmaprc` configuration file in your project root and automatically appends fnmap documentation to `CLAUDE.md` or `AGENTS.md` if they exist (useful for AI assistants).
38
41
 
39
42
  ### Basic Usage
40
43
 
@@ -156,17 +159,84 @@ Usage: fnmap [options] [files...]
156
159
 
157
160
  Options:
158
161
  -v, --version Show version number
159
- -f, --files <files> Process specific files (comma-separated)
162
+ -f, --files <files> Process specific files (comma-separated, generates separate .fnmap for each)
160
163
  -d, --dir <dir> Process all code files in directory
161
164
  -p, --project <dir> Specify project root directory (default: current directory)
162
165
  -c, --changed Process git changed files (staged + modified + untracked)
163
166
  -s, --staged Process git staged files (for pre-commit hook)
164
167
  -m, --mermaid [mode] Generate Mermaid call graph (file=file-level, project=project-level)
165
168
  -q, --quiet Quiet mode (suppress output)
166
- --init Create default configuration file .fnmaprc
169
+ --init Create default configuration file and append docs to CLAUDE.md/AGENTS.md
167
170
  -h, --help Display help information
168
171
  ```
169
172
 
173
+ ## Programmatic API
174
+
175
+ fnmap can be used as a library in your Node.js applications.
176
+
177
+ ### Processing Code Strings
178
+
179
+ ```typescript
180
+ import { processCode } from '@didnhdj/fnmap';
181
+
182
+ const code = `
183
+ export function hello(name) {
184
+ console.log('Hello, ' + name);
185
+ }
186
+ `;
187
+
188
+ const result = processCode(code, { filePath: 'example.js' });
189
+
190
+ if (result.success) {
191
+ console.log('Functions:', result.info.functions);
192
+ console.log('Imports:', result.info.imports);
193
+ console.log('Call Graph:', result.info.callGraph);
194
+ } else {
195
+ console.error('Parse error:', result.error);
196
+ }
197
+ ```
198
+
199
+ ### Processing Files
200
+
201
+ ```typescript
202
+ import { processFile } from '@didnhdj/fnmap';
203
+
204
+ const result = processFile('./src/utils.js');
205
+
206
+ if (result.success) {
207
+ console.log('Analysis result:', result.info);
208
+ }
209
+ ```
210
+
211
+ ### API Types
212
+
213
+ ```typescript
214
+ // Process result type
215
+ type ProcessResult = ProcessSuccess | ProcessFailure;
216
+
217
+ interface ProcessSuccess {
218
+ success: true;
219
+ info: FileInfo;
220
+ }
221
+
222
+ interface ProcessFailure {
223
+ success: false;
224
+ error: string;
225
+ errorType: ErrorType;
226
+ loc?: { line: number; column: number };
227
+ }
228
+
229
+ // File info structure
230
+ interface FileInfo {
231
+ imports: ImportInfo[];
232
+ functions: FunctionInfo[];
233
+ classes: ClassInfo[];
234
+ constants: ConstantInfo[];
235
+ callGraph: CallGraph;
236
+ isPureTypeFile: boolean; // Whether file only contains type definitions
237
+ }
238
+ ```
239
+
170
240
  ## Use Cases
171
241
 
172
242
  ### 1. Pre-commit Hook
@@ -219,6 +289,10 @@ fnmap --mermaid project
219
289
  - `.tsx` - React TypeScript
220
290
  - `.mjs` - ES Modules
221
291
 
292
+ **Auto-filtered files:**
293
+ - `.d.ts`, `.d.tsx`, `.d.mts` - Type definition files
294
+ - Files containing only `type` or `interface` declarations (pure type files)
295
+
222
296
  ## Limitations
223
297
 
224
298
  To ensure performance and safety, fnmap has the following default limits:
@@ -251,7 +325,7 @@ Analyzing: src/utils.js
251
325
  ✓ Imports: 3, Functions: 5, Classes: 0, Constants: 2
252
326
 
253
327
  Generating .fnmap index...
254
- ✓ src/.fnmap
328
+ ✓ src/utils.fnmap
255
329
 
256
330
  ==================================================
257
331
  Complete! Analyzed: 1, Failed: 0
package/README_CN.md CHANGED
@@ -13,6 +13,9 @@
13
13
  - 🎯 **Git 集成**:只处理改动的文件,提高工作效率
14
14
  - ⚙️ **灵活配置**:支持多种配置方式
15
15
  - 🔌 **Pre-commit Hook**:无缝集成 git hooks
16
+ - 📦 **编程接口**:可作为库直接处理代码字符串
17
+ - 🎨 **智能过滤**:自动跳过类型定义文件和纯类型文件
18
+ - 🌍 **跨平台支持**:支持 Windows、macOS 和 Linux 的路径规范化
16
19
 
17
20
  ## 安装
18
21
 
@@ -34,7 +37,7 @@ npm install --save-dev @didnhdj/fnmap
34
37
  fnmap --init
35
38
  ```
36
39
 
37
- 这会在项目根目录创建 `.fnmaprc` 配置文件。
40
+ 这会在项目根目录创建 `.fnmaprc` 配置文件,并自动追加 fnmap 文档到 `CLAUDE.md` 或 `AGENTS.md`(如果存在,方便 AI 助手理解)。
38
41
 
39
42
  ### 基本用法
40
43
 
@@ -156,17 +159,84 @@ flowchart TD
156
159
 
157
160
  选项:
158
161
  -v, --version 显示版本号
159
- -f, --files <files> 处理指定文件(逗号分隔)
162
+ -f, --files <files> 处理指定文件(逗号分隔,为每个文件生成单独的 .fnmap)
160
163
  -d, --dir <dir> 处理目录下所有代码文件
161
164
  -p, --project <dir> 指定项目根目录(默认:当前目录)
162
165
  -c, --changed 处理 git 改动的文件(staged + modified + untracked)
163
166
  -s, --staged 处理 git staged 文件(用于 pre-commit hook)
164
167
  -m, --mermaid [mode] 生成 Mermaid 调用图(file=文件级,project=项目级)
165
168
  -q, --quiet 静默模式(不输出信息)
166
- --init 创建默认配置文件 .fnmaprc
169
+ --init 创建默认配置文件并追加文档到 CLAUDE.md/AGENTS.md
167
170
  -h, --help 显示帮助信息
168
171
  ```
169
172
 
173
+ ## 编程接口
174
+
175
+ fnmap 可以作为库在 Node.js 应用中使用。
176
+
177
+ ### 处理代码字符串
178
+
179
+ ```typescript
180
+ import { processCode } from '@didnhdj/fnmap';
181
+
182
+ const code = `
183
+ export function hello(name) {
184
+ console.log('Hello, ' + name);
185
+ }
186
+ `;
187
+
188
+ const result = processCode(code, { filePath: 'example.js' });
189
+
190
+ if (result.success) {
191
+ console.log('函数:', result.info.functions);
192
+ console.log('导入:', result.info.imports);
193
+ console.log('调用图:', result.info.callGraph);
194
+ } else {
195
+ console.error('解析错误:', result.error);
196
+ }
197
+ ```
198
+
199
+ ### 处理文件
200
+
201
+ ```typescript
202
+ import { processFile } from '@didnhdj/fnmap';
203
+
204
+ const result = processFile('./src/utils.js');
205
+
206
+ if (result.success) {
207
+ console.log('分析结果:', result.info);
208
+ }
209
+ ```
210
+
211
+ ### API 类型定义
212
+
213
+ ```typescript
214
+ // 处理结果类型
215
+ type ProcessResult = ProcessSuccess | ProcessFailure;
216
+
217
+ interface ProcessSuccess {
218
+ success: true;
219
+ info: FileInfo;
220
+ }
221
+
222
+ interface ProcessFailure {
223
+ success: false;
224
+ error: string;
225
+ errorType: ErrorType;
226
+ loc?: { line: number; column: number };
227
+ }
228
+
229
+ // 文件信息结构
230
+ interface FileInfo {
231
+ imports: ImportInfo[];
232
+ functions: FunctionInfo[];
233
+ classes: ClassInfo[];
234
+ constants: ConstantInfo[];
235
+ callGraph: CallGraph;
236
+ isPureTypeFile: boolean; // 文件是否仅包含类型定义
237
+ }
238
+ ```
239
+
170
240
  ## 使用场景
171
241
 
172
242
  ### 1. Pre-commit Hook
@@ -219,12 +289,15 @@ fnmap --mermaid project
219
289
  - `.tsx` - React TypeScript
220
290
  - `.mjs` - ES Modules
221
291
 
292
+ **自动过滤的文件:**
293
+ - `.d.ts`、`.d.tsx`、`.d.mts` - 类型定义文件
294
+ - 仅包含 `type` 或 `interface` 声明的纯类型文件
295
+
222
296
  ## 限制
223
297
 
224
298
  为了保证性能和安全,fnmap 有以下默认限制:
225
299
  - **文件大小**:单个文件最大支持 10MB
226
300
  - **目录深度**:最大递归深度为 50 层
227
- - **超时**:目前没有硬性超时限制,但处理超大文件可能会较慢
228
301
 
229
302
  ## 工作原理
230
303
 
@@ -252,7 +325,7 @@ Analyzing: src/utils.js
252
325
  ✓ Imports: 3, Functions: 5, Classes: 0, Constants: 2
253
326
 
254
327
  Generating .fnmap index...
255
- ✓ src/.fnmap
328
+ ✓ src/utils.fnmap
256
329
 
257
330
  ==================================================
258
331
  Complete! Analyzed: 1, Failed: 0
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,aAAa,EAMd,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,uBAAuB,EAAqB,MAAM,SAAS,CAAC;AAKrE;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,aAAa,CA+YjF;AAoFD,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,aAAa,EAMd,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,uBAAuB,EAAqB,MAAM,SAAS,CAAC;AAKrE;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,aAAa,CA40BjF;AAoFD,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
@@ -5,6 +5,7 @@ export declare const logger: {
5
5
  info: (msg: string) => void;
6
6
  warn: (msg: string) => void;
7
7
  title: (msg: string) => void;
8
+ stats: (msg: string) => void;
8
9
  };
9
10
  export declare function setQuietMode(quiet: boolean): void;
10
11
  export declare function isQuietMode(): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,eAAO,MAAM,MAAM;iBACJ,MAAM,KAAG,IAAI;mBAGX,MAAM,KAAG,IAAI;gBAGhB,MAAM,KAAG,IAAI;gBAGb,MAAM,KAAG,IAAI;iBAGZ,MAAM,KAAG,IAAI;CAG3B,CAAC;AAEF,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAEjD;AAED,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAQnC;AAED;;GAEG;AACH,wBAAgB,QAAQ,IAAI,OAAO,CAgDlC;AAGD,wBAAgB,UAAU,IAAI,OAAO,CAKpC;AAGD,eAAO,MAAM,OAAO;;;;CAUnB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,eAAO,MAAM,MAAM;iBACJ,MAAM,KAAG,IAAI;mBAGX,MAAM,KAAG,IAAI;gBAGhB,MAAM,KAAG,IAAI;gBAGb,MAAM,KAAG,IAAI;iBAGZ,MAAM,KAAG,IAAI;iBAIb,MAAM,KAAG,IAAI;CAG3B,CAAC;AAEF,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAEjD;AAED,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAQnC;AAED;;GAEG;AACH,wBAAgB,QAAQ,IAAI,OAAO,CAqDlC;AAGD,wBAAgB,UAAU,IAAI,OAAO,CAKpC;AAGD,eAAO,MAAM,OAAO;;;;CAUnB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -3,10 +3,10 @@
3
3
  * fnmap - AI Code Indexing Tool
4
4
  * Analyzes JS/TS code structure and generates structured code maps to help AI understand code quickly
5
5
  */
6
- export type { ErrorType, ValidationResult, ValidationSuccess, ValidationFailure, FnmapConfig, LoadedConfig, ImportInfo, FunctionInfo, MethodInfo, ClassInfo, ConstantInfo, CallGraph, FileInfo, ParseErrorResult, AnalyzeResult, ProcessResult, ProcessSuccess, ProcessFailure, CLIOptions, ErrorContext, FileInfoEntry } from './types';
6
+ export type { ErrorType, ValidationResult, ValidationSuccess, ValidationFailure, FnmapConfig, LoadedConfig, ImportInfo, FunctionInfo, MethodInfo, ClassInfo, ConstantInfo, CallGraph, FileInfo, ParseErrorResult, AnalyzeResult, ProcessResult, ProcessSuccess, ProcessFailure, CLIOptions, InitOptions, ErrorContext, FileInfoEntry } from './types';
7
7
  export { ErrorTypes, isParseError, isProcessSuccess, isProcessFailure, isValidationSuccess, isValidationFailure } from './types';
8
8
  export { COLORS, SUPPORTED_EXTENSIONS, DEFAULT_EXCLUDES, DEFAULT_CONFIG, MAX_FILE_SIZE, MAX_DIR_DEPTH } from './constants';
9
- export { validateFilePath, validateConfig, formatError } from './validation';
9
+ export { validateFilePath, validateConfig, formatError, normalizePath, normalizePaths } from './validation';
10
10
  export { loadConfig, mergeConfig } from './config';
11
11
  export { setupCLI, getVersion, logger, setQuietMode, isQuietMode, program } from './cli';
12
12
  export { scanDirectory, getGitChangedFiles } from './scanner';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAGH,YAAY,EACV,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACd,UAAU,EACV,YAAY,EACZ,aAAa,EACd,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAGjI,OAAO,EAAE,MAAM,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG3H,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG7E,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAGnD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAGzF,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAG9D,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAGlE,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,aAAa,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAGhI,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGtD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAGH,YAAY,EACV,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACd,UAAU,EACV,WAAW,EACX,YAAY,EACZ,aAAa,EACd,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAGjI,OAAO,EAAE,MAAM,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG3H,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG5G,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAGnD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAGzF,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAG9D,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAGlE,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,aAAa,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAGhI,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGtD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,IAAI,EAAE,CAAC"}
package/dist/index.js CHANGED
@@ -1,13 +1,14 @@
1
1
  #!/usr/bin/env node
2
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const C=require("fs"),h=require("path"),Fe=require("commander"),P=require("child_process"),Ie=require("@babel/parser"),z=require("@babel/traverse"),A={FILE_NOT_FOUND:"FILE_NOT_FOUND",FILE_READ_ERROR:"FILE_READ_ERROR",PARSE_ERROR:"PARSE_ERROR",CONFIG_ERROR:"CONFIG_ERROR",VALIDATION_ERROR:"VALIDATION_ERROR",PERMISSION_ERROR:"PERMISSION_ERROR",FILE_TOO_LARGE:"FILE_TOO_LARGE"};function Y(e){return"parseError"in e}function Ce(e){return e.success===!0}function be(e){return e.success===!1}function xe(e){return e.valid===!0}function Ae(e){return e.valid===!1}const x={reset:"\x1B[0m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",gray:"\x1B[90m",bold:"\x1B[1m"},K=10*1024*1024,X=50,W=[".js",".ts",".jsx",".tsx",".mjs"],ee=["node_modules",".git","dist","build",".next","coverage","__pycache__",".cache"],H={enable:!0,include:["**/*.js","**/*.ts","**/*.jsx","**/*.tsx","**/*.mjs"],exclude:[]};function le(e){if(!e||typeof e!="string")return{valid:!1,error:"File path is required and must be a string / 文件路径必须是字符串",errorType:A.VALIDATION_ERROR};if(!C.existsSync(e))return{valid:!1,error:`File not found: ${e} / 文件不存在: ${e}`,errorType:A.FILE_NOT_FOUND};try{const o=C.statSync(e);if(!o.isFile())return{valid:!1,error:`Path is not a file: ${e} / 路径不是文件: ${e}`,errorType:A.VALIDATION_ERROR};if(o.size>K)return{valid:!1,error:`File too large (${(o.size/1024/1024).toFixed(2)}MB > ${K/1024/1024}MB): ${e} / 文件过大`,errorType:A.FILE_TOO_LARGE}}catch(o){return{valid:!1,error:`Cannot access file: ${e}. Reason: ${o.message} / 无法访问文件`,errorType:A.PERMISSION_ERROR}}return{valid:!0}}function Q(e){if(!e||typeof e!="object")return{valid:!1,error:"Config must be an object / 配置必须是对象"};const o=e;return o.enable!==void 0&&typeof o.enable!="boolean"?{valid:!1,error:"Config.enable must be a boolean / enable 字段必须是布尔值"}:o.include!==void 0&&!Array.isArray(o.include)?{valid:!1,error:"Config.include must be an array / include 字段必须是数组"}:o.exclude!==void 0&&!Array.isArray(o.exclude)?{valid:!1,error:"Config.exclude must be an array / exclude 字段必须是数组"}:{valid:!0}}function q(e,o,s={}){const n=[o];return s.file&&n.push(`File: ${s.file}`),s.line!==void 0&&s.column!==void 0&&n.push(`Location: Line ${s.line}, Column ${s.column}`),s.suggestion&&n.push(`Suggestion: ${s.suggestion}`),n.join(`
3
- `)}let w=!1,G=null;const $={error:e=>{w||console.error(`${x.red}✗${x.reset} ${e}`)},success:e=>{w||console.log(`${x.green}✓${x.reset} ${e}`)},info:e=>{w||console.log(e)},warn:e=>{w||console.warn(`${x.yellow}!${x.reset} ${e}`)},title:e=>{w||console.log(`${x.bold}${e}${x.reset}`)}};function fe(e){w=e}function ve(){return w}function de(){try{return require("../../package.json").version}catch{return"0.1.0"}}function ne(){return G=new Fe.Command,G.name("fnmap").description("AI code indexing tool - Analyzes JS/TS code structure and generates structured code maps").version(de(),"-v, --version","Show version number").option("-f, --files <files>","Process specified files (comma-separated)",e=>e.split(",").map(o=>o.trim()).filter(Boolean)).option("-d, --dir <dir>","Process all code files in directory").option("-p, --project <dir>","Specify project root directory",process.env.CLAUDE_PROJECT_DIR??process.cwd()).option("-c, --changed","Process only git changed files (staged + modified + untracked)").option("-s, --staged","Process only git staged files (for pre-commit hook)").option("-m, --mermaid [mode]","Generate Mermaid call graph (file=file-level, project=project-level)").option("-q, --quiet","Quiet mode").option("--init","Create default config file .fnmaprc").argument("[files...]","Directly specify file paths").allowUnknownOption(!1).addHelpText("after",`
2
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const F=require("fs"),g=require("path"),nn=require("commander"),Ie=require("child_process"),tn=require("@babel/parser"),Re=require("@babel/traverse"),W={FILE_NOT_FOUND:"FILE_NOT_FOUND",FILE_READ_ERROR:"FILE_READ_ERROR",PARSE_ERROR:"PARSE_ERROR",CONFIG_ERROR:"CONFIG_ERROR",VALIDATION_ERROR:"VALIDATION_ERROR",PERMISSION_ERROR:"PERMISSION_ERROR",FILE_TOO_LARGE:"FILE_TOO_LARGE"};function Te(e){return"parseError"in e}function rn(e){return e.success===!0}function sn(e){return e.success===!1}function on(e){return e.valid===!0}function an(e){return e.valid===!1}const S={reset:"\x1B[0m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",gray:"\x1B[90m",bold:"\x1B[1m"},Le=10*1024*1024,je=50,Fe=[".js",".ts",".jsx",".tsx",".mjs"],Oe=["node_modules",".git","dist","build",".next","coverage","__pycache__",".cache"],Ne={enable:!0,include:["**/*.js","**/*.ts","**/*.jsx","**/*.tsx","**/*.mjs"],exclude:[]};function $e(e){if(!e)return e;const r=e.replace(/\\/g,"/");return g.normalize(r)}function cn(e){return e.map($e)}function ze(e){if(!e||typeof e!="string")return{valid:!1,error:"File path is required and must be a string / 文件路径必须是字符串",errorType:W.VALIDATION_ERROR};if(!F.existsSync(e))return{valid:!1,error:`File not found: ${e} / 文件不存在: ${e}`,errorType:W.FILE_NOT_FOUND};try{const r=F.statSync(e);if(!r.isFile())return{valid:!1,error:`Path is not a file: ${e} / 路径不是文件: ${e}`,errorType:W.VALIDATION_ERROR};if(r.size>Le)return{valid:!1,error:`File too large (${(r.size/1024/1024).toFixed(2)}MB > ${Le/1024/1024}MB): ${e} / 文件过大`,errorType:W.FILE_TOO_LARGE}}catch(r){return{valid:!1,error:`Cannot access file: ${e}. Reason: ${r.message} / 无法访问文件`,errorType:W.PERMISSION_ERROR}}return{valid:!0}}function De(e){if(!e||typeof e!="object")return{valid:!1,error:"Config must be an object / 配置必须是对象"};const r=e;return r.enable!==void 0&&typeof r.enable!="boolean"?{valid:!1,error:"Config.enable must be a boolean / enable 字段必须是布尔值"}:r.include!==void 0&&!Array.isArray(r.include)?{valid:!1,error:"Config.include must be an array / include 字段必须是数组"}:r.exclude!==void 0&&!Array.isArray(r.exclude)?{valid:!1,error:"Config.exclude must be an array / exclude 字段必须是数组"}:{valid:!0}}function Se(e,r,t={}){const s=[r];return t.file&&s.push(`File: ${t.file}`),t.line!==void 0&&t.column!==void 0&&s.push(`Location: Line ${t.line}, Column ${t.column}`),t.suggestion&&s.push(`Suggestion: ${t.suggestion}`),s.join(`
3
+ `)}let ye=!0,be=null;const E={error:e=>{ye||console.error(`${S.red}✗${S.reset} ${e}`)},success:e=>{ye||console.log(`${S.green}✓${S.reset} ${e}`)},info:e=>{ye||console.log(e)},warn:e=>{ye||console.warn(`${S.yellow}!${S.reset} ${e}`)},title:e=>{ye||console.log(`${S.bold}${e}${S.reset}`)},stats:e=>{console.log(e)}};function he(e){ye=e}function _e(){return ye}function Be(){try{return require("../../package.json").version}catch{return"0.1.0"}}function Me(){return be=new nn.Command,be.name("fnmap").description("AI code indexing tool - Analyzes JS/TS code structure and generates structured code maps").version(Be(),"-v, --version","Show version number").option("-f, --files <files>","Process specified files (comma-separated)",e=>e.split(",").map(r=>$e(r.trim())).filter(Boolean)).option("-d, --dir <dir>","Process all code files in directory",e=>$e(e)).option("-p, --project <dir>","Specify project root directory (default: current directory)",e=>$e(e),process.env.CLAUDE_PROJECT_DIR??process.cwd()).option("-c, --changed","Process only git changed files (staged + modified + untracked)").option("-s, --staged","Process only git staged files (for pre-commit hook)").option("-m, --mermaid [mode]","Generate Mermaid call graph (file=file-level, project=project-level)").option("-l, --log","Show detailed processing logs").option("--init","Create default config file and setup project (interactive)").option("--clear","Clear generated files (.fnmap, *.fnmap, *.mermaid)").argument("[files...]","Directly specify file paths").allowUnknownOption(!1).addHelpText("after",`
4
4
  Configuration files (by priority):
5
5
  .fnmaprc JSON config file
6
6
  .fnmaprc.json JSON config file
7
7
  package.json#fnmap fnmap field in package.json
8
8
 
9
9
  Output:
10
- .fnmap Code index file (imports, functions, classes, constants, call graph)
10
+ .fnmap Code index file in directory mode (imports, functions, classes, constants, call graph)
11
+ *.fnmap Individual file index when using --files (e.g., module.fnmap)
11
12
  *.mermaid Mermaid call graph (when using --mermaid file)
12
13
  .fnmap.mermaid Project-level Mermaid call graph (when using --mermaid project)
13
14
 
@@ -15,20 +16,23 @@ Examples:
15
16
  $ fnmap --dir src Process src directory
16
17
  $ fnmap --files a.js,b.js Process specified files
17
18
  $ fnmap --changed Process git changed files
18
- $ fnmap --staged -q For pre-commit hook usage
19
+ $ fnmap --staged For pre-commit hook usage
20
+ $ fnmap --log --dir src Show detailed processing logs
19
21
  $ fnmap --mermaid file --dir src Generate file-level call graphs
20
22
  $ fnmap --mermaid project Generate project-level call graph
21
- $ fnmap --init Create config file
22
- `),G}function M(){return G||ne()}const _e={get opts(){return M().opts.bind(M())},get args(){return M().args},get parse(){return M().parse.bind(M())}};function ue(e){const o=[".fnmaprc",".fnmaprc.json"];for(const n of o){const a=h.join(e,n);if(C.existsSync(a))try{const l=C.readFileSync(a,"utf-8");if(!l.trim()){$.warn(`Config file is empty: ${n}. Using default config / 配置文件为空,使用默认配置`);continue}let g;try{g=JSON.parse(l)}catch(d){const m=d,r=q(A.CONFIG_ERROR,`Failed to parse config file: ${n} / 配置文件解析失败`,{file:a,line:m.lineNumber,column:m.columnNumber,suggestion:"Check JSON syntax, ensure proper quotes and commas / 检查 JSON 语法,确保引号和逗号正确"});$.warn(r);continue}const p=Q(g);if(!p.valid){$.warn(`Invalid config in ${n}: ${p.error}`);continue}return{config:g,source:n}}catch(l){const g=l,p=q(A.FILE_READ_ERROR,`Failed to read config file: ${n} / 配置文件读取失败`,{file:a,suggestion:g.message});$.warn(p)}}const s=h.join(e,"package.json");if(C.existsSync(s))try{const n=JSON.parse(C.readFileSync(s,"utf-8"));if(n.fnmap){const a=Q(n.fnmap);if(!a.valid)$.warn(`Invalid fnmap config in package.json: ${a.error}`);else return{config:n.fnmap,source:"package.json#fnmap"}}}catch{}return{config:null,source:null}}function pe(e){return e?{...H,...e,exclude:[...e.exclude??[]]}:H}function te(e){return e.endsWith(".d.ts")||e.endsWith(".d.tsx")||e.endsWith(".d.mts")}function Ne(e){try{return P.execSync("git rev-parse --show-toplevel",{cwd:e,encoding:"utf-8"}).trim()}catch{return null}}function me(e,o=!1){const s=[];try{const n=Ne(e);if(!n)return[];let a;if(o)a=P.execSync("git diff --cached --name-only --diff-filter=ACMR",{cwd:e,encoding:"utf-8"});else{const p=P.execSync("git diff --cached --name-only --diff-filter=ACMR",{cwd:e,encoding:"utf-8"}),d=P.execSync("git diff --name-only --diff-filter=ACMR",{cwd:e,encoding:"utf-8"}),m=P.execSync("git ls-files --others --exclude-standard",{cwd:e,encoding:"utf-8"});a=`${p}
23
- ${d}
24
- ${m}`}const l=a.split(`
25
- `).map(p=>p.trim()).filter(Boolean).filter(p=>{const d=h.extname(p);return W.includes(d)&&!te(p)}),g=[...new Set(l)];for(const p of g){const d=h.resolve(n,p);C.existsSync(d)&&d.startsWith(h.resolve(e))&&s.push(d)}}catch{return[]}return s}function Te(e){const o=[];if(!C.existsSync(e))return o;try{const s=C.readdirSync(e,{withFileTypes:!0});for(const n of s)if(n.isFile()){const a=h.extname(n.name);W.includes(a)&&!te(n.name)&&o.push(h.join(e,n.name))}}catch{return o}return o}function U(e,o=e,s=ee,n=0,a=new Set){const l=[];if(!C.existsSync(e))return $.warn(`Directory does not exist: ${e} / 目录不存在`),l;if(n>X)return $.warn(`Max directory depth (${X}) exceeded: ${e} / 超过最大目录深度`),l;let g;try{g=C.realpathSync(e)}catch(d){const m=d;return $.warn(`Cannot resolve real path: ${e}. Reason: ${m.message} / 无法解析真实路径`),l}if(a.has(g))return $.warn(`Circular reference detected, skipping: ${e} / 检测到循环引用`),l;a.add(g);let p;try{p=C.readdirSync(e,{withFileTypes:!0})}catch(d){const m=d;return m.code==="EACCES"||m.code==="EPERM"?$.warn(`Permission denied: ${e} / 权限不足`):$.warn(`Failed to read directory: ${e}. Reason: ${m.message} / 读取目录失败`),l}for(const d of p)try{const m=h.join(e,d.name);if(d.isDirectory())s.includes(d.name)||l.push(...U(m,o,s,n+1,a));else if(d.isFile()){const r=h.extname(d.name);W.includes(r)&&!te(d.name)&&l.push(h.relative(o,m))}}catch(m){const r=m;$.warn(`Error processing entry: ${d.name}. Reason: ${r.message} / 处理条目出错`)}return l}function k(e){if(!e)return"";const s=e.value.split(`
26
- `).map(n=>n.replace(/^\s*\*\s?/,"").trim());for(const n of s)if(n.startsWith("@description "))return n.slice(13).trim().slice(0,60);for(const n of s)if(n&&!n.startsWith("@")&&!n.startsWith("/"))return n.slice(0,60);return""}function B(e,o){if(e.leadingComments&&e.leadingComments.length>0)return e.leadingComments[e.leadingComments.length-1]??null;if(o&&(o.type==="ExportNamedDeclaration"||o.type==="ExportDefaultDeclaration")){const s=o;if(s.leadingComments&&s.leadingComments.length>0)return s.leadingComments[s.leadingComments.length-1]??null}return null}const J=typeof z=="function"?z:z.default;function re(e,o){var f,S;if(e==null)return{parseError:"Code content is null or undefined / 代码内容为空",errorType:A.VALIDATION_ERROR};if(typeof e!="string")return{parseError:"Code must be a string / 代码必须是字符串类型",errorType:A.VALIDATION_ERROR};if(!e.trim())return{description:"",imports:[],functions:[],classes:[],constants:[],callGraph:{}};const s={description:"",imports:[],functions:[],classes:[],constants:[],callGraph:{}},n=e.match(/^\/\*\*[\s\S]*?\*\//);if(n){const t=n[0].split(`
27
- `).map(i=>i.replace(/^\s*\*\s?/,"").trim()).filter(i=>i&&!i.startsWith("/")&&!i.startsWith("@ai"));for(const i of t)if(i.startsWith("@description ")){s.description=i.slice(13).trim();break}if(!s.description&&t.length>0){const i=t.find(y=>!y.startsWith("@"));i&&(s.description=i)}}let a;try{const c=o&&(o.endsWith(".ts")||o.endsWith(".tsx"));a=Ie.parse(e,{sourceType:"unambiguous",plugins:["jsx","classPrivateProperties","classPrivateMethods",...c?["typescript"]:[]]})}catch(c){const t=c;return{parseError:q(A.PARSE_ERROR,`Syntax error: ${t.message} / 语法错误`,{file:o??void 0,line:(f=t.loc)==null?void 0:f.line,column:(S=t.loc)==null?void 0:S.column,suggestion:"Check syntax errors in the file / 检查文件中的语法错误"}),loc:t.loc,errorType:A.PARSE_ERROR}}const l=new Map,g=new Map,p=new Map;function d(c){var i,y,I;let t=c;for(;t;){if(t.node.type==="FunctionDeclaration"){const E=t.node;if(E.id)return E.id.name}if(t.node.type==="ClassMethod"){const E=t.node,F=(i=t.parentPath)==null?void 0:i.parentPath,R=F==null?void 0:F.node,b=((y=R==null?void 0:R.id)==null?void 0:y.name)??"",v=((I=E.key)==null?void 0:I.name)??"";return b?`${b}.${v}`:v}if(t.node.type==="ArrowFunctionExpression"||t.node.type==="FunctionExpression"){const E=t.parent;if((E==null?void 0:E.type)==="VariableDeclarator"){const R=E.id;if(R!=null&&R.name)return R.name}}t=t.parentPath}return null}J(a,{VariableDeclarator(c){var i,y,I,E;const t=c.node;if(((i=t.init)==null?void 0:i.type)==="CallExpression"&&((y=t.init.callee)==null?void 0:y.type)==="Identifier"&&t.init.callee.name==="require"&&((E=(I=t.init.arguments)==null?void 0:I[0])==null?void 0:E.type)==="StringLiteral"){const F=t.init.arguments[0].value;if(l.has(F)||l.set(F,new Set),t.id.type==="Identifier"){const R=t.id.name;l.get(F).add(R),g.set(R,F),p.set(R,new Set)}else if(t.id.type==="ObjectPattern"){for(const R of t.id.properties)if(R.type==="ObjectProperty"&&R.key.type==="Identifier"){const b=R.value.type==="Identifier"?R.value.name:R.key.name;l.get(F).add(R.key.name),g.set(b,F),p.set(b,new Set)}}}},CallExpression(c){var i,y,I,E,F,R;const t=c.node;if(((i=t.callee)==null?void 0:i.type)==="Identifier"&&t.callee.name==="require"&&((I=(y=t.arguments)==null?void 0:y[0])==null?void 0:I.type)==="StringLiteral"){const b=c.parent;if((b==null?void 0:b.type)==="MemberExpression"&&((E=b.property)==null?void 0:E.type)==="Identifier"){const v=t.arguments[0].value;l.has(v)||l.set(v,new Set),l.get(v).add(b.property.name);const N=(F=c.parentPath)==null?void 0:F.parent;if((N==null?void 0:N.type)==="VariableDeclarator"){const T=N;((R=T.id)==null?void 0:R.type)==="Identifier"&&(g.set(T.id.name,v),p.set(T.id.name,new Set))}}}},ImportDeclaration(c){const t=c.node,i=t.source.value;l.has(i)||l.set(i,new Set);for(const y of t.specifiers){let I,E;if(y.type==="ImportDefaultSpecifier")I="default",E=y.local.name;else if(y.type==="ImportNamespaceSpecifier")I="*",E=y.local.name;else if(y.type==="ImportSpecifier"){const F=y.imported;I=F.type==="Identifier"?F.name:F.value,E=y.local.name}I&&E&&(l.get(i).add(I),g.set(E,i),p.set(E,new Set))}}}),J(a,{Identifier(c){const t=c.node.name;if(p.has(t)){const i=c.parent;if((i==null?void 0:i.type)==="VariableDeclarator"&&i.id===c.node||(i==null?void 0:i.type)==="ImportSpecifier"||(i==null?void 0:i.type)==="ImportDefaultSpecifier")return;const y=d(c);y&&p.get(t).add(y)}},FunctionDeclaration(c){var R,b,v,N,T;const t=c.node,i=((R=t.id)==null?void 0:R.name)??"[anonymous]",y=t.params.map(_=>{var D,L;return _.type==="Identifier"?_.name:_.type==="AssignmentPattern"&&((D=_.left)==null?void 0:D.type)==="Identifier"?_.left.name+"?":_.type==="RestElement"&&((L=_.argument)==null?void 0:L.type)==="Identifier"?"..."+_.argument.name:"?"}),I=((v=(b=t.loc)==null?void 0:b.start)==null?void 0:v.line)??0,E=((T=(N=t.loc)==null?void 0:N.end)==null?void 0:T.line)??0,F=k(B(t,c.parent));s.functions.push({name:i,params:y.join(","),startLine:I,endLine:E,description:F})},ClassDeclaration(c){var b,v,N,T,_,D,L,se,oe,ie;const t=c.node,i=((b=t.id)==null?void 0:b.name)??"[anonymous]",y=((N=(v=t.loc)==null?void 0:v.start)==null?void 0:N.line)??0,I=((_=(T=t.loc)==null?void 0:T.end)==null?void 0:_.line)??0,E=((D=t.superClass)==null?void 0:D.type)==="Identifier"?t.superClass.name:null,F=k(B(t,c.parent)),R=[];if((L=t.body)!=null&&L.body){for(const O of t.body.body)if(O.type==="ClassMethod"){const Ee=((se=O.key)==null?void 0:se.type)==="Identifier"?O.key.name:"[computed]",Se=O.params.map(j=>{var ce;return j.type==="Identifier"?j.name:j.type==="AssignmentPattern"&&((ce=j.left)==null?void 0:ce.type)==="Identifier"?j.left.name+"?":"?"}),Re=((ie=(oe=O.loc)==null?void 0:oe.start)==null?void 0:ie.line)??0;let ae="";const V=O.leadingComments;V&&V.length>0&&(ae=k(V[V.length-1])),R.push({name:Ee,params:Se.join(","),line:Re,static:O.static,kind:O.kind,description:ae})}}s.classes.push({name:i,superClass:E,startLine:y,endLine:I,methods:R,description:F})},VariableDeclaration(c){var y,I,E;const t=c.parent.type;if(t!=="Program"&&t!=="ExportNamedDeclaration")return;const i=c.node;if(i.kind==="const"){const F=k(B(i,c.parent));for(const R of i.declarations){const b=((y=R.id)==null?void 0:y.type)==="Identifier"?R.id.name:void 0;if(b&&b===b.toUpperCase()&&b.length>2){const v=((E=(I=i.loc)==null?void 0:I.start)==null?void 0:E.line)??0;s.constants.push({name:b,line:v,description:F})}}}}});for(const[c,t]of l){const i=new Set;for(const y of g.keys())if(g.get(y)===c&&p.has(y))for(const I of p.get(y))i.add(I);s.imports.push({module:c,members:Array.from(t),usedIn:Array.from(i)})}const m=new Set;for(const c of s.functions)m.add(c.name);for(const c of s.classes)for(const t of c.methods)m.add(t.name),m.add(`${c.name}.${t.name}`);const r=new Set(g.keys()),u=new Map;J(a,{CallExpression(c){var y,I;const t=c.node;let i=null;if(t.callee.type==="Identifier")i=t.callee.name;else if(t.callee.type==="MemberExpression"&&((y=t.callee.property)==null?void 0:y.type)==="Identifier"){const E=((I=t.callee.object)==null?void 0:I.type)==="Identifier"?t.callee.object.name:void 0,F=t.callee.property.name;E&&r.has(E)?i=`${E}.${F}`:i=F}if(i){const E=d(c);if(E&&E!==i){const F=m.has(i),R=r.has(i)||i.includes(".")&&r.has(i.split(".")[0]);(F||R)&&(u.has(E)||u.set(E,new Set),u.get(E).add(i))}}}}),s.callGraph={};for(const[c,t]of u)s.callGraph[c]=Array.from(t);return s.isPureType=Oe(a),s}function Oe(e){let o=!1;for(const s of e.program.body){switch(s.type){case"TSTypeAliasDeclaration":case"TSInterfaceDeclaration":case"TSEnumDeclaration":break;case"ImportDeclaration":s.importKind!=="type"&&s.specifiers.some(a=>a.type==="ImportSpecifier"?a.importKind!=="type":!0)&&s.specifiers.length>0&&(o=!0);break;case"ExportNamedDeclaration":if(s.exportKind==="type")break;if(s.declaration){const n=s.declaration.type;n!=="TSTypeAliasDeclaration"&&n!=="TSInterfaceDeclaration"&&(o=!0)}else s.specifiers&&s.specifiers.length>0&&s.specifiers.some(a=>a.type==="ExportSpecifier"?a.exportKind!=="type":!0)&&(o=!0);break;case"ExportDefaultDeclaration":o=!0;break;case"ExportAllDeclaration":s.exportKind!=="type"&&(o=!0);break;default:o=!0;break}if(o)break}return!o}function we(e,o){const s=[];let n=`/*@AI ${o}`;e.description&&(n+=` - ${e.description.slice(0,50)}`),s.push(n);for(const a of e.imports){const l=Array.isArray(a.members)?a.members.join(","):"";let g=`<${a.module}:${l}`;Array.isArray(a.usedIn)&&a.usedIn.length>0&&(g+=` ->${a.usedIn.join(",")}`),s.push(g)}for(const a of e.classes){let l=a.name;a.superClass&&(l+=`:${a.superClass}`),l+=` ${a.startLine}-${a.endLine}`,a.description&&(l+=` ${a.description}`),s.push(l);for(const g of a.methods){const p=g.static?" +":" .",d=g.kind==="get"?"get:":g.kind==="set"?"set:":"";let m=`${p}${d}${g.name}(${g.params}) ${g.line}`;g.description&&(m+=` ${g.description}`),s.push(m)}}for(const a of e.functions){let l=`${a.name}(${a.params}) ${a.startLine}-${a.endLine}`;a.description&&(l+=` ${a.description}`),s.push(l)}for(const a of e.constants){let l=`${a.name} ${a.line}`;a.description&&(l+=` ${a.description}`),s.push(l)}return s.push("@AI*/"),s.join(`
28
- `)}function De(e){let o=e;return o=o.replace(/\/\*@AI[\s\S]*?@AI\*\/\s*/g,""),o=o.replace(/\/\*\*[\s\S]*?@ai-context-end[\s\S]*?\*\/\s*/g,""),o=o.replace(/^\/\*\*[\s\S]*?\*\/\s*\n?/,""),o}function Z(e,o){var n,a,l;const s=[`@FNMAP ${h.basename(e)}/`];for(const{relativePath:g,info:p}of o){let m=`#${h.basename(g)}`;p.description&&(m+=` ${p.description.slice(0,50)}`),s.push(m);for(const r of p.imports){const u=Array.isArray(r.members)?r.members.join(","):"";s.push(` <${r.module}:${u}`)}for(const r of p.classes){let u=` ${r.name}`;r.superClass&&(u+=`:${r.superClass}`),u+=` ${r.startLine}-${r.endLine}`,r.description&&(u+=` ${r.description}`),s.push(u);for(const f of r.methods){const S=f.static?" +":" .",c=f.kind==="get"?"get:":f.kind==="set"?"set:":"";let t=`${S}${c}${f.name}(${f.params}) ${f.line}`;f.description&&(t+=` ${f.description}`);const i=`${r.name}.${f.name}`,y=((n=p.callGraph)==null?void 0:n[i])??((a=p.callGraph)==null?void 0:a[f.name]);Array.isArray(y)&&y.length>0&&(t+=` →${y.join(",")}`),s.push(t)}}for(const r of p.functions){let u=` ${r.name}(${r.params}) ${r.startLine}-${r.endLine}`;r.description&&(u+=` ${r.description}`);const f=(l=p.callGraph)==null?void 0:l[r.name];Array.isArray(f)&&f.length>0&&(u+=` →${f.join(",")}`),s.push(u)}for(const r of p.constants){let u=` ${r.name} ${r.line}`;r.description&&(u+=` ${r.description}`),s.push(u)}}return s.push("@FNMAP"),s.join(`
29
- `)}function ge(e,o){const s=["flowchart TD"],n=r=>"id_"+r.replace(/[^a-zA-Z0-9]/g,u=>`_${u.charCodeAt(0)}_`),a=r=>r.replace(/"/g,"#quot;"),l=o.functions.map(r=>r.name),g=[];for(const r of o.classes)for(const u of r.methods)g.push(`${r.name}.${u.name}`);const p=[...l,...g];if(p.length===0)return null;const d=h.basename(e,h.extname(e));s.push(` subgraph ${n(d)}["${d}"]`);for(const r of p)s.push(` ${n(r)}["${a(r)}"]`);s.push(" end");const m=o.callGraph??{};for(const[r,u]of Object.entries(m))if(Array.isArray(u)){for(const f of u)if(p.includes(f)||f.includes(".")){const S=p.includes(f)?f:f.split(".").pop();(p.includes(f)||p.some(c=>c.endsWith(S)))&&s.push(` ${n(r)} --> ${n(f)}`)}}return s.join(`
30
- `)}function ye(e,o){const s=["flowchart TD"],n=d=>"id_"+d.replace(/[^a-zA-Z0-9]/g,m=>`_${m.charCodeAt(0)}_`),a=d=>d.replace(/"/g,"#quot;"),l=new Map,g=[];for(const{relativePath:d,info:m}of o){const r=h.basename(d,h.extname(d)),u=m.functions.map(t=>t.name),f=[];for(const t of m.classes)for(const i of t.methods)f.push(`${t.name}.${i.name}`);const S=[...u,...f];l.set(d,{fileName:r,functions:S});const c=m.callGraph??{};for(const[t,i]of Object.entries(c))if(Array.isArray(i))for(const y of i)g.push({file:d,fileName:r,caller:t,callee:y})}for(const[,{fileName:d,functions:m}]of l)if(m.length!==0){s.push(` subgraph ${n(d)}["${a(d)}"]`);for(const r of m)s.push(` ${n(d)}_${n(r)}["${a(r)}"]`);s.push(" end")}const p=new Set;for(const{fileName:d,caller:m,callee:r}of g){const u=`${n(d)}_${n(m)}`;let f=null;for(const[,{fileName:S,functions:c}]of l)if(c.includes(r)){f=`${n(S)}_${n(r)}`;break}if(!f){const S=[...l.keys()].find(c=>{var t;return((t=l.get(c))==null?void 0:t.fileName)===d});if(S){const c=l.get(S);c!=null&&c.functions.includes(r)&&(f=`${n(d)}_${n(r)}`)}}if(f){const S=`${u}-->${f}`;p.has(S)||(s.push(` ${u} --> ${f}`),p.add(S))}}return s.join(`
31
- `)}function Le(e,o){const s=(o==null?void 0:o.filePath)??null;try{const n=re(e,s);return n?Y(n)?{success:!1,error:n.parseError,errorType:n.errorType,loc:n.loc}:{success:!0,info:n}:{success:!1,error:"Analysis returned null / 分析返回空值",errorType:A.PARSE_ERROR}}catch(n){return{success:!1,error:`Failed to process code / 处理代码失败: ${n.message}`,errorType:A.PARSE_ERROR}}}function he(e){const o=le(e);if(!o.valid)return{success:!1,error:o.error,errorType:o.errorType??A.VALIDATION_ERROR};try{const s=C.readFileSync(e,"utf-8"),n=re(s,e);return n?Y(n)?{success:!1,error:n.parseError,errorType:n.errorType,loc:n.loc}:{success:!0,info:n}:{success:!1,error:"Analysis returned null / 分析返回空值",errorType:A.PARSE_ERROR}}catch(s){const n=s;return{success:!1,error:q(A.FILE_READ_ERROR,"Failed to read or process file / 读取或处理文件失败",{file:e,suggestion:n.message}),errorType:A.FILE_READ_ERROR}}}const je=`
23
+ $ fnmap --init Interactive project setup
24
+ $ fnmap --clear Clear all generated files
25
+ $ fnmap --clear --dir src Clear generated files in src directory
26
+ `),be}function xe(){return be||Me()}const ln={get opts(){return xe().opts.bind(xe())},get args(){return xe().args},get parse(){return xe().parse.bind(xe())}};function Je(e){const r=[".fnmaprc",".fnmaprc.json"];for(const s of r){const c=g.join(e,s);if(F.existsSync(c))try{const f=F.readFileSync(c,"utf-8");if(!f.trim()){E.warn(`Config file is empty: ${s}. Using default config / 配置文件为空,使用默认配置`);continue}let $;try{$=JSON.parse(f)}catch(p){const h=p,o=Se(W.CONFIG_ERROR,`Failed to parse config file: ${s} / 配置文件解析失败`,{file:c,line:h.lineNumber,column:h.columnNumber,suggestion:"Check JSON syntax, ensure proper quotes and commas / 检查 JSON 语法,确保引号和逗号正确"});E.warn(o);continue}const u=De($);if(!u.valid){E.warn(`Invalid config in ${s}: ${u.error}`);continue}return{config:$,source:s}}catch(f){const $=f,u=Se(W.FILE_READ_ERROR,`Failed to read config file: ${s} / 配置文件读取失败`,{file:c,suggestion:$.message});E.warn(u)}}const t=g.join(e,"package.json");if(F.existsSync(t))try{const s=JSON.parse(F.readFileSync(t,"utf-8"));if(s.fnmap){const c=De(s.fnmap);if(!c.valid)E.warn(`Invalid fnmap config in package.json: ${c.error}`);else return{config:s.fnmap,source:"package.json#fnmap"}}}catch{}return{config:null,source:null}}function Ke(e){return e?{...Ne,...e,exclude:[...e.exclude??[]]}:Ne}function Pe(e){return e.endsWith(".d.ts")||e.endsWith(".d.tsx")||e.endsWith(".d.mts")}function fn(e){try{return Ie.execSync("git rev-parse --show-toplevel",{cwd:e,encoding:"utf-8"}).trim()}catch{return null}}function Xe(e,r=!1){const t=[];try{const s=fn(e);if(!s)return[];let c;if(r)c=Ie.execSync("git diff --cached --name-only --diff-filter=ACMR",{cwd:e,encoding:"utf-8"});else{const u=Ie.execSync("git diff --cached --name-only --diff-filter=ACMR",{cwd:e,encoding:"utf-8"}),p=Ie.execSync("git diff --name-only --diff-filter=ACMR",{cwd:e,encoding:"utf-8"}),h=Ie.execSync("git ls-files --others --exclude-standard",{cwd:e,encoding:"utf-8"});c=`${u}
27
+ ${p}
28
+ ${h}`}const f=c.split(`
29
+ `).map(u=>u.trim()).filter(Boolean).filter(u=>{const p=g.extname(u);return Fe.includes(p)&&!Pe(u)}),$=[...new Set(f)];for(const u of $){const p=g.resolve(s,u);F.existsSync(p)&&p.startsWith(g.resolve(e))&&t.push(p)}}catch{return[]}return t}function dn(e){const r=[];if(!F.existsSync(e))return r;try{const t=F.readdirSync(e,{withFileTypes:!0});for(const s of t)if(s.isFile()){const c=g.extname(s.name);Fe.includes(c)&&!Pe(s.name)&&r.push(g.join(e,s.name))}}catch{return r}return r}function Ae(e,r=e,t=Oe,s=0,c=new Set){const f=[];if(!F.existsSync(e))return E.warn(`Directory does not exist: ${e} / 目录不存在`),f;if(s>je)return E.warn(`Max directory depth (${je}) exceeded: ${e} / 超过最大目录深度`),f;let $;try{$=F.realpathSync(e)}catch(p){const h=p;return E.warn(`Cannot resolve real path: ${e}. Reason: ${h.message} / 无法解析真实路径`),f}if(c.has($))return E.warn(`Circular reference detected, skipping: ${e} / 检测到循环引用`),f;c.add($);let u;try{u=F.readdirSync(e,{withFileTypes:!0})}catch(p){const h=p;return h.code==="EACCES"||h.code==="EPERM"?E.warn(`Permission denied: ${e} / 权限不足`):E.warn(`Failed to read directory: ${e}. Reason: ${h.message} / 读取目录失败`),f}for(const p of u)try{const h=g.join(e,p.name);if(p.isDirectory())t.includes(p.name)||f.push(...Ae(h,r,t,s+1,c));else if(p.isFile()){const o=g.extname(p.name);Fe.includes(o)&&!Pe(p.name)&&f.push(g.relative(r,h))}}catch(h){const o=h;E.warn(`Error processing entry: ${p.name}. Reason: ${o.message} / 处理条目出错`)}return f}function Y(e){if(!e)return"";const t=e.value.split(`
30
+ `).map(s=>s.replace(/^\s*\*\s?/,"").trim());for(const s of t)if(s.startsWith("@description "))return s.slice(13).trim().slice(0,60);for(const s of t)if(s&&!s.startsWith("@")&&!s.startsWith("/"))return s.slice(0,60);return""}function ge(e,r){if(e.leadingComments&&e.leadingComments.length>0)return e.leadingComments[e.leadingComments.length-1]??null;if(r&&(r.type==="ExportNamedDeclaration"||r.type==="ExportDefaultDeclaration")){const t=r;if(t.leadingComments&&t.leadingComments.length>0)return t.leadingComments[t.leadingComments.length-1]??null}return null}const ve=typeof Re=="function"?Re:Re.default;function Ge(e,r){var I,v;if(e==null)return{parseError:"Code content is null or undefined / 代码内容为空",errorType:W.VALIDATION_ERROR};if(typeof e!="string")return{parseError:"Code must be a string / 代码必须是字符串类型",errorType:W.VALIDATION_ERROR};if(!e.trim())return{description:"",imports:[],functions:[],classes:[],constants:[],callGraph:{}};const t={description:"",imports:[],functions:[],classes:[],constants:[],callGraph:{}},s=e.match(/^\/\*\*[\s\S]*?\*\//);if(s){const n=s[0].split(`
31
+ `).map(i=>i.replace(/^\s*\*\s?/,"").trim()).filter(i=>i&&!i.startsWith("/")&&!i.startsWith("@ai"));for(const i of n)if(i.startsWith("@description ")){t.description=i.slice(13).trim();break}if(!t.description&&n.length>0){const i=n.find(m=>!m.startsWith("@"));i&&(t.description=i)}}let c;try{const a=r&&(r.endsWith(".ts")||r.endsWith(".tsx"));c=tn.parse(e,{sourceType:"unambiguous",plugins:["jsx","classPrivateProperties","classPrivateMethods",...a?["typescript"]:[]]})}catch(a){const n=a;return{parseError:Se(W.PARSE_ERROR,`Syntax error: ${n.message} / 语法错误`,{file:r??void 0,line:(I=n.loc)==null?void 0:I.line,column:(v=n.loc)==null?void 0:v.column,suggestion:"Check syntax errors in the file / 检查文件中的语法错误"}),loc:n.loc,errorType:W.PARSE_ERROR}}const f=new Map,$=new Map,u=new Map;function p(a){if(!a)return null;if(a.type==="Identifier")return a.name;if(a.type==="MemberExpression"){const n=a.object,i=a.property;if(n.type==="Identifier"&&i.type==="Identifier")return n.name}return null}function h(a){var i,m,b;let n=a;for(;n;){if(n.node.type==="FunctionDeclaration"){const x=n.node;if(x.id)return x.id.name}if(n.node.type==="ClassMethod"){const x=n.node,R=(i=n.parentPath)==null?void 0:i.parentPath,C=R==null?void 0:R.node,j=((m=C==null?void 0:C.id)==null?void 0:m.name)??"",O=((b=x.key)==null?void 0:b.name)??"";return j?`${j}.${O}`:O}if(n.node.type==="ArrowFunctionExpression"||n.node.type==="FunctionExpression"){const x=n.parent;if((x==null?void 0:x.type)==="VariableDeclarator"){const C=x.id;if(C!=null&&C.name)return C.name}}n=n.parentPath}return null}ve(c,{VariableDeclarator(a){var i,m,b,x;const n=a.node;if(((i=n.init)==null?void 0:i.type)==="CallExpression"&&((m=n.init.callee)==null?void 0:m.type)==="Identifier"&&n.init.callee.name==="require"&&((x=(b=n.init.arguments)==null?void 0:b[0])==null?void 0:x.type)==="StringLiteral"){const R=n.init.arguments[0].value;if(f.has(R)||f.set(R,new Set),n.id.type==="Identifier"){const C=n.id.name;f.get(R).add(C),$.set(C,R),u.set(C,new Set)}else if(n.id.type==="ObjectPattern"){for(const C of n.id.properties)if(C.type==="ObjectProperty"&&C.key.type==="Identifier"){const j=C.value.type==="Identifier"?C.value.name:C.key.name;f.get(R).add(C.key.name),$.set(j,R),u.set(j,new Set)}}}},CallExpression(a){var i,m,b,x,R,C;const n=a.node;if(((i=n.callee)==null?void 0:i.type)==="Identifier"&&n.callee.name==="require"&&((b=(m=n.arguments)==null?void 0:m[0])==null?void 0:b.type)==="StringLiteral"){const j=a.parent;if((j==null?void 0:j.type)==="MemberExpression"&&((x=j.property)==null?void 0:x.type)==="Identifier"){const O=n.arguments[0].value;f.has(O)||f.set(O,new Set),f.get(O).add(j.property.name);const U=(R=a.parentPath)==null?void 0:R.parent;if((U==null?void 0:U.type)==="VariableDeclarator"){const V=U;((C=V.id)==null?void 0:C.type)==="Identifier"&&($.set(V.id.name,O),u.set(V.id.name,new Set))}}}},ImportDeclaration(a){const n=a.node,i=n.source.value;f.has(i)||f.set(i,new Set);for(const m of n.specifiers){let b,x;if(m.type==="ImportDefaultSpecifier")b="default",x=m.local.name;else if(m.type==="ImportNamespaceSpecifier")b="*",x=m.local.name;else if(m.type==="ImportSpecifier"){const R=m.imported;b=R.type==="Identifier"?R.name:R.value,x=m.local.name}b&&x&&(f.get(i).add(b),$.set(x,i),u.set(x,new Set))}}}),ve(c,{Identifier(a){const n=a.node.name;if(u.has(n)){const i=a.parent;if((i==null?void 0:i.type)==="VariableDeclarator"&&i.id===a.node||(i==null?void 0:i.type)==="ImportSpecifier"||(i==null?void 0:i.type)==="ImportDefaultSpecifier")return;const m=h(a);m&&u.get(n).add(m)}},FunctionDeclaration(a){var C,j,O,U,V;if(a.parent.type==="ExportDefaultDeclaration")return;const n=a.node,i=((C=n.id)==null?void 0:C.name)??"[anonymous]",m=n.params.map(G=>{var K,X;return G.type==="Identifier"?G.name:G.type==="AssignmentPattern"&&((K=G.left)==null?void 0:K.type)==="Identifier"?G.left.name+"?":G.type==="RestElement"&&((X=G.argument)==null?void 0:X.type)==="Identifier"?"..."+G.argument.name:"?"}),b=((O=(j=n.loc)==null?void 0:j.start)==null?void 0:O.line)??0,x=((V=(U=n.loc)==null?void 0:U.end)==null?void 0:V.line)??0,R=Y(ge(n,a.parent));t.functions.push({name:i,params:m.join(","),startLine:b,endLine:x,description:R})},ClassDeclaration(a){var j,O,U,V,G,K,X,ee,ne;if(a.parent.type==="ExportDefaultDeclaration")return;const n=a.node,i=((j=n.id)==null?void 0:j.name)??"[anonymous]",m=((U=(O=n.loc)==null?void 0:O.start)==null?void 0:U.line)??0,b=((G=(V=n.loc)==null?void 0:V.end)==null?void 0:G.line)??0,x=p(n.superClass),R=Y(ge(n,a.parent)),C=[];if((K=n.body)!=null&&K.body){for(const z of n.body.body)if(z.type==="ClassMethod"){const se=((X=z.key)==null?void 0:X.type)==="Identifier"?z.key.name:"[computed]",ie=z.params.map(H=>{var re;return H.type==="Identifier"?H.name:H.type==="AssignmentPattern"&&((re=H.left)==null?void 0:re.type)==="Identifier"?H.left.name+"?":"?"}),oe=((ne=(ee=z.loc)==null?void 0:ee.start)==null?void 0:ne.line)??0;let te="";const Z=z.leadingComments;Z&&Z.length>0&&(te=Y(Z[Z.length-1])),C.push({name:se,params:ie.join(","),line:oe,static:z.static,kind:z.kind,description:te})}}t.classes.push({name:i,superClass:x,startLine:m,endLine:b,methods:C,description:R})},VariableDeclaration(a){var b,x,R,C,j,O,U,V,G,K,X,ee,ne,z,se,ie,oe,te,Z,H,re,ce,le,fe,de,me,pe,ae,B,L,J;const n=a.parent.type;if(n!=="Program"&&n!=="ExportNamedDeclaration")return;const i=a.node,m=Y(ge(i,a.parent));for(const k of i.declarations){const _=((b=k.id)==null?void 0:b.type)==="Identifier"?k.id.name:void 0;if(_){if(((x=k.init)==null?void 0:x.type)==="ArrowFunctionExpression"||((R=k.init)==null?void 0:R.type)==="FunctionExpression"){const d=k.init.params.map(P=>{var N,q;return P.type==="Identifier"?P.name:P.type==="AssignmentPattern"&&((N=P.left)==null?void 0:N.type)==="Identifier"?P.left.name+"?":P.type==="RestElement"&&((q=P.argument)==null?void 0:q.type)==="Identifier"?"..."+P.argument.name:"?"}),A=((j=(C=i.loc)==null?void 0:C.start)==null?void 0:j.line)??0,M=((U=(O=i.loc)==null?void 0:O.end)==null?void 0:U.line)??0;t.functions.push({name:_,params:d.join(","),startLine:A,endLine:M,description:m});continue}if(((V=k.init)==null?void 0:V.type)==="ClassExpression"){const w=k.init,d=((K=(G=i.loc)==null?void 0:G.start)==null?void 0:K.line)??0,A=((ee=(X=i.loc)==null?void 0:X.end)==null?void 0:ee.line)??0,M=p(w.superClass),P=[];if((ne=w.body)!=null&&ne.body){for(const N of w.body.body)if(N.type==="ClassMethod"){const q=((z=N.key)==null?void 0:z.type)==="Identifier"?N.key.name:"[computed]",T=N.params.map(Ee=>{var Ue;return Ee.type==="Identifier"?Ee.name:Ee.type==="AssignmentPattern"&&((Ue=Ee.left)==null?void 0:Ue.type)==="Identifier"?Ee.left.name+"?":"?"}),D=((ie=(se=N.loc)==null?void 0:se.start)==null?void 0:ie.line)??0;let Q="";const ue=N.leadingComments;ue&&ue.length>0&&(Q=Y(ue[ue.length-1])),P.push({name:q,params:T.join(","),line:D,static:N.static,kind:N.kind,description:Q})}}t.classes.push({name:_,superClass:M,startLine:d,endLine:A,methods:P,description:m});continue}if(((oe=k.init)==null?void 0:oe.type)==="ObjectExpression"){const w=k.init;for(const d of w.properties)if(d.type==="ObjectMethod"){const A=((te=d.key)==null?void 0:te.type)==="Identifier"?`${_}.${d.key.name}`:`${_}.[computed]`,M=d.params.map(T=>{var D,Q;return T.type==="Identifier"?T.name:T.type==="AssignmentPattern"&&((D=T.left)==null?void 0:D.type)==="Identifier"?T.left.name+"?":T.type==="RestElement"&&((Q=T.argument)==null?void 0:Q.type)==="Identifier"?"..."+T.argument.name:"?"}),P=((H=(Z=d.loc)==null?void 0:Z.start)==null?void 0:H.line)??0,N=((ce=(re=d.loc)==null?void 0:re.end)==null?void 0:ce.line)??0;let q="";d.leadingComments&&d.leadingComments.length>0&&(q=Y(d.leadingComments[d.leadingComments.length-1])),t.functions.push({name:A,params:M.join(","),startLine:P,endLine:N,description:q})}else if(d.type==="ObjectProperty"&&((le=d.key)==null?void 0:le.type)==="Identifier"&&(((fe=d.value)==null?void 0:fe.type)==="ArrowFunctionExpression"||((de=d.value)==null?void 0:de.type)==="FunctionExpression")){const A=d.value,M=`${_}.${d.key.name}`,P=A.params.map(D=>{var Q,ue;return D.type==="Identifier"?D.name:D.type==="AssignmentPattern"&&((Q=D.left)==null?void 0:Q.type)==="Identifier"?D.left.name+"?":D.type==="RestElement"&&((ue=D.argument)==null?void 0:ue.type)==="Identifier"?"..."+D.argument.name:"?"}),N=((pe=(me=d.loc)==null?void 0:me.start)==null?void 0:pe.line)??0,q=((B=(ae=d.loc)==null?void 0:ae.end)==null?void 0:B.line)??0;let T="";d.leadingComments&&d.leadingComments.length>0&&(T=Y(d.leadingComments[d.leadingComments.length-1])),t.functions.push({name:M,params:P.join(","),startLine:N,endLine:q,description:T})}}if(i.kind==="const"&&_===_.toUpperCase()&&_.length>2){const w=((J=(L=i.loc)==null?void 0:L.start)==null?void 0:J.line)??0;t.constants.push({name:_,line:w,description:m})}}}},ExportDefaultDeclaration(a){var b,x,R,C,j,O,U,V,G,K,X,ee,ne,z,se,ie,oe,te,Z,H,re,ce,le,fe,de,me,pe,ae,B;const n=a.node,i=n.declaration,m=Y(ge(n,a.parent));if(i.type==="FunctionDeclaration"){const L=i,J=((b=L.id)==null?void 0:b.name)??"[default]",k=L.params.map(d=>{var A,M;return d.type==="Identifier"?d.name:d.type==="AssignmentPattern"&&((A=d.left)==null?void 0:A.type)==="Identifier"?d.left.name+"?":d.type==="RestElement"&&((M=d.argument)==null?void 0:M.type)==="Identifier"?"..."+d.argument.name:"?"}),_=((R=(x=n.loc)==null?void 0:x.start)==null?void 0:R.line)??0,w=((j=(C=n.loc)==null?void 0:C.end)==null?void 0:j.line)??0;t.functions.push({name:J,params:k.join(","),startLine:_,endLine:w,description:m});return}if(i.type==="ClassDeclaration"){const L=i,J=((O=L.id)==null?void 0:O.name)??"[default]",k=((V=(U=n.loc)==null?void 0:U.start)==null?void 0:V.line)??0,_=((K=(G=n.loc)==null?void 0:G.end)==null?void 0:K.line)??0,w=p(L.superClass),d=[];if((X=L.body)!=null&&X.body){for(const A of L.body.body)if(A.type==="ClassMethod"){const M=((ee=A.key)==null?void 0:ee.type)==="Identifier"?A.key.name:"[computed]",P=A.params.map(D=>{var Q;return D.type==="Identifier"?D.name:D.type==="AssignmentPattern"&&((Q=D.left)==null?void 0:Q.type)==="Identifier"?D.left.name+"?":"?"}),N=((z=(ne=A.loc)==null?void 0:ne.start)==null?void 0:z.line)??0;let q="";const T=A.leadingComments;T&&T.length>0&&(q=Y(T[T.length-1])),d.push({name:M,params:P.join(","),line:N,static:A.static,kind:A.kind,description:q})}}t.classes.push({name:J,superClass:w,startLine:k,endLine:_,methods:d,description:m});return}if(i.type==="ArrowFunctionExpression"||i.type==="FunctionExpression"){const L=i,J=L.type==="FunctionExpression"&&((se=L.id)!=null&&se.name)?L.id.name:"[default]",k=L.params.map(d=>{var A,M;return d.type==="Identifier"?d.name:d.type==="AssignmentPattern"&&((A=d.left)==null?void 0:A.type)==="Identifier"?d.left.name+"?":d.type==="RestElement"&&((M=d.argument)==null?void 0:M.type)==="Identifier"?"..."+d.argument.name:"?"}),_=((oe=(ie=n.loc)==null?void 0:ie.start)==null?void 0:oe.line)??0,w=((Z=(te=n.loc)==null?void 0:te.end)==null?void 0:Z.line)??0;t.functions.push({name:J,params:k.join(","),startLine:_,endLine:w,description:m});return}if(i.type==="ClassExpression"){const L=i,J=((H=L.id)==null?void 0:H.name)??"[default]",k=((ce=(re=n.loc)==null?void 0:re.start)==null?void 0:ce.line)??0,_=((fe=(le=n.loc)==null?void 0:le.end)==null?void 0:fe.line)??0,w=((de=L.superClass)==null?void 0:de.type)==="Identifier"?L.superClass.name:null,d=[];if((me=L.body)!=null&&me.body){for(const A of L.body.body)if(A.type==="ClassMethod"){const M=((pe=A.key)==null?void 0:pe.type)==="Identifier"?A.key.name:"[computed]",P=A.params.map(D=>{var Q;return D.type==="Identifier"?D.name:D.type==="AssignmentPattern"&&((Q=D.left)==null?void 0:Q.type)==="Identifier"?D.left.name+"?":"?"}),N=((B=(ae=A.loc)==null?void 0:ae.start)==null?void 0:B.line)??0;let q="";const T=A.leadingComments;T&&T.length>0&&(q=Y(T[T.length-1])),d.push({name:M,params:P.join(","),line:N,static:A.static,kind:A.kind,description:q})}}t.classes.push({name:J,superClass:w,startLine:k,endLine:_,methods:d,description:m})}},AssignmentExpression(a){var x,R,C,j,O,U,V,G,K,X,ee,ne,z,se,ie,oe,te,Z,H,re,ce,le,fe,de,me,pe;const n=a.node;if(a.parent.type!=="ExpressionStatement")return;const i=(x=a.parentPath)==null?void 0:x.parent;if((i==null?void 0:i.type)!=="Program")return;const m=n.left,b=n.right;if(m.type==="MemberExpression"&&((R=m.object)==null?void 0:R.type)==="Identifier"&&m.object.name==="module"&&((C=m.property)==null?void 0:C.type)==="Identifier"&&m.property.name==="exports"){const ae=Y(ge(a.parent,i));if(b.type==="FunctionExpression"||b.type==="ArrowFunctionExpression"){const B=b,L=b.type==="FunctionExpression"&&((j=b.id)!=null&&j.name)?b.id.name:"[exports]",J=B.params.map(w=>{var d,A;return w.type==="Identifier"?w.name:w.type==="AssignmentPattern"&&((d=w.left)==null?void 0:d.type)==="Identifier"?w.left.name+"?":w.type==="RestElement"&&((A=w.argument)==null?void 0:A.type)==="Identifier"?"..."+w.argument.name:"?"}),k=((U=(O=n.loc)==null?void 0:O.start)==null?void 0:U.line)??0,_=((G=(V=n.loc)==null?void 0:V.end)==null?void 0:G.line)??0;t.functions.push({name:L,params:J.join(","),startLine:k,endLine:_,description:ae});return}if(b.type==="ClassExpression"){const B=b,L=((K=B.id)==null?void 0:K.name)??"[exports]",J=((ee=(X=n.loc)==null?void 0:X.start)==null?void 0:ee.line)??0,k=((z=(ne=n.loc)==null?void 0:ne.end)==null?void 0:z.line)??0,_=p(B.superClass),w=[];if((se=B.body)!=null&&se.body){for(const d of B.body.body)if(d.type==="ClassMethod"){const A=((ie=d.key)==null?void 0:ie.type)==="Identifier"?d.key.name:"[computed]",M=d.params.map(N=>{var q;return N.type==="Identifier"?N.name:N.type==="AssignmentPattern"&&((q=N.left)==null?void 0:q.type)==="Identifier"?N.left.name+"?":"?"}),P=((te=(oe=d.loc)==null?void 0:oe.start)==null?void 0:te.line)??0;w.push({name:A,params:M.join(","),line:P,static:d.static,kind:d.kind,description:""})}}t.classes.push({name:L,superClass:_,startLine:J,endLine:k,methods:w,description:ae});return}}if(m.type==="MemberExpression"&&((Z=m.property)==null?void 0:Z.type)==="Identifier"){const ae=m.property.name;let B=!1;if(((H=m.object)==null?void 0:H.type)==="Identifier"&&m.object.name==="exports"&&(B=!0),((re=m.object)==null?void 0:re.type)==="MemberExpression"&&((ce=m.object.object)==null?void 0:ce.type)==="Identifier"&&m.object.object.name==="module"&&((le=m.object.property)==null?void 0:le.type)==="Identifier"&&m.object.property.name==="exports"&&(B=!0),B){const L=Y(ge(a.parent,i));if(b.type==="FunctionExpression"||b.type==="ArrowFunctionExpression"){const k=b.params.map(d=>{var A,M;return d.type==="Identifier"?d.name:d.type==="AssignmentPattern"&&((A=d.left)==null?void 0:A.type)==="Identifier"?d.left.name+"?":d.type==="RestElement"&&((M=d.argument)==null?void 0:M.type)==="Identifier"?"..."+d.argument.name:"?"}),_=((de=(fe=n.loc)==null?void 0:fe.start)==null?void 0:de.line)??0,w=((pe=(me=n.loc)==null?void 0:me.end)==null?void 0:pe.line)??0;t.functions.push({name:ae,params:k.join(","),startLine:_,endLine:w,description:L})}}}}});for(const[a,n]of f){const i=new Set;for(const m of $.keys())if($.get(m)===a&&u.has(m))for(const b of u.get(m))i.add(b);t.imports.push({module:a,members:Array.from(n),usedIn:Array.from(i)})}const o=new Set;for(const a of t.functions)o.add(a.name);for(const a of t.classes)for(const n of a.methods)o.add(n.name),o.add(`${a.name}.${n.name}`);const y=new Set($.keys()),l=new Map;ve(c,{CallExpression(a){var m,b;const n=a.node;let i=null;if(n.callee.type==="Identifier")i=n.callee.name;else if(n.callee.type==="MemberExpression"&&((m=n.callee.property)==null?void 0:m.type)==="Identifier"){const x=((b=n.callee.object)==null?void 0:b.type)==="Identifier"?n.callee.object.name:void 0,R=n.callee.property.name;x&&y.has(x)?i=`${x}.${R}`:i=R}if(i){const x=h(a);if(x&&x!==i){const R=o.has(i),C=y.has(i)||i.includes(".")&&y.has(i.split(".")[0]);(R||C)&&(l.has(x)||l.set(x,new Set),l.get(x).add(i))}}}}),t.callGraph={};for(const[a,n]of l)t.callGraph[a]=Array.from(n);return t.isPureType=mn(c),t}function mn(e){let r=!1;for(const t of e.program.body){switch(t.type){case"TSTypeAliasDeclaration":case"TSInterfaceDeclaration":case"TSEnumDeclaration":break;case"ImportDeclaration":t.importKind!=="type"&&t.specifiers.some(c=>c.type==="ImportSpecifier"?c.importKind!=="type":!0)&&t.specifiers.length>0&&(r=!0);break;case"ExportNamedDeclaration":if(t.exportKind==="type")break;if(t.declaration){const s=t.declaration.type;s!=="TSTypeAliasDeclaration"&&s!=="TSInterfaceDeclaration"&&(r=!0)}else t.specifiers&&t.specifiers.length>0&&t.specifiers.some(c=>c.type==="ExportSpecifier"?c.exportKind!=="type":!0)&&(r=!0);break;case"ExportDefaultDeclaration":r=!0;break;case"ExportAllDeclaration":t.exportKind!=="type"&&(r=!0);break;default:r=!0;break}if(r)break}return!r}function pn(e,r){const t=[];let s=`/*@AI ${r}`;e.description&&(s+=` - ${e.description.slice(0,50)}`),t.push(s);for(const c of e.imports){const f=Array.isArray(c.members)?c.members.join(","):"";let $=`<${c.module}:${f}`;Array.isArray(c.usedIn)&&c.usedIn.length>0&&($+=` ->${c.usedIn.join(",")}`),t.push($)}for(const c of e.classes){let f=c.name;c.superClass&&(f+=`:${c.superClass}`),f+=` ${c.startLine}-${c.endLine}`,c.description&&(f+=` ${c.description}`),t.push(f);for(const $ of c.methods){const u=$.static?" +":" .",p=$.kind==="get"?"get:":$.kind==="set"?"set:":"";let h=`${u}${p}${$.name}(${$.params}) ${$.line}`;$.description&&(h+=` ${$.description}`),t.push(h)}}for(const c of e.functions){let f=`${c.name}(${c.params}) ${c.startLine}-${c.endLine}`;c.description&&(f+=` ${c.description}`),t.push(f)}for(const c of e.constants){let f=`${c.name} ${c.line}`;c.description&&(f+=` ${c.description}`),t.push(f)}return t.push("@AI*/"),t.join(`
32
+ `)}function un(e){let r=e;return r=r.replace(/\/\*@AI[\s\S]*?@AI\*\/\s*/g,""),r=r.replace(/\/\*\*[\s\S]*?@ai-context-end[\s\S]*?\*\/\s*/g,""),r=r.replace(/^\/\*\*[\s\S]*?\*\/\s*\n?/,""),r}function ke(e,r){var s,c,f;const t=[`@FNMAP ${g.basename(e)}/`];for(const{relativePath:$,info:u}of r){let h=`#${g.basename($)}`;u.description&&(h+=` ${u.description.slice(0,50)}`),t.push(h);for(const o of u.imports){const y=Array.isArray(o.members)?o.members.join(","):"";t.push(` <${o.module}:${y}`)}for(const o of u.classes){let y=` ${o.name}`;o.superClass&&(y+=`:${o.superClass}`),y+=` ${o.startLine}-${o.endLine}`,o.description&&(y+=` ${o.description}`),t.push(y);for(const l of o.methods){const I=l.static?" +":" .",v=l.kind==="get"?"get:":l.kind==="set"?"set:":"";let a=`${I}${v}${l.name}(${l.params}) ${l.line}`;l.description&&(a+=` ${l.description}`);const n=`${o.name}.${l.name}`,i=((s=u.callGraph)==null?void 0:s[n])??((c=u.callGraph)==null?void 0:c[l.name]);Array.isArray(i)&&i.length>0&&(a+=` →${i.join(",")}`),t.push(a)}}for(const o of u.functions){let y=` ${o.name}(${o.params}) ${o.startLine}-${o.endLine}`;o.description&&(y+=` ${o.description}`);const l=(f=u.callGraph)==null?void 0:f[o.name];Array.isArray(l)&&l.length>0&&(y+=` →${l.join(",")}`),t.push(y)}for(const o of u.constants){let y=` ${o.name} ${o.line}`;o.description&&(y+=` ${o.description}`),t.push(y)}}return t.push("@FNMAP"),t.join(`
33
+ `)}function He(e,r){const t=["flowchart TD"],s=o=>"id_"+o.replace(/[^a-zA-Z0-9]/g,y=>`_${y.charCodeAt(0)}_`),c=o=>o.replace(/"/g,"#quot;"),f=r.functions.map(o=>o.name),$=[];for(const o of r.classes)for(const y of o.methods)$.push(`${o.name}.${y.name}`);const u=[...f,...$];if(u.length===0)return null;const p=g.basename(e,g.extname(e));t.push(` subgraph ${s(p)}["${p}"]`);for(const o of u)t.push(` ${s(o)}["${c(o)}"]`);t.push(" end");const h=r.callGraph??{};for(const[o,y]of Object.entries(h))if(Array.isArray(y)){for(const l of y)if(u.includes(l)||l.includes(".")){const I=u.includes(l)?l:l.split(".").pop();(u.includes(l)||u.some(v=>v.endsWith(I)))&&t.push(` ${s(o)} --> ${s(l)}`)}}return t.join(`
34
+ `)}function Qe(e,r){const t=["flowchart TD"],s=p=>"id_"+p.replace(/[^a-zA-Z0-9]/g,h=>`_${h.charCodeAt(0)}_`),c=p=>p.replace(/"/g,"#quot;"),f=new Map,$=[];for(const{relativePath:p,info:h}of r){const o=g.basename(p,g.extname(p)),y=h.functions.map(a=>a.name),l=[];for(const a of h.classes)for(const n of a.methods)l.push(`${a.name}.${n.name}`);const I=[...y,...l];f.set(p,{fileName:o,functions:I});const v=h.callGraph??{};for(const[a,n]of Object.entries(v))if(Array.isArray(n))for(const i of n)$.push({file:p,fileName:o,caller:a,callee:i})}for(const[,{fileName:p,functions:h}]of f)if(h.length!==0){t.push(` subgraph ${s(p)}["${c(p)}"]`);for(const o of h)t.push(` ${s(p)}_${s(o)}["${c(o)}"]`);t.push(" end")}const u=new Set;for(const{fileName:p,caller:h,callee:o}of $){const y=`${s(p)}_${s(h)}`;let l=null;for(const[,{fileName:I,functions:v}]of f)if(v.includes(o)){l=`${s(I)}_${s(o)}`;break}if(!l){const I=[...f.keys()].find(v=>{var a;return((a=f.get(v))==null?void 0:a.fileName)===p});if(I){const v=f.get(I);v!=null&&v.functions.includes(o)&&(l=`${s(p)}_${s(o)}`)}}if(l){const I=`${y}-->${l}`;u.has(I)||(t.push(` ${y} --> ${l}`),u.add(I))}}return t.join(`
35
+ `)}function yn(e,r){const t=(r==null?void 0:r.filePath)??null;try{const s=Ge(e,t);return s?Te(s)?{success:!1,error:s.parseError,errorType:s.errorType,loc:s.loc}:{success:!0,info:s}:{success:!1,error:"Analysis returned null / 分析返回空值",errorType:W.PARSE_ERROR}}catch(s){return{success:!1,error:`Failed to process code / 处理代码失败: ${s.message}`,errorType:W.PARSE_ERROR}}}function Ze(e){const r=ze(e);if(!r.valid)return{success:!1,error:r.error,errorType:r.errorType??W.VALIDATION_ERROR};try{const t=F.readFileSync(e,"utf-8"),s=Ge(t,e);return s?Te(s)?{success:!1,error:s.parseError,errorType:s.errorType,loc:s.loc}:{success:!0,info:s}:{success:!1,error:"Analysis returned null / 分析返回空值",errorType:W.PARSE_ERROR}}catch(t){const s=t;return{success:!1,error:Se(W.FILE_READ_ERROR,"Failed to read or process file / 读取或处理文件失败",{file:e,suggestion:s.message}),errorType:W.FILE_READ_ERROR}}}const Ve={},qe=`
32
36
 
33
37
  ## .fnmap Code Index Format
34
38
 
@@ -53,8 +57,24 @@ The \`.fnmap\` file provides a structured code index for quick navigation. Read
53
57
  1. Every global variable, function, class, and file module must have a **concise comment describing its purpose or functionality** - avoid describing anything else
54
58
  2. When updating code, always update related comments to reflect the changes
55
59
  3. Prefer encapsulating logic in functions rather than writing flat, sequential code
56
- `;function Me(e){const o=["CLAUDE.md","AGENTS.md"],s=C.readdirSync(e);for(const n of o){const a=s.find(l=>l.toLowerCase()===n.toLowerCase());if(a){const l=h.join(e,a);if(C.readFileSync(l,"utf-8").includes(".fnmap Code Index Format")){console.log(`${x.yellow}!${x.reset} ${a} already contains fnmap documentation`);continue}C.appendFileSync(l,je),console.log(`${x.green}✓${x.reset} Appended fnmap documentation to ${a}`)}}}function $e(){const e=ne();e.parse(process.argv);const o=e.opts(),s=e.args;o.quiet&&fe(!0);const n=h.resolve(o.project);if(o.init){const r=h.join(n,".fnmaprc");if(C.existsSync(r))console.log(`${x.yellow}!${x.reset} Config file already exists: .fnmaprc`);else{const u={enable:!0,include:["src/**/*.js","src/**/*.ts","src/**/*.jsx","src/**/*.tsx"],exclude:["node_modules","dist","build",".next","coverage","__pycache__",".cache"]};C.writeFileSync(r,JSON.stringify(u,null,2)),console.log(`${x.green}✓${x.reset} Created config file: .fnmaprc`)}Me(n);return}const a=[...o.files??[],...s].filter(r=>C.existsSync(r));let l=[],g=!1;if(o.changed||o.staged){const r=me(n,o.staged);if(r.length===0){$.info("No git changed code files detected");return}const u=new Set;for(const f of r)u.add(h.dirname(f));for(const f of u){const S=Te(f);l.push(...S)}}else if(a.length>0)g=!0,l=a.map(r=>h.isAbsolute(r)?r:h.resolve(n,r));else if(o.dir){const r=h.resolve(n,o.dir);l=U(r,n).map(f=>h.join(n,f))}else{const{config:r,source:u}=ue(n);if(r){if($.info(`Using config: ${u}`),r.enable===!1){$.info("Config file has enable set to false, skipping processing");return}const f=pe(r),S=[...ee,...f.exclude];if(f.include)for(const c of f.include){const t=c.replace(/\/\*\*\/.*$/,"").replace(/\*\*\/.*$/,""),i=t?h.resolve(n,t):n;if(C.existsSync(i)){const y=U(i,n,S);l.push(...y.map(I=>h.join(n,I)))}}}else{$.warn("No config file found. Use fnmap init to create config, or use --dir/--files to specify scope"),$.info(""),$.info("Supported config files: .fnmaprc, .fnmaprc.json, package.json#fnmap");return}}if(l.length===0){$.info("No files found to process");return}l=[...new Set(l)],$.info("=".repeat(50)),$.title("fnmap - AI Code Indexing Tool"),$.info("=".repeat(50));let p=0,d=0;const m=new Map;for(const r of l){const u=h.relative(n,r);$.info(`
57
- Analyzing: ${u}`);const f=he(r);if(f.success){p++;const S=f.info;if(S.isPureType){$.info("Skipped (pure type file) / 跳过纯类型文件");continue}$.success(`Imports: ${S.imports.length}, Functions: ${S.functions.length}, Classes: ${S.classes.length}, Constants: ${S.constants.length}`);const c=h.dirname(r);m.has(c)||m.set(c,[]),m.get(c).push({relativePath:u,info:S})}else d++,$.error(f.error)}if(m.size>0)if($.info(`
58
- Generating .fnmap index...`),g)for(const[r,u]of m)for(const{relativePath:f,info:S}of u)try{const c=Z(r,[{relativePath:f,info:S}]),t=h.basename(f,h.extname(f)),i=h.join(r,`${t}.fnmap`);C.writeFileSync(i,c),$.success(h.relative(n,i))}catch(c){const t=c;$.error(`Failed to generate .fnmap for ${f}: ${t.message}`)}else for(const[r,u]of m)try{const f=Z(r,u),S=h.join(r,".fnmap");C.writeFileSync(S,f),$.success(h.relative(n,S))}catch(f){const S=f;$.error(`Failed to generate .fnmap for ${h.relative(n,r)}: ${S.message}`)}if(o.mermaid&&m.size>0){if($.info(`
59
- Generating Mermaid call graphs...`),o.mermaid==="file"||o.mermaid===!0)for(const[r,u]of m)for(const{relativePath:f,info:S}of u)try{const c=ge(f,S);if(c){const t=h.basename(f,h.extname(f)),i=h.join(r,`${t}.mermaid`);C.writeFileSync(i,c),$.success(h.relative(n,i))}}catch(c){const t=c;$.error(`Failed to generate mermaid for ${f}: ${t.message}`)}else if(o.mermaid==="project")try{const r=[];for(const[,S]of m)r.push(...S);const u=ye(n,r),f=h.join(n,".fnmap.mermaid");C.writeFileSync(f,u),$.success(h.relative(n,f))}catch(r){const u=r;$.error(`Failed to generate project mermaid: ${u.message}`)}}$.info(`
60
- `+"=".repeat(50)),$.info(`Complete! Analyzed: ${x.green}${p}${x.reset}, Failed: ${d>0?x.red:""}${d}${x.reset}`),$.info("=".repeat(50))}require.main===module&&$e();exports.COLORS=x;exports.DEFAULT_CONFIG=H;exports.DEFAULT_EXCLUDES=ee;exports.ErrorTypes=A;exports.MAX_DIR_DEPTH=X;exports.MAX_FILE_SIZE=K;exports.SUPPORTED_EXTENSIONS=W;exports.analyzeFile=re;exports.extractJSDocDescription=k;exports.formatError=q;exports.generateAiMap=Z;exports.generateFileMermaid=ge;exports.generateHeader=we;exports.generateProjectMermaid=ye;exports.getGitChangedFiles=me;exports.getVersion=de;exports.isParseError=Y;exports.isProcessFailure=be;exports.isProcessSuccess=Ce;exports.isQuietMode=ve;exports.isValidationFailure=Ae;exports.isValidationSuccess=xe;exports.loadConfig=ue;exports.logger=$;exports.main=$e;exports.mergeConfig=pe;exports.processCode=Le;exports.processFile=he;exports.program=_e;exports.removeExistingHeaders=De;exports.scanDirectory=U;exports.setQuietMode=fe;exports.setupCLI=ne;exports.validateConfig=Q;exports.validateFilePath=le;
60
+ `,We=`
61
+ # fnmap generated files
62
+ .fnmap
63
+ *.fnmap
64
+ *.mermaid
65
+ .fnmap.mermaid
66
+ `;function Ce(e,r){return new Promise(t=>{e.question(r,s=>{t(s.trim())})})}function Ye(e,r){let t=0;const s=["node_modules",".git","dist","build",".next","coverage"];if(!F.existsSync(e))return E.warn(`Directory does not exist: ${e}`),0;const c=F.readdirSync(e,{withFileTypes:!0});for(const f of c){const $=g.join(e,f.name);if(f.isDirectory()){if(s.includes(f.name))continue;t+=Ye($,r)}else if(f.isFile()){const u=f.name;if(u===".fnmap"||u.endsWith(".fnmap")||u.endsWith(".mermaid"))try{F.unlinkSync($),E.success(`Deleted: ${g.relative(r,$)}`),t++}catch(p){const h=p;E.error(`Failed to delete ${g.relative(r,$)}: ${h.message}`)}}}return t}function gn(e,r){E.title("fnmap - Clear Generated Files"),E.info("=".repeat(50));const t=r?g.resolve(e,r):e,s=Ye(t,e);E.info("=".repeat(50)),s>0?E.success(`Cleared ${s} generated file(s)`):E.info("No generated files found")}function hn(e){const r=g.join(e,".gitignore");if(F.existsSync(r)){const t=F.readFileSync(r,"utf-8");if(t.includes("fnmap generated files")||t.includes("*.fnmap")){console.log(`${S.yellow}!${S.reset} .gitignore already contains fnmap rules`);return}F.appendFileSync(r,We)}else F.writeFileSync(r,We.trim()+`
67
+ `);console.log(`${S.green}✓${S.reset} Added fnmap rules to .gitignore`)}function we(e,r){const t=g.dirname(e);if(F.existsSync(t)||F.mkdirSync(t,{recursive:!0}),F.existsSync(e)){if(F.readFileSync(e,"utf-8").includes(".fnmap Code Index Format")){console.log(`${S.yellow}!${S.reset} ${r} already contains fnmap documentation`);return}F.appendFileSync(e,qe)}else F.writeFileSync(e,qe.trim()+`
68
+ `);console.log(`${S.green}✓${S.reset} Added fnmap documentation to ${r}`)}async function $n(e){const r=Ve.createInterface({input:process.stdin,output:process.stdout});console.log(`
69
+ ${S.bold}fnmap - Interactive Setup${S.reset}`),console.log("=".repeat(50));try{const t=g.join(e,".fnmaprc");if(F.existsSync(t))console.log(`${S.yellow}!${S.reset} Config file already exists: .fnmaprc`);else{const y={enable:!0,include:["src/**/*.js","src/**/*.ts","src/**/*.jsx","src/**/*.tsx"],exclude:["node_modules","dist","build",".next","coverage","__pycache__",".cache"]};F.writeFileSync(t,JSON.stringify(y,null,2)),console.log(`${S.green}✓${S.reset} Created config file: .fnmaprc`)}(await Ce(r,`
70
+ Add fnmap rules to .gitignore? (Y/n): `)).toLowerCase()!=="n"&&hn(e);const c=g.join(e,"CLAUDE.md"),f=g.join(e,"AGENTS.md"),$=g.join(Ve.homedir(),".claude","CLAUDE.md"),u=F.existsSync(c),p=F.existsSync(f),h=F.existsSync($);if(!(u||p))console.log(`
71
+ ${S.yellow}!${S.reset} No CLAUDE.md or AGENTS.md found in project.`),(await Ce(r,"Create CLAUDE.md with fnmap documentation? (Y/n): ")).toLowerCase()!=="n"&&we(c,"CLAUDE.md");else{console.log(`
72
+ ${S.bold}Select files to add fnmap documentation:${S.reset}`),console.log(`(Enter numbers separated by comma, e.g., 1,2)
73
+ `);const y=[];let l=1;u&&y.push({key:String(l++),label:"Project CLAUDE.md",path:c,exists:!0}),y.push({key:String(l++),label:"User CLAUDE.md (~/.claude/CLAUDE.md)",path:$,exists:h}),p&&y.push({key:String(l++),label:"AGENTS.md",path:f,exists:!0});const I=String(l);for(const n of y){const i=n.exists?`${S.green}[exists]${S.reset}`:`${S.gray}[new]${S.reset}`;console.log(` ${n.key}. ${n.label} ${i}`)}console.log(` ${I}. Custom file path`),console.log(` 0. Skip
74
+ `);const a=(await Ce(r,"Your choice: ")).split(",").map(n=>n.trim()).filter(Boolean);if(a.includes("0")||a.length===0)console.log("Skipped adding documentation to files.");else for(const n of a)if(n===I){const i=await Ce(r,"Enter custom file path: ");if(i){const m=g.isAbsolute(i)?i:g.resolve(e,i);we(m,i)}}else{const i=y.find(m=>m.key===n);i&&we(i.path,i.label)}}console.log(`
75
+ `+"=".repeat(50)),console.log(`${S.green}✓${S.reset} Setup complete!`),console.log(`
76
+ Run ${S.bold}fnmap${S.reset} or ${S.bold}fnmap --dir src${S.reset} to generate code index.`)}finally{r.close()}}async function en(){const e=Me();e.parse(process.argv);const r=e.opts(),t=e.args;r.log&&he(!1);const s=g.resolve(r.project);if(r.clear){const o=_e();he(!1),gn(s,r.dir),he(o);return}if(r.init){const o=_e();he(!1),await $n(s),he(o);return}const c=[...r.files??[],...t.map($e)].filter(o=>F.existsSync(o));let f=[],$=!1;if(r.changed||r.staged){const o=Xe(s,r.staged);if(o.length===0){E.info("No git changed code files detected");return}const y=new Set;for(const l of o)y.add(g.dirname(l));for(const l of y){const I=dn(l);f.push(...I)}}else if(c.length>0)$=!0,f=c.map(o=>g.isAbsolute(o)?o:g.resolve(s,o));else if(r.dir){const o=g.resolve(s,r.dir);f=Ae(o,s).map(l=>g.join(s,l))}else{const{config:o,source:y}=Je(s);if(o){if(E.info(`Using config: ${y}`),o.enable===!1){E.info("Config file has enable set to false, skipping processing");return}const l=Ke(o),I=[...Oe,...l.exclude];if(l.include&&l.include.length>0){const v=new Set;for(const a of l.include){const n=a.replace(/\/\*\*\/.*$/,"").replace(/\*\*\/.*$/,"").replace(/\/\*\..*$/,"").replace(/\*\..*$/,"");n&&v.add(n)}for(const a of v){const n=g.resolve(s,a);if(F.existsSync(n)){const i=Ae(n,s,I);f.push(...i.map(m=>g.join(s,m)))}}}}else{E.warn("No config file found. Use fnmap init to create config, or use --dir/--files to specify scope"),E.info(""),E.info("Supported config files: .fnmaprc, .fnmaprc.json, package.json#fnmap");return}}if(f.length===0){E.info("No files found to process");return}f=[...new Set(f)],E.info("=".repeat(50)),E.title("fnmap - AI Code Indexing Tool"),E.info("=".repeat(50));let u=0,p=0;const h=new Map;for(const o of f){const y=g.relative(s,o);E.info(`
77
+ Analyzing: ${y}`);const l=Ze(o);if(l.success){u++;const I=l.info;if(I.isPureType){E.info("Skipped (pure type file) / 跳过纯类型文件");continue}E.success(`Imports: ${I.imports.length}, Functions: ${I.functions.length}, Classes: ${I.classes.length}, Constants: ${I.constants.length}`);const v=g.dirname(o);h.has(v)||h.set(v,[]),h.get(v).push({relativePath:y,info:I})}else p++,E.error(l.error)}if(h.size>0)if(E.info(`
78
+ Generating .fnmap index...`),$)for(const[o,y]of h)for(const{relativePath:l,info:I}of y)try{const v=ke(o,[{relativePath:l,info:I}]),a=g.basename(l,g.extname(l)),n=g.join(o,`${a}.fnmap`);F.writeFileSync(n,v),E.success(g.relative(s,n))}catch(v){const a=v;E.error(`Failed to generate .fnmap for ${l}: ${a.message}`)}else for(const[o,y]of h)try{const l=ke(o,y),I=g.join(o,".fnmap");F.writeFileSync(I,l),E.success(g.relative(s,I))}catch(l){const I=l;E.error(`Failed to generate .fnmap for ${g.relative(s,o)}: ${I.message}`)}if(r.mermaid&&h.size>0){if(E.info(`
79
+ Generating Mermaid call graphs...`),r.mermaid==="file"||r.mermaid===!0)for(const[o,y]of h)for(const{relativePath:l,info:I}of y)try{const v=He(l,I);if(v){const a=g.basename(l,g.extname(l)),n=g.join(o,`${a}.mermaid`);F.writeFileSync(n,v),E.success(g.relative(s,n))}}catch(v){const a=v;E.error(`Failed to generate mermaid for ${l}: ${a.message}`)}else if(r.mermaid==="project")try{const o=[];for(const[,I]of h)o.push(...I);const y=Qe(s,o),l=g.join(s,".fnmap.mermaid");F.writeFileSync(l,y),E.success(g.relative(s,l))}catch(o){const y=o;E.error(`Failed to generate project mermaid: ${y.message}`)}}E.info(`
80
+ `+"=".repeat(50)),E.stats(`Complete! Analyzed: ${S.green}${u}${S.reset}, Failed: ${p>0?S.red:""}${p}${S.reset}`),E.info("=".repeat(50))}require.main===module&&en().catch(e=>{console.error(e),process.exit(1)});exports.COLORS=S;exports.DEFAULT_CONFIG=Ne;exports.DEFAULT_EXCLUDES=Oe;exports.ErrorTypes=W;exports.MAX_DIR_DEPTH=je;exports.MAX_FILE_SIZE=Le;exports.SUPPORTED_EXTENSIONS=Fe;exports.analyzeFile=Ge;exports.extractJSDocDescription=Y;exports.formatError=Se;exports.generateAiMap=ke;exports.generateFileMermaid=He;exports.generateHeader=pn;exports.generateProjectMermaid=Qe;exports.getGitChangedFiles=Xe;exports.getVersion=Be;exports.isParseError=Te;exports.isProcessFailure=sn;exports.isProcessSuccess=rn;exports.isQuietMode=_e;exports.isValidationFailure=an;exports.isValidationSuccess=on;exports.loadConfig=Je;exports.logger=E;exports.main=en;exports.mergeConfig=Ke;exports.normalizePath=$e;exports.normalizePaths=cn;exports.processCode=yn;exports.processFile=Ze;exports.program=ln;exports.removeExistingHeaders=un;exports.scanDirectory=Ae;exports.setQuietMode=he;exports.setupCLI=Me;exports.validateConfig=De;exports.validateFilePath=ze;
package/dist/main.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * 主函数
3
3
  */
4
- export declare function main(): void;
4
+ export declare function main(): Promise<void>;
5
5
  //# sourceMappingURL=main.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAkEA;;GAEG;AACH,wBAAgB,IAAI,IAAI,IAAI,CA4O3B"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAmRA;;GAEG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAmP1C"}
@@ -99,8 +99,14 @@ export interface CLIOptions {
99
99
  changed?: boolean;
100
100
  staged?: boolean;
101
101
  mermaid?: boolean | 'file' | 'project';
102
- quiet?: boolean;
102
+ log?: boolean;
103
103
  init?: boolean;
104
+ clear?: boolean;
105
+ }
106
+ export interface InitOptions {
107
+ gitignore: boolean;
108
+ claudeMd: 'project' | 'user' | 'none';
109
+ cursorRules: boolean;
104
110
  }
105
111
  export interface ErrorContext {
106
112
  file?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,12 @@
1
1
  import type { ValidationResult, ErrorContext, ErrorType } from '../types';
2
+ /**
3
+ * 规范化路径,统一使用系统原生分隔符
4
+ */
5
+ export declare function normalizePath(inputPath: string): string;
6
+ /**
7
+ * 规范化多个路径
8
+ */
9
+ export declare function normalizePaths(paths: string[]): string[];
2
10
  /**
3
11
  * 验证文件路径
4
12
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validation/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAe,SAAS,EAAE,MAAM,UAAU,CAAC;AAIvF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,gBAAgB,CA6CpE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,gBAAgB,CAgChE;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,SAAS,GAAG,MAAM,EAC9B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,YAAiB,GACzB,MAAM,CAgBR"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validation/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAe,SAAS,EAAE,MAAM,UAAU,CAAC;AAIvF;;GAEG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAExD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,gBAAgB,CA6CpE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,gBAAgB,CAgChE;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,SAAS,GAAG,MAAM,EAC9B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,YAAiB,GACzB,MAAM,CAgBR"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@didnhdj/fnmap",
3
- "version": "0.1.14",
3
+ "version": "0.2.0",
4
4
  "description": "AI code indexing tool for analyzing JS/TS code structure and generating structured code maps to help AI understand code quickly",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",