@mycodemap/mycodemap 0.4.1 → 0.5.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/CHANGELOG.md +100 -0
- package/README.md +307 -243
- package/dist/ai/claude.d.ts +38 -0
- package/dist/ai/claude.d.ts.map +1 -0
- package/dist/ai/claude.js +169 -0
- package/dist/ai/claude.js.map +1 -0
- package/dist/ai/codex.d.ts +38 -0
- package/dist/ai/codex.d.ts.map +1 -0
- package/dist/ai/codex.js +169 -0
- package/dist/ai/codex.js.map +1 -0
- package/dist/ai/factory.d.ts +48 -0
- package/dist/ai/factory.d.ts.map +1 -0
- package/dist/ai/factory.js +95 -0
- package/dist/ai/factory.js.map +1 -0
- package/dist/ai/index.d.ts +12 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +29 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/provider.d.ts +70 -0
- package/dist/ai/provider.d.ts.map +1 -0
- package/dist/ai/provider.js +31 -0
- package/dist/ai/provider.js.map +1 -0
- package/dist/ai/subagent-caller.d.ts +90 -0
- package/dist/ai/subagent-caller.d.ts.map +1 -0
- package/dist/ai/subagent-caller.js +280 -0
- package/dist/ai/subagent-caller.js.map +1 -0
- package/dist/ai/types.d.ts +70 -0
- package/dist/ai/types.d.ts.map +1 -0
- package/dist/ai/types.js +5 -0
- package/dist/ai/types.js.map +1 -0
- package/dist/cli/commands/analyze-options.d.ts +36 -0
- package/dist/cli/commands/analyze-options.d.ts.map +1 -0
- package/dist/cli/commands/analyze-options.js +147 -0
- package/dist/cli/commands/analyze-options.js.map +1 -0
- package/dist/cli/commands/analyze.d.ts +93 -4
- package/dist/cli/commands/analyze.d.ts.map +1 -1
- package/dist/cli/commands/analyze.js +592 -176
- package/dist/cli/commands/analyze.js.map +1 -1
- package/dist/cli/commands/ci.d.ts +47 -1
- package/dist/cli/commands/ci.d.ts.map +1 -1
- package/dist/cli/commands/ci.js +208 -1
- package/dist/cli/commands/ci.js.map +1 -1
- package/dist/cli/commands/design.d.ts +47 -0
- package/dist/cli/commands/design.d.ts.map +1 -0
- package/dist/cli/commands/design.js +268 -0
- package/dist/cli/commands/design.js.map +1 -0
- package/dist/cli/commands/export.d.ts.map +1 -1
- package/dist/cli/commands/export.js +2 -2
- package/dist/cli/commands/export.js.map +1 -1
- package/dist/cli/commands/generate.d.ts +8 -2
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +151 -22
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +2 -13
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/server.d.ts.map +1 -1
- package/dist/cli/commands/server.js +2 -5
- package/dist/cli/commands/server.js.map +1 -1
- package/dist/cli/commands/ship/checker.d.ts.map +1 -1
- package/dist/cli/commands/ship/checker.js +0 -3
- package/dist/cli/commands/ship/checker.js.map +1 -1
- package/dist/cli/commands/ship/pipeline.d.ts.map +1 -1
- package/dist/cli/commands/ship/pipeline.js +8 -1
- package/dist/cli/commands/ship/pipeline.js.map +1 -1
- package/dist/cli/commands/ship/publisher.d.ts +9 -1
- package/dist/cli/commands/ship/publisher.d.ts.map +1 -1
- package/dist/cli/commands/ship/publisher.js +149 -6
- package/dist/cli/commands/ship/publisher.js.map +1 -1
- package/dist/cli/commands/ship/rules/quality-rules.d.ts +0 -1
- package/dist/cli/commands/ship/rules/quality-rules.d.ts.map +1 -1
- package/dist/cli/commands/ship/rules/quality-rules.js +4 -76
- package/dist/cli/commands/ship/rules/quality-rules.js.map +1 -1
- package/dist/cli/commands/workflow.js +4 -4
- package/dist/cli/commands/workflow.js.map +1 -1
- package/dist/cli/config-loader.d.ts +31 -0
- package/dist/cli/config-loader.d.ts.map +1 -0
- package/dist/cli/config-loader.js +235 -0
- package/dist/cli/config-loader.js.map +1 -0
- package/dist/cli/design-contract-loader.d.ts +15 -0
- package/dist/cli/design-contract-loader.d.ts.map +1 -0
- package/dist/cli/design-contract-loader.js +175 -0
- package/dist/cli/design-contract-loader.js.map +1 -0
- package/dist/cli/design-contract-schema.d.ts +11 -0
- package/dist/cli/design-contract-schema.d.ts.map +1 -0
- package/dist/cli/design-contract-schema.js +75 -0
- package/dist/cli/design-contract-schema.js.map +1 -0
- package/dist/cli/design-handoff-builder.d.ts +15 -0
- package/dist/cli/design-handoff-builder.d.ts.map +1 -0
- package/dist/cli/design-handoff-builder.js +345 -0
- package/dist/cli/design-handoff-builder.js.map +1 -0
- package/dist/cli/design-scope-resolver.d.ts +8 -0
- package/dist/cli/design-scope-resolver.d.ts.map +1 -0
- package/dist/cli/design-scope-resolver.js +712 -0
- package/dist/cli/design-scope-resolver.js.map +1 -0
- package/dist/cli/design-verification-builder.d.ts +8 -0
- package/dist/cli/design-verification-builder.d.ts.map +1 -0
- package/dist/cli/design-verification-builder.js +369 -0
- package/dist/cli/design-verification-builder.js.map +1 -0
- package/dist/cli/index.js +20 -63
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/removed-commands.d.ts +9 -0
- package/dist/cli/removed-commands.d.ts.map +1 -0
- package/dist/cli/removed-commands.js +48 -0
- package/dist/cli/removed-commands.js.map +1 -0
- package/dist/cli/storage-runtime.d.ts +8 -0
- package/dist/cli/storage-runtime.d.ts.map +1 -0
- package/dist/cli/storage-runtime.js +14 -0
- package/dist/cli/storage-runtime.js.map +1 -0
- package/dist/cli/tree-sitter-check.d.ts.map +1 -1
- package/dist/cli/tree-sitter-check.js +0 -1
- package/dist/cli/tree-sitter-check.js.map +1 -1
- package/dist/cli-new/commands/export.d.ts.map +1 -1
- package/dist/cli-new/commands/export.js +2 -2
- package/dist/cli-new/commands/export.js.map +1 -1
- package/dist/cli-new/commands/query.d.ts.map +1 -1
- package/dist/cli-new/commands/query.js +5 -4
- package/dist/cli-new/commands/query.js.map +1 -1
- package/dist/cli-new/commands/server.d.ts.map +1 -1
- package/dist/cli-new/commands/server.js +2 -6
- package/dist/cli-new/commands/server.js.map +1 -1
- package/dist/cli-new/index.d.ts.map +1 -1
- package/dist/cli-new/index.js +0 -2
- package/dist/cli-new/index.js.map +1 -1
- package/dist/core/analyzer.d.ts.map +1 -1
- package/dist/core/analyzer.js +7 -39
- package/dist/core/analyzer.js.map +1 -1
- package/dist/core/file-discovery.d.ts +17 -0
- package/dist/core/file-discovery.d.ts.map +1 -0
- package/dist/core/file-discovery.js +75 -0
- package/dist/core/file-discovery.js.map +1 -0
- package/dist/core/global-index.d.ts +5 -0
- package/dist/core/global-index.d.ts.map +1 -1
- package/dist/core/global-index.js +71 -21
- package/dist/core/global-index.js.map +1 -1
- package/dist/generator/ai-overview.d.ts +51 -0
- package/dist/generator/ai-overview.d.ts.map +1 -0
- package/dist/generator/ai-overview.js +160 -0
- package/dist/generator/ai-overview.js.map +1 -0
- package/dist/generator/index.d.ts.map +1 -1
- package/dist/generator/index.js +8 -0
- package/dist/generator/index.js.map +1 -1
- package/dist/infrastructure/parser/implementations/GoParser.d.ts +2 -5
- package/dist/infrastructure/parser/implementations/GoParser.d.ts.map +1 -1
- package/dist/infrastructure/parser/implementations/GoParser.js +2 -5
- package/dist/infrastructure/parser/implementations/GoParser.js.map +1 -1
- package/dist/infrastructure/parser/implementations/PythonParser.d.ts +1 -5
- package/dist/infrastructure/parser/implementations/PythonParser.d.ts.map +1 -1
- package/dist/infrastructure/parser/implementations/PythonParser.js +1 -5
- package/dist/infrastructure/parser/implementations/PythonParser.js.map +1 -1
- package/dist/infrastructure/parser/implementations/TypeScriptParser.d.ts +1 -5
- package/dist/infrastructure/parser/implementations/TypeScriptParser.d.ts.map +1 -1
- package/dist/infrastructure/parser/implementations/TypeScriptParser.js +1 -5
- package/dist/infrastructure/parser/implementations/TypeScriptParser.js.map +1 -1
- package/dist/infrastructure/storage/StorageFactory.d.ts +12 -6
- package/dist/infrastructure/storage/StorageFactory.d.ts.map +1 -1
- package/dist/infrastructure/storage/StorageFactory.js +59 -43
- package/dist/infrastructure/storage/StorageFactory.js.map +1 -1
- package/dist/infrastructure/storage/adapters/FileSystemStorage.d.ts.map +1 -1
- package/dist/infrastructure/storage/adapters/FileSystemStorage.js +24 -137
- package/dist/infrastructure/storage/adapters/FileSystemStorage.js.map +1 -1
- package/dist/infrastructure/storage/adapters/KuzuDBStorage.d.ts +10 -18
- package/dist/infrastructure/storage/adapters/KuzuDBStorage.d.ts.map +1 -1
- package/dist/infrastructure/storage/adapters/KuzuDBStorage.js +103 -146
- package/dist/infrastructure/storage/adapters/KuzuDBStorage.js.map +1 -1
- package/dist/infrastructure/storage/adapters/MemoryStorage.d.ts +0 -1
- package/dist/infrastructure/storage/adapters/MemoryStorage.d.ts.map +1 -1
- package/dist/infrastructure/storage/adapters/MemoryStorage.js +16 -136
- package/dist/infrastructure/storage/adapters/MemoryStorage.js.map +1 -1
- package/dist/infrastructure/storage/adapters/Neo4jStorage.d.ts +9 -17
- package/dist/infrastructure/storage/adapters/Neo4jStorage.d.ts.map +1 -1
- package/dist/infrastructure/storage/adapters/Neo4jStorage.js +78 -138
- package/dist/infrastructure/storage/adapters/Neo4jStorage.js.map +1 -1
- package/dist/infrastructure/storage/graph-helpers.d.ts +16 -0
- package/dist/infrastructure/storage/graph-helpers.d.ts.map +1 -0
- package/dist/infrastructure/storage/graph-helpers.js +161 -0
- package/dist/infrastructure/storage/graph-helpers.js.map +1 -0
- package/dist/infrastructure/storage/index.d.ts.map +1 -1
- package/dist/interface/config/index.d.ts +10 -1
- package/dist/interface/config/index.d.ts.map +1 -1
- package/dist/interface/types/design-contract.d.ts +68 -0
- package/dist/interface/types/design-contract.d.ts.map +1 -0
- package/dist/interface/types/design-contract.js +7 -0
- package/dist/interface/types/design-contract.js.map +1 -0
- package/dist/interface/types/design-handoff.d.ts +68 -0
- package/dist/interface/types/design-handoff.d.ts.map +1 -0
- package/dist/interface/types/design-handoff.js +4 -0
- package/dist/interface/types/design-handoff.js.map +1 -0
- package/dist/interface/types/design-mapping.d.ts +51 -0
- package/dist/interface/types/design-mapping.d.ts.map +1 -0
- package/dist/interface/types/design-mapping.js +4 -0
- package/dist/interface/types/design-mapping.js.map +1 -0
- package/dist/interface/types/design-verification.d.ts +49 -0
- package/dist/interface/types/design-verification.d.ts.map +1 -0
- package/dist/interface/types/design-verification.js +4 -0
- package/dist/interface/types/design-verification.js.map +1 -0
- package/dist/interface/types/index.d.ts +17 -0
- package/dist/interface/types/index.d.ts.map +1 -1
- package/dist/interface/types/storage.d.ts +1 -4
- package/dist/interface/types/storage.d.ts.map +1 -1
- package/dist/orchestrator/ai-feed-generator.d.ts +210 -0
- package/dist/orchestrator/ai-feed-generator.d.ts.map +1 -0
- package/dist/orchestrator/ai-feed-generator.js +377 -0
- package/dist/orchestrator/ai-feed-generator.js.map +1 -0
- package/dist/orchestrator/confidence.d.ts +9 -9
- package/dist/orchestrator/confidence.d.ts.map +1 -1
- package/dist/orchestrator/confidence.js +44 -67
- package/dist/orchestrator/confidence.js.map +1 -1
- package/dist/orchestrator/file-header-scanner.d.ts.map +1 -1
- package/dist/orchestrator/file-header-scanner.js +22 -31
- package/dist/orchestrator/file-header-scanner.js.map +1 -1
- package/dist/orchestrator/intent-router.d.ts +2 -11
- package/dist/orchestrator/intent-router.d.ts.map +1 -1
- package/dist/orchestrator/intent-router.js +58 -49
- package/dist/orchestrator/intent-router.js.map +1 -1
- package/dist/orchestrator/tool-orchestrator.d.ts.map +1 -1
- package/dist/orchestrator/tool-orchestrator.js +6 -4
- package/dist/orchestrator/tool-orchestrator.js.map +1 -1
- package/dist/orchestrator/types.d.ts +113 -2
- package/dist/orchestrator/types.d.ts.map +1 -1
- package/dist/orchestrator/types.js +29 -0
- package/dist/orchestrator/types.js.map +1 -1
- package/dist/orchestrator/workflow/config.d.ts +4 -12
- package/dist/orchestrator/workflow/config.d.ts.map +1 -1
- package/dist/orchestrator/workflow/config.js +4 -6
- package/dist/orchestrator/workflow/config.js.map +1 -1
- package/dist/orchestrator/workflow/git-analyzer.d.ts.map +1 -1
- package/dist/orchestrator/workflow/git-analyzer.js +9 -19
- package/dist/orchestrator/workflow/git-analyzer.js.map +1 -1
- package/dist/orchestrator/workflow/phase-inheritance.d.ts.map +1 -1
- package/dist/orchestrator/workflow/phase-inheritance.js +14 -23
- package/dist/orchestrator/workflow/phase-inheritance.js.map +1 -1
- package/dist/orchestrator/workflow/result-fusion.d.ts.map +1 -1
- package/dist/orchestrator/workflow/result-fusion.js +9 -11
- package/dist/orchestrator/workflow/result-fusion.js.map +1 -1
- package/dist/orchestrator/workflow/templates.d.ts +4 -1
- package/dist/orchestrator/workflow/templates.d.ts.map +1 -1
- package/dist/orchestrator/workflow/templates.js +49 -207
- package/dist/orchestrator/workflow/templates.js.map +1 -1
- package/dist/orchestrator/workflow/test-linker.d.ts.map +1 -1
- package/dist/orchestrator/workflow/test-linker.js +12 -24
- package/dist/orchestrator/workflow/test-linker.js.map +1 -1
- package/dist/orchestrator/workflow/types.d.ts +11 -8
- package/dist/orchestrator/workflow/types.d.ts.map +1 -1
- package/dist/orchestrator/workflow/types.js +8 -1
- package/dist/orchestrator/workflow/types.js.map +1 -1
- package/dist/orchestrator/workflow/visualizer.d.ts.map +1 -1
- package/dist/orchestrator/workflow/visualizer.js +7 -9
- package/dist/orchestrator/workflow/visualizer.js.map +1 -1
- package/dist/orchestrator/workflow/workflow-context.d.ts.map +1 -1
- package/dist/orchestrator/workflow/workflow-context.js +3 -5
- package/dist/orchestrator/workflow/workflow-context.js.map +1 -1
- package/dist/orchestrator/workflow/workflow-orchestrator.d.ts +0 -4
- package/dist/orchestrator/workflow/workflow-orchestrator.d.ts.map +1 -1
- package/dist/orchestrator/workflow/workflow-orchestrator.js +7 -99
- package/dist/orchestrator/workflow/workflow-orchestrator.js.map +1 -1
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/parser/index.js +2 -2
- package/dist/parser/index.js.map +1 -1
- package/dist/plugins/index.d.ts +5 -3
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +19 -8
- package/dist/plugins/index.js.map +1 -1
- package/dist/plugins/plugin-loader.d.ts +21 -6
- package/dist/plugins/plugin-loader.d.ts.map +1 -1
- package/dist/plugins/plugin-loader.js +170 -54
- package/dist/plugins/plugin-loader.js.map +1 -1
- package/dist/plugins/plugin-registry.d.ts +7 -4
- package/dist/plugins/plugin-registry.d.ts.map +1 -1
- package/dist/plugins/plugin-registry.js +62 -14
- package/dist/plugins/plugin-registry.js.map +1 -1
- package/dist/plugins/types.d.ts +16 -6
- package/dist/plugins/types.d.ts.map +1 -1
- package/dist/plugins/types.js +2 -0
- package/dist/plugins/types.js.map +1 -1
- package/dist/server/handlers/AnalysisHandler.d.ts +16 -2
- package/dist/server/handlers/AnalysisHandler.d.ts.map +1 -1
- package/dist/server/handlers/AnalysisHandler.js +31 -47
- package/dist/server/handlers/AnalysisHandler.js.map +1 -1
- package/dist/server/routes/api.d.ts.map +1 -1
- package/dist/server/routes/api.js +31 -12
- package/dist/server/routes/api.js.map +1 -1
- package/docs/AI_ASSISTANT_SETUP.md +3 -1
- package/docs/SETUP_GUIDE.md +41 -17
- package/docs/ai-guide/COMMANDS.md +179 -102
- package/docs/ai-guide/INTEGRATION.md +23 -21
- package/docs/ai-guide/OUTPUT.md +621 -10
- package/docs/ai-guide/PATTERNS.md +77 -18
- package/docs/ai-guide/PROMPTS.md +24 -18
- package/docs/ai-guide/QUICKSTART.md +35 -19
- package/docs/ai-guide/README.md +22 -4
- package/docs/archive/test-report-symbol-search.md +384 -0
- package/docs/archive/test-scenario-4-complexity-analysis.md +460 -0
- package/docs/archive/test_report_scenario5.md +615 -0
- package/docs/archive/test_scenario_3_impact_analysis_report.md +520 -0
- package/docs/product-specs/DESIGN_CONTRACT_TEMPLATE.md +79 -0
- package/docs/product-specs/MVP3-ARCHITECTURE-COMPARISON.md +159 -434
- package/docs/product-specs/MVP3-ARCHITECTURE-REDESIGN-PRD.md +169 -261
- package/docs/product-specs/MVP3-ARCHITECTURE-REDESIGN-TECH-PRD.md +201 -1259
- package/docs/product-specs/README.md +9 -1
- package/docs/rules/architecture-guardrails.md +1 -2
- package/docs/rules/engineering-with-codex-openai.md +20 -10
- package/docs/rules/validation.md +29 -4
- package/mycodemap.config.schema.json +76 -5
- package/package.json +1 -1
- package/scripts/experiments/arcadedb-http-smoke.mjs +90 -0
- package/scripts/sync-analyze-docs.js +500 -0
- package/scripts/validate-ai-docs.js +54 -1
- package/scripts/validate-docs.js +992 -25
|
@@ -1,1374 +1,316 @@
|
|
|
1
|
-
# CodeMap MVP3
|
|
1
|
+
# CodeMap MVP3 架构重构技术需求文档(Tech-PRD,v1.3 同步版)
|
|
2
2
|
|
|
3
|
-
> **版本**: v1.
|
|
4
|
-
> **状态**:
|
|
5
|
-
> **日期**: 2026-03-
|
|
3
|
+
> **版本**: v1.3-sync
|
|
4
|
+
> **状态**: Shipped baseline / technical sync
|
|
5
|
+
> **日期**: 2026-03-25
|
|
6
6
|
> **负责人**: Architecture Team
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
## 1.
|
|
10
|
+
## 1. 文档作用
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
本文档描述当前仓库在 `v1.3` 收口后的**技术基线**,而不是继续把早期草案中的未交付方案写成当前现实。
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
16
|
-
│ 架构设计原则 │
|
|
17
|
-
├─────────────────────────────────────────────────────────────────┤
|
|
18
|
-
│ │
|
|
19
|
-
│ 1. 依赖方向: Interface → Infrastructure → Domain → Server → CLI│
|
|
20
|
-
│ (外层依赖内层,内层不依赖外层) │
|
|
21
|
-
│ │
|
|
22
|
-
│ 2. 接口隔离: 每层通过明确定义的接口与其他层交互 │
|
|
23
|
-
│ │
|
|
24
|
-
│ 3. 依赖注入: 通过构造函数注入依赖,便于测试和替换 │
|
|
25
|
-
│ │
|
|
26
|
-
│ 4. 单一职责: 每个模块只有一个变化理由 │
|
|
27
|
-
│ │
|
|
28
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
29
|
-
```
|
|
14
|
+
---
|
|
30
15
|
|
|
31
|
-
|
|
16
|
+
## 2. 当前目录结构
|
|
32
17
|
|
|
33
|
-
```
|
|
18
|
+
```text
|
|
34
19
|
src/
|
|
35
|
-
├── interface/
|
|
20
|
+
├── interface/
|
|
36
21
|
│ ├── types/
|
|
37
|
-
│ │ ├── index.ts # 核心类型定义
|
|
38
|
-
│ │ ├── storage.ts # 存储接口
|
|
39
|
-
│ │ ├── parser.ts # 解析器接口
|
|
40
|
-
│ │ └── analyzer.ts # 分析器接口
|
|
41
22
|
│ └── config/
|
|
42
|
-
│ └── index.ts # 配置类型
|
|
43
23
|
│
|
|
44
|
-
├── infrastructure/
|
|
45
|
-
│ ├── storage/
|
|
46
|
-
│ │ ├──
|
|
47
|
-
│ │ │ └── IStorage.ts
|
|
48
|
-
│ │ ├── implementations/
|
|
24
|
+
├── infrastructure/
|
|
25
|
+
│ ├── storage/
|
|
26
|
+
│ │ ├── adapters/
|
|
49
27
|
│ │ │ ├── FileSystemStorage.ts
|
|
50
28
|
│ │ │ ├── KuzuDBStorage.ts
|
|
51
|
-
│ │ │ └──
|
|
29
|
+
│ │ │ └── MemoryStorage.ts
|
|
30
|
+
│ │ ├── interfaces/StorageBase.ts
|
|
52
31
|
│ │ ├── StorageFactory.ts
|
|
32
|
+
│ │ ├── graph-helpers.ts
|
|
53
33
|
│ │ └── index.ts
|
|
54
34
|
│ │
|
|
55
|
-
│ ├── parser/
|
|
56
|
-
│ │ ├── interfaces/
|
|
57
|
-
│ │ │ └── ILanguageParser.ts
|
|
35
|
+
│ ├── parser/
|
|
58
36
|
│ │ ├── implementations/
|
|
59
|
-
│ │ │ ├──
|
|
60
|
-
│ │ │ ├──
|
|
61
|
-
│ │ │
|
|
62
|
-
│ │
|
|
63
|
-
│ │
|
|
64
|
-
│ │ │ └── ... (其他语言)
|
|
65
|
-
│ │ ├── ParserRegistry.ts
|
|
37
|
+
│ │ │ ├── TypeScriptParser.ts
|
|
38
|
+
│ │ │ ├── GoParser.ts
|
|
39
|
+
│ │ │ └── PythonParser.ts
|
|
40
|
+
│ │ ├── interfaces/ParserBase.ts
|
|
41
|
+
│ │ ├── registry/ParserRegistry.ts
|
|
66
42
|
│ │ └── index.ts
|
|
67
43
|
│ │
|
|
68
|
-
│
|
|
69
|
-
│ ├── file-system/ # 文件系统抽象
|
|
70
|
-
│ └── logger/ # 日志系统
|
|
44
|
+
│ └── repositories/
|
|
71
45
|
│
|
|
72
|
-
├── domain/
|
|
73
|
-
│ ├── entities/
|
|
74
|
-
│
|
|
75
|
-
│
|
|
76
|
-
│ │ ├── Symbol.ts
|
|
77
|
-
│ │ ├── Dependency.ts
|
|
78
|
-
│ │ └── CodeGraph.ts
|
|
79
|
-
│ │
|
|
80
|
-
│ ├── services/ # 领域服务
|
|
81
|
-
│ │ ├── AnalysisService.ts
|
|
82
|
-
│ │ ├── DependencyService.ts
|
|
83
|
-
│ │ ├── SymbolIndexService.ts
|
|
84
|
-
│ │ └── ComplexityService.ts
|
|
85
|
-
│ │
|
|
86
|
-
│ ├── value-objects/ # 值对象
|
|
87
|
-
│ │ ├── FilePath.ts
|
|
88
|
-
│ │ ├── Position.ts
|
|
89
|
-
│ │ └── Range.ts
|
|
90
|
-
│ │
|
|
91
|
-
│ └── repositories/ # 仓储接口
|
|
92
|
-
│ └── ICodeGraphRepository.ts
|
|
46
|
+
├── domain/
|
|
47
|
+
│ ├── entities/
|
|
48
|
+
│ ├── services/
|
|
49
|
+
│ └── repositories/
|
|
93
50
|
│
|
|
94
|
-
├── server/
|
|
95
|
-
│ ├──
|
|
96
|
-
│
|
|
97
|
-
│
|
|
98
|
-
│
|
|
99
|
-
│
|
|
100
|
-
│ │ ├── StartWorkflow.ts
|
|
101
|
-
│ │ └── ...
|
|
102
|
-
│ │
|
|
103
|
-
│ ├── dto/ # 数据传输对象
|
|
104
|
-
│ │ ├── GenerateRequest.ts
|
|
105
|
-
│ │ ├── GenerateResponse.ts
|
|
106
|
-
│ │ └── QueryRequest.ts
|
|
107
|
-
│ │
|
|
108
|
-
│ ├── mappers/ # 对象映射
|
|
109
|
-
│ │ ├── ModuleMapper.ts
|
|
110
|
-
│ │ └── SymbolMapper.ts
|
|
111
|
-
│ │
|
|
112
|
-
│ └── services/ # 应用服务
|
|
113
|
-
│ ├── CodeMapService.ts
|
|
114
|
-
│ ├── QueryService.ts
|
|
115
|
-
│ └── WorkflowService.ts
|
|
51
|
+
├── server/
|
|
52
|
+
│ ├── CodeMapServer.ts
|
|
53
|
+
│ ├── handlers/
|
|
54
|
+
│ ├── routes/
|
|
55
|
+
│ ├── types/
|
|
56
|
+
│ └── index.ts
|
|
116
57
|
│
|
|
117
|
-
└── cli/
|
|
118
|
-
├── commands/
|
|
119
|
-
├──
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
│ └── HeatmapVisualizer.ts
|
|
123
|
-
├── formatters/ # 输出格式化
|
|
124
|
-
└── index.ts # 入口
|
|
58
|
+
└── cli/
|
|
59
|
+
├── commands/
|
|
60
|
+
├── utils/
|
|
61
|
+
├── runtime-logger.ts
|
|
62
|
+
└── index.ts
|
|
125
63
|
```
|
|
126
64
|
|
|
65
|
+
### 2.1 关键说明
|
|
66
|
+
|
|
67
|
+
- `server/` 当前不是 `usecases/` + `dto/` 的独立应用层树,而是内部 transport / handler 组织
|
|
68
|
+
- `cli/` 当前没有公开 `viz` / `tui` 子系统
|
|
69
|
+
- `infrastructure/parser/` 当前只有 3 个 shipped parser 实现
|
|
70
|
+
|
|
127
71
|
---
|
|
128
72
|
|
|
129
|
-
##
|
|
73
|
+
## 3. 分层职责
|
|
130
74
|
|
|
131
|
-
|
|
75
|
+
| 层级 | 主要职责 | 当前约束 |
|
|
76
|
+
|------|----------|----------|
|
|
77
|
+
| CLI | 公共命令面、参数解析、输出编排 | 不重新公开 `server` / `watch` / `report` / `logs` |
|
|
78
|
+
| Server | 内部 HTTP transport / handler / route | internal-only,不等于公共产品面 |
|
|
79
|
+
| Domain | 业务实体、领域服务、仓储接口 | 不依赖 CLI |
|
|
80
|
+
| Infrastructure | storage、parser、repository 等技术实现 | 通过 interface/types 契约对齐 |
|
|
81
|
+
| Interface | 类型定义与配置契约 | 不承载运行时副作用 |
|
|
132
82
|
|
|
133
|
-
|
|
134
|
-
// src/infrastructure/storage/interfaces/IStorage.ts
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* 存储抽象接口
|
|
138
|
-
* 定义所有存储后端必须实现的能力
|
|
139
|
-
*/
|
|
140
|
-
export interface IStorage {
|
|
141
|
-
/** 存储类型标识 */
|
|
142
|
-
readonly type: StorageType;
|
|
143
|
-
|
|
144
|
-
/** 初始化存储 */
|
|
145
|
-
initialize(projectPath: string): Promise<void>;
|
|
146
|
-
|
|
147
|
-
/** 关闭存储连接 */
|
|
148
|
-
close(): Promise<void>;
|
|
149
|
-
|
|
150
|
-
// ========== 项目级别操作 ==========
|
|
151
|
-
|
|
152
|
-
/** 保存完整代码图 */
|
|
153
|
-
saveCodeGraph(graph: CodeGraph): Promise<void>;
|
|
154
|
-
|
|
155
|
-
/** 加载完整代码图 */
|
|
156
|
-
loadCodeGraph(): Promise<CodeGraph>;
|
|
157
|
-
|
|
158
|
-
/** 删除项目数据 */
|
|
159
|
-
deleteProject(): Promise<void>;
|
|
160
|
-
|
|
161
|
-
// ========== 增量更新 ==========
|
|
162
|
-
|
|
163
|
-
/** 更新单个模块 */
|
|
164
|
-
updateModule(module: Module): Promise<void>;
|
|
165
|
-
|
|
166
|
-
/** 删除模块 */
|
|
167
|
-
deleteModule(moduleId: string): Promise<void>;
|
|
168
|
-
|
|
169
|
-
// ========== 查询操作 ==========
|
|
170
|
-
|
|
171
|
-
/** 查询模块 */
|
|
172
|
-
findModuleById(id: string): Promise<Module | null>;
|
|
173
|
-
findModulesByPath(path: string): Promise<Module[]>;
|
|
174
|
-
|
|
175
|
-
/** 查询符号 */
|
|
176
|
-
findSymbolByName(name: string): Promise<Symbol[]>;
|
|
177
|
-
findSymbolById(id: string): Promise<Symbol | null>;
|
|
178
|
-
|
|
179
|
-
/** 查询依赖 */
|
|
180
|
-
findDependencies(moduleId: string): Promise<Dependency[]>;
|
|
181
|
-
findDependents(moduleId: string): Promise<Dependency[]>;
|
|
182
|
-
|
|
183
|
-
/** 查询调用关系 */
|
|
184
|
-
findCallers(functionId: string): Promise<Symbol[]>;
|
|
185
|
-
findCallees(functionId: string): Promise<Symbol[]>;
|
|
186
|
-
|
|
187
|
-
/** 模糊搜索 */
|
|
188
|
-
search(query: string, options: SearchOptions): Promise<SearchResult[]>;
|
|
189
|
-
|
|
190
|
-
// ========== 分析操作 ==========
|
|
191
|
-
|
|
192
|
-
/** 检测循环依赖 */
|
|
193
|
-
detectCycles(): Promise<Cycle[]>;
|
|
194
|
-
|
|
195
|
-
/** 计算影响范围 */
|
|
196
|
-
calculateImpact(moduleId: string, depth: number): Promise<ImpactResult>;
|
|
197
|
-
|
|
198
|
-
/** 获取项目统计 */
|
|
199
|
-
getStatistics(): Promise<ProjectStatistics>;
|
|
200
|
-
}
|
|
83
|
+
---
|
|
201
84
|
|
|
202
|
-
|
|
203
|
-
export type StorageType = 'filesystem' | 'kuzudb' | 'neo4j' | 'memory';
|
|
85
|
+
## 4. 存储契约与当前实现
|
|
204
86
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
limit?: number;
|
|
210
|
-
offset?: number;
|
|
211
|
-
}
|
|
87
|
+
### 4.1 当前类型契约
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
export type StorageType = 'filesystem' | 'kuzudb' | 'memory';
|
|
212
91
|
|
|
213
|
-
/** 存储配置 */
|
|
214
92
|
export interface StorageConfig {
|
|
215
93
|
type: StorageType | 'auto';
|
|
216
|
-
|
|
217
|
-
// FileSystem 配置
|
|
218
94
|
outputPath?: string;
|
|
219
|
-
|
|
220
|
-
// KùzuDB 配置
|
|
221
95
|
databasePath?: string;
|
|
222
|
-
|
|
223
|
-
// Neo4j 配置
|
|
224
|
-
uri?: string;
|
|
225
|
-
username?: string;
|
|
226
|
-
password?: string;
|
|
227
|
-
|
|
228
|
-
// 自动选择配置
|
|
229
96
|
autoThresholds?: {
|
|
230
97
|
useGraphDBWhenFileCount: number;
|
|
231
98
|
useGraphDBWhenNodeCount: number;
|
|
232
99
|
};
|
|
233
100
|
}
|
|
234
|
-
|
|
235
|
-
/** 存储工厂 */
|
|
236
|
-
export interface IStorageFactory {
|
|
237
|
-
create(config: StorageConfig): Promise<IStorage>;
|
|
238
|
-
createForProject(projectPath: string, config: StorageConfig): Promise<IStorage>;
|
|
239
|
-
}
|
|
240
101
|
```
|
|
241
102
|
|
|
242
|
-
###
|
|
103
|
+
### 4.2 当前实现矩阵
|
|
243
104
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
* 语言解析器接口
|
|
251
|
-
* 所有语言解析器必须实现此接口
|
|
252
|
-
*/
|
|
253
|
-
export interface ILanguageParser {
|
|
254
|
-
/** 支持的语言标识 */
|
|
255
|
-
readonly languageId: LanguageId;
|
|
256
|
-
|
|
257
|
-
/** 支持的文件扩展名 */
|
|
258
|
-
readonly fileExtensions: string[];
|
|
259
|
-
|
|
260
|
-
/** 解析器名称 */
|
|
261
|
-
readonly name: string;
|
|
262
|
-
|
|
263
|
-
/** 初始化解析器 */
|
|
264
|
-
initialize(): Promise<void>;
|
|
265
|
-
|
|
266
|
-
/** 释放解析器资源 */
|
|
267
|
-
dispose(): Promise<void>;
|
|
268
|
-
|
|
269
|
-
/** 解析单个文件 */
|
|
270
|
-
parseFile(filePath: string, content: string, options?: ParseOptions): Promise<ParseResult>;
|
|
271
|
-
|
|
272
|
-
/** 批量解析文件 */
|
|
273
|
-
parseFiles(files: Array<{ path: string; content: string }>, options?: ParseOptions): Promise<ParseResult[]>;
|
|
274
|
-
|
|
275
|
-
/** 提取导入信息 */
|
|
276
|
-
extractImports(content: string): Promise<ImportInfo[]>;
|
|
277
|
-
|
|
278
|
-
/** 提取导出信息 */
|
|
279
|
-
extractExports(content: string): Promise<ExportInfo[]>;
|
|
280
|
-
|
|
281
|
-
/** 提取符号信息 */
|
|
282
|
-
extractSymbols(content: string): Promise<SymbolInfo[]>;
|
|
283
|
-
|
|
284
|
-
/** 构建调用图 */
|
|
285
|
-
buildCallGraph(content: string): Promise<CallGraphInfo>;
|
|
286
|
-
|
|
287
|
-
/** 计算复杂度 */
|
|
288
|
-
calculateComplexity(content: string): Promise<ComplexityMetrics>;
|
|
289
|
-
|
|
290
|
-
/** 检测语言特性支持 */
|
|
291
|
-
supportsFeature(feature: LanguageFeature): boolean;
|
|
292
|
-
}
|
|
105
|
+
| 类型 | 实现 | 当前状态 |
|
|
106
|
+
|------|------|----------|
|
|
107
|
+
| `filesystem` | `FileSystemStorage` | shipped |
|
|
108
|
+
| `memory` | `MemoryStorage` | shipped |
|
|
109
|
+
| `kuzudb` | `KuzuDBStorage` | shipped |
|
|
110
|
+
| `auto` | `StorageFactory.determineStorageType()` | shipped surface,但当前保守返回 `filesystem` |
|
|
293
111
|
|
|
294
|
-
|
|
295
|
-
export type LanguageId =
|
|
296
|
-
| 'typescript' | 'javascript' | 'go' // Phase 1 (已支持)
|
|
297
|
-
| 'python' | 'java' | 'rust' | 'cpp' // Phase 2 (MVP3)
|
|
298
|
-
| 'csharp' | 'ruby' | 'php' // Phase 3
|
|
299
|
-
| 'swift' | 'kotlin' | 'dart' | 'perl'; // Phase 3
|
|
300
|
-
|
|
301
|
-
/** 解析结果 */
|
|
302
|
-
export interface ParseResult {
|
|
303
|
-
/** 文件路径 */
|
|
304
|
-
filePath: string;
|
|
305
|
-
|
|
306
|
-
/** 语言 */
|
|
307
|
-
language: LanguageId;
|
|
308
|
-
|
|
309
|
-
/** 模块信息 */
|
|
310
|
-
module: Module;
|
|
311
|
-
|
|
312
|
-
/** 符号列表 */
|
|
313
|
-
symbols: Symbol[];
|
|
314
|
-
|
|
315
|
-
/** 导入列表 */
|
|
316
|
-
imports: Import[];
|
|
317
|
-
|
|
318
|
-
/** 导出列表 */
|
|
319
|
-
exports: Export[];
|
|
320
|
-
|
|
321
|
-
/** 依赖列表 */
|
|
322
|
-
dependencies: Dependency[];
|
|
323
|
-
|
|
324
|
-
/** 调用图 */
|
|
325
|
-
callGraph?: CallGraph;
|
|
326
|
-
|
|
327
|
-
/** 复杂度指标 */
|
|
328
|
-
complexity?: ComplexityMetrics;
|
|
329
|
-
|
|
330
|
-
/** 解析耗时 (ms) */
|
|
331
|
-
parseTime: number;
|
|
332
|
-
|
|
333
|
-
/** 错误信息 */
|
|
334
|
-
errors?: ParseError[];
|
|
335
|
-
}
|
|
112
|
+
### 4.3 已移除的正式产品面
|
|
336
113
|
|
|
337
|
-
|
|
338
|
-
export type LanguageFeature =
|
|
339
|
-
| 'type-inference' // 类型推导
|
|
340
|
-
| 'generic-types' // 泛型
|
|
341
|
-
| 'decorators' // 装饰器
|
|
342
|
-
| 'call-graph' // 调用图
|
|
343
|
-
| 'cross-file-analysis' // 跨文件分析
|
|
344
|
-
| 'complexity-metrics'; // 复杂度指标
|
|
345
|
-
|
|
346
|
-
/** 解析器注册表 */
|
|
347
|
-
export interface IParserRegistry {
|
|
348
|
-
/** 注册解析器 */
|
|
349
|
-
register(parser: ILanguageParser): void;
|
|
350
|
-
|
|
351
|
-
/** 获取解析器 */
|
|
352
|
-
getParser(language: LanguageId): ILanguageParser | undefined;
|
|
353
|
-
getParserByFile(filePath: string): ILanguageParser | undefined;
|
|
354
|
-
|
|
355
|
-
/** 获取所有支持的扩展名 */
|
|
356
|
-
getSupportedExtensions(): string[];
|
|
357
|
-
|
|
358
|
-
/** 获取所有支持的语言 */
|
|
359
|
-
getSupportedLanguages(): LanguageId[];
|
|
360
|
-
}
|
|
361
|
-
```
|
|
114
|
+
`neo4j` 已不再是正式支持 backend。
|
|
362
115
|
|
|
363
|
-
|
|
116
|
+
当前技术语义:
|
|
364
117
|
|
|
365
|
-
|
|
366
|
-
|
|
118
|
+
- 旧配置若出现 `neo4j`,`StorageFactory` 会抛出 `UNSUPPORTED_STORAGE_TYPE`
|
|
119
|
+
- 文档和实现都不再承诺 Neo4j runtime surface
|
|
367
120
|
|
|
368
|
-
|
|
121
|
+
### 4.4 `auto` 的真实状态
|
|
369
122
|
|
|
370
|
-
|
|
371
|
-
* 生成代码图用例
|
|
372
|
-
*/
|
|
373
|
-
export interface IGenerateCodeMapUseCase {
|
|
374
|
-
execute(request: GenerateRequest): Promise<GenerateResponse>;
|
|
375
|
-
}
|
|
123
|
+
`autoThresholds` 仍保留在契约里,但当前 `StorageFactory` 的保守行为是:
|
|
376
124
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
/** 包含模式 */
|
|
383
|
-
include?: string[];
|
|
384
|
-
|
|
385
|
-
/** 排除模式 */
|
|
386
|
-
exclude?: string[];
|
|
387
|
-
|
|
388
|
-
/** 分析模式 */
|
|
389
|
-
mode: 'fast' | 'smart' | 'hybrid';
|
|
390
|
-
|
|
391
|
-
/** 存储配置 */
|
|
392
|
-
storage?: StorageConfig;
|
|
393
|
-
|
|
394
|
-
/** 输出配置 */
|
|
395
|
-
output?: {
|
|
396
|
-
formats: ('aimap' | 'context' | 'json' | 'deps-graph')[];
|
|
397
|
-
directory: string;
|
|
398
|
-
};
|
|
399
|
-
|
|
400
|
-
/** 是否启用进度回调 */
|
|
401
|
-
enableProgress?: boolean;
|
|
402
|
-
|
|
403
|
-
/** 进度回调 */
|
|
404
|
-
onProgress?: (progress: ProgressInfo) => void;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
// src/server/dto/GenerateResponse.ts
|
|
408
|
-
export interface GenerateResponse {
|
|
409
|
-
/** 成功状态 */
|
|
410
|
-
success: boolean;
|
|
411
|
-
|
|
412
|
-
/** 代码图 */
|
|
413
|
-
codeGraph: CodeGraph;
|
|
414
|
-
|
|
415
|
-
/** 生成的文件路径 */
|
|
416
|
-
generatedFiles: string[];
|
|
417
|
-
|
|
418
|
-
/** 统计信息 */
|
|
419
|
-
statistics: {
|
|
420
|
-
totalFiles: number;
|
|
421
|
-
parsedFiles: number;
|
|
422
|
-
failedFiles: number;
|
|
423
|
-
totalSymbols: number;
|
|
424
|
-
totalDependencies: number;
|
|
425
|
-
duration: number;
|
|
426
|
-
};
|
|
427
|
-
|
|
428
|
-
/** 警告信息 */
|
|
429
|
-
warnings?: string[];
|
|
430
|
-
|
|
431
|
-
/** 错误信息 */
|
|
432
|
-
error?: string;
|
|
433
|
-
}
|
|
125
|
+
```typescript
|
|
126
|
+
const thresholds = config.autoThresholds ?? {
|
|
127
|
+
useGraphDBWhenFileCount: 1000,
|
|
128
|
+
useGraphDBWhenNodeCount: 10000,
|
|
129
|
+
};
|
|
434
130
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
execute(request: QuerySymbolRequest): Promise<QuerySymbolResponse>;
|
|
438
|
-
}
|
|
131
|
+
return 'filesystem';
|
|
132
|
+
```
|
|
439
133
|
|
|
440
|
-
|
|
441
|
-
execute(request: AnalyzeImpactRequest): Promise<AnalyzeImpactResponse>;
|
|
442
|
-
}
|
|
134
|
+
因此:
|
|
443
135
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
}
|
|
447
|
-
```
|
|
136
|
+
- `auto` 是稳定配置面
|
|
137
|
+
- 但“按规模自动切到图数据库”的更强启发式仍是未来候选,而不是当前完成能力
|
|
448
138
|
|
|
449
139
|
---
|
|
450
140
|
|
|
451
|
-
##
|
|
141
|
+
## 5. Parser 契约与当前实现
|
|
452
142
|
|
|
453
|
-
###
|
|
143
|
+
### 5.1 接口层现状
|
|
454
144
|
|
|
455
|
-
|
|
456
|
-
// src/infrastructure/storage/implementations/FileSystemStorage.ts
|
|
457
|
-
|
|
458
|
-
export class FileSystemStorage implements IStorage {
|
|
459
|
-
readonly type = 'filesystem';
|
|
460
|
-
private outputPath: string = '';
|
|
461
|
-
private codeGraph: CodeGraph | null = null;
|
|
462
|
-
|
|
463
|
-
async initialize(projectPath: string): Promise<void> {
|
|
464
|
-
this.outputPath = path.join(projectPath, '.mycodemap');
|
|
465
|
-
await fs.mkdir(this.outputPath, { recursive: true });
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
async saveCodeGraph(graph: CodeGraph): Promise<void> {
|
|
469
|
-
// 保存 codemap.json
|
|
470
|
-
const jsonPath = path.join(this.outputPath, 'codemap.json');
|
|
471
|
-
await fs.writeFile(jsonPath, JSON.stringify(graph, null, 2));
|
|
472
|
-
|
|
473
|
-
// 生成 AI_MAP.md
|
|
474
|
-
const aiMap = this.generateAIMap(graph);
|
|
475
|
-
await fs.writeFile(path.join(this.outputPath, 'AI_MAP.md'), aiMap);
|
|
476
|
-
|
|
477
|
-
// 生成 CONTEXT.md
|
|
478
|
-
const context = this.generateContext(graph);
|
|
479
|
-
await fs.writeFile(path.join(this.outputPath, 'CONTEXT.md'), context);
|
|
480
|
-
|
|
481
|
-
this.codeGraph = graph;
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
async loadCodeGraph(): Promise<CodeGraph> {
|
|
485
|
-
if (this.codeGraph) return this.codeGraph;
|
|
486
|
-
|
|
487
|
-
const jsonPath = path.join(this.outputPath, 'codemap.json');
|
|
488
|
-
const content = await fs.readFile(jsonPath, 'utf-8');
|
|
489
|
-
this.codeGraph = JSON.parse(content);
|
|
490
|
-
return this.codeGraph;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
async findSymbolByName(name: string): Promise<Symbol[]> {
|
|
494
|
-
const graph = await this.loadCodeGraph();
|
|
495
|
-
return graph.modules
|
|
496
|
-
.flatMap(m => m.symbols)
|
|
497
|
-
.filter(s => s.name === name);
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
// ... 其他方法实现
|
|
501
|
-
}
|
|
502
|
-
```
|
|
145
|
+
`LanguageId` 联合类型仍保留未来扩展位,但**当前 shipped parser 实现并不等于联合类型的全部成员**。
|
|
503
146
|
|
|
504
|
-
###
|
|
147
|
+
### 5.2 当前默认注册
|
|
505
148
|
|
|
506
149
|
```typescript
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
private dbPath: string = '';
|
|
514
|
-
|
|
515
|
-
async initialize(projectPath: string): Promise<void> {
|
|
516
|
-
this.dbPath = path.join(projectPath, '.mycodemap', 'graph.db');
|
|
517
|
-
await fs.mkdir(path.dirname(this.dbPath), { recursive: true });
|
|
518
|
-
|
|
519
|
-
this.db = new kuzu.Database(this.dbPath);
|
|
520
|
-
this.conn = new kuzu.Connection(this.db);
|
|
521
|
-
|
|
522
|
-
await this.createSchema();
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
private async createSchema(): Promise<void> {
|
|
526
|
-
// 创建节点表
|
|
527
|
-
await this.conn?.query(`
|
|
528
|
-
CREATE NODE TABLE IF NOT EXISTS Module(
|
|
529
|
-
id STRING PRIMARY KEY,
|
|
530
|
-
path STRING,
|
|
531
|
-
language STRING,
|
|
532
|
-
lines INT64
|
|
533
|
-
)
|
|
534
|
-
`);
|
|
535
|
-
|
|
536
|
-
await this.conn?.query(`
|
|
537
|
-
CREATE NODE TABLE IF NOT EXISTS Symbol(
|
|
538
|
-
id STRING PRIMARY KEY,
|
|
539
|
-
name STRING,
|
|
540
|
-
kind STRING,
|
|
541
|
-
moduleId STRING
|
|
542
|
-
)
|
|
543
|
-
`);
|
|
544
|
-
|
|
545
|
-
// 创建关系表
|
|
546
|
-
await this.conn?.query(`
|
|
547
|
-
CREATE REL TABLE IF NOT EXISTS IMPORTS(
|
|
548
|
-
FROM Module TO Module,
|
|
549
|
-
MANY_MANY
|
|
550
|
-
)
|
|
551
|
-
`);
|
|
552
|
-
|
|
553
|
-
await this.conn?.query(`
|
|
554
|
-
CREATE REL TABLE IF NOT EXISTS CALLS(
|
|
555
|
-
FROM Symbol TO Symbol,
|
|
556
|
-
MANY_MANY
|
|
557
|
-
)
|
|
558
|
-
`);
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
async saveCodeGraph(graph: CodeGraph): Promise<void> {
|
|
562
|
-
// 批量导入节点
|
|
563
|
-
const modules = graph.modules.map(m => ({
|
|
564
|
-
id: m.id,
|
|
565
|
-
path: m.path,
|
|
566
|
-
language: m.language,
|
|
567
|
-
lines: m.stats.lines
|
|
568
|
-
}));
|
|
569
|
-
|
|
570
|
-
await this.bulkInsert('Module', modules);
|
|
571
|
-
|
|
572
|
-
// 批量导入关系
|
|
573
|
-
const imports = graph.modules.flatMap(m =>
|
|
574
|
-
m.dependencies.map(dep => ({
|
|
575
|
-
from: m.id,
|
|
576
|
-
to: dep.targetId
|
|
577
|
-
}))
|
|
578
|
-
);
|
|
579
|
-
|
|
580
|
-
await this.bulkInsertRelations('IMPORTS', imports);
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
async findCallers(functionId: string): Promise<Symbol[]> {
|
|
584
|
-
const result = await this.conn?.query(`
|
|
585
|
-
MATCH (caller:Symbol)-[:CALLS]->(callee:Symbol {id: '${functionId}'})
|
|
586
|
-
RETURN caller.id, caller.name, caller.kind
|
|
587
|
-
`);
|
|
588
|
-
|
|
589
|
-
return result ? this.mapToSymbols(result) : [];
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
async calculateImpact(moduleId: string, depth: number): Promise<ImpactResult> {
|
|
593
|
-
const result = await this.conn?.query(`
|
|
594
|
-
MATCH (start:Module {id: '${moduleId}'})-[:IMPORTS*1..${depth}]->(impact:Module)
|
|
595
|
-
RETURN impact.id, impact.path
|
|
596
|
-
`);
|
|
597
|
-
|
|
598
|
-
return {
|
|
599
|
-
rootModule: moduleId,
|
|
600
|
-
affectedModules: result ? this.mapToModules(result) : [],
|
|
601
|
-
depth
|
|
602
|
-
};
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
// ... 其他方法实现
|
|
150
|
+
export function createDefaultParserRegistry(): ParserRegistry {
|
|
151
|
+
const registry = new ParserRegistry();
|
|
152
|
+
registry.register(new TypeScriptParser());
|
|
153
|
+
registry.register(new GoParser());
|
|
154
|
+
registry.register(new PythonParser());
|
|
155
|
+
return registry;
|
|
606
156
|
}
|
|
607
157
|
```
|
|
608
158
|
|
|
609
|
-
###
|
|
159
|
+
### 5.3 当前 shipped parser
|
|
610
160
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
const type = await this.resolveStorageType(config);
|
|
617
|
-
|
|
618
|
-
switch (type) {
|
|
619
|
-
case 'filesystem':
|
|
620
|
-
return new FileSystemStorage();
|
|
621
|
-
case 'kuzudb':
|
|
622
|
-
return new KuzuDBStorage();
|
|
623
|
-
case 'neo4j':
|
|
624
|
-
return new Neo4jStorage();
|
|
625
|
-
default:
|
|
626
|
-
throw new Error(`Unknown storage type: ${type}`);
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
async createForProject(
|
|
631
|
-
projectPath: string,
|
|
632
|
-
config: StorageConfig
|
|
633
|
-
): Promise<IStorage> {
|
|
634
|
-
const storage = await this.create(config);
|
|
635
|
-
await storage.initialize(projectPath);
|
|
636
|
-
return storage;
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
private async resolveStorageType(config: StorageConfig): Promise<StorageType> {
|
|
640
|
-
if (config.type !== 'auto') {
|
|
641
|
-
return config.type;
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
// 自动选择逻辑
|
|
645
|
-
const thresholds = config.autoThresholds || {
|
|
646
|
-
useGraphDBWhenFileCount: 500,
|
|
647
|
-
useGraphDBWhenNodeCount: 10000
|
|
648
|
-
};
|
|
649
|
-
|
|
650
|
-
const fileCount = await this.estimateFileCount();
|
|
651
|
-
|
|
652
|
-
return fileCount >= thresholds.useGraphDBWhenFileCount
|
|
653
|
-
? 'kuzudb'
|
|
654
|
-
: 'filesystem';
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
private async estimateFileCount(): Promise<number> {
|
|
658
|
-
// 快速估算文件数量
|
|
659
|
-
return 0;
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
```
|
|
161
|
+
| 实现 | 覆盖范围 |
|
|
162
|
+
|------|----------|
|
|
163
|
+
| `TypeScriptParser` | `ts` / `tsx` / `js` / `jsx` / `mjs` / `cjs` |
|
|
164
|
+
| `GoParser` | `go` |
|
|
165
|
+
| `PythonParser` | `py` |
|
|
663
166
|
|
|
664
|
-
|
|
167
|
+
### 5.4 Deferred
|
|
665
168
|
|
|
666
|
-
|
|
169
|
+
以下语言仍属于未来扩展空间,而非当前 shipped reality:
|
|
667
170
|
|
|
668
|
-
|
|
171
|
+
- Java
|
|
172
|
+
- Rust
|
|
173
|
+
- C/C++
|
|
174
|
+
- C#
|
|
175
|
+
- Ruby
|
|
176
|
+
- PHP
|
|
177
|
+
- Swift
|
|
178
|
+
- Kotlin
|
|
179
|
+
- Dart
|
|
180
|
+
- Perl
|
|
669
181
|
|
|
670
|
-
|
|
671
|
-
// src/infrastructure/parser/implementations/TreeSitterParser.ts
|
|
672
|
-
|
|
673
|
-
import Parser from 'tree-sitter';
|
|
674
|
-
|
|
675
|
-
/**
|
|
676
|
-
* Tree-sitter 解析器基类
|
|
677
|
-
* 所有 Tree-sitter 语言解析器继承此类
|
|
678
|
-
*/
|
|
679
|
-
export abstract class TreeSitterParser implements ILanguageParser {
|
|
680
|
-
protected parser: Parser | null = null;
|
|
681
|
-
protected grammar: any;
|
|
682
|
-
|
|
683
|
-
async initialize(): Promise<void> {
|
|
684
|
-
this.parser = new Parser();
|
|
685
|
-
this.parser.setLanguage(this.grammar);
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
async parseFile(
|
|
689
|
-
filePath: string,
|
|
690
|
-
content: string,
|
|
691
|
-
options?: ParseOptions
|
|
692
|
-
): Promise<ParseResult> {
|
|
693
|
-
if (!this.parser) {
|
|
694
|
-
throw new Error('Parser not initialized');
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
const tree = this.parser.parse(content);
|
|
698
|
-
const root = tree.rootNode;
|
|
699
|
-
|
|
700
|
-
const startTime = performance.now();
|
|
701
|
-
|
|
702
|
-
// 并行提取信息
|
|
703
|
-
const [imports, exports, symbols, callGraph, complexity] = await Promise.all([
|
|
704
|
-
this.extractImports(content),
|
|
705
|
-
this.extractExports(content),
|
|
706
|
-
this.extractSymbols(content),
|
|
707
|
-
options?.includeCallGraph ? this.buildCallGraph(content) : Promise.resolve(undefined),
|
|
708
|
-
options?.includeComplexity ? this.calculateComplexity(content) : Promise.resolve(undefined)
|
|
709
|
-
]);
|
|
710
|
-
|
|
711
|
-
const parseTime = performance.now() - startTime;
|
|
712
|
-
|
|
713
|
-
return {
|
|
714
|
-
filePath,
|
|
715
|
-
language: this.languageId,
|
|
716
|
-
module: this.buildModule(filePath, content, imports, exports),
|
|
717
|
-
symbols,
|
|
718
|
-
imports,
|
|
719
|
-
exports,
|
|
720
|
-
dependencies: this.buildDependencies(imports),
|
|
721
|
-
callGraph,
|
|
722
|
-
complexity,
|
|
723
|
-
parseTime
|
|
724
|
-
};
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
abstract extractImports(content: string): Promise<Import[]>;
|
|
728
|
-
abstract extractExports(content: string): Promise<Export[]>;
|
|
729
|
-
abstract extractSymbols(content: string): Promise<Symbol[]>;
|
|
730
|
-
abstract buildCallGraph(content: string): Promise<CallGraph>;
|
|
731
|
-
abstract calculateComplexity(content: string): Promise<ComplexityMetrics>;
|
|
732
|
-
|
|
733
|
-
// ... 其他方法实现
|
|
734
|
-
}
|
|
735
|
-
```
|
|
182
|
+
---
|
|
736
183
|
|
|
737
|
-
|
|
184
|
+
## 6. Server Layer 当前实现
|
|
738
185
|
|
|
739
|
-
|
|
740
|
-
// src/infrastructure/parser/implementations/python/PythonParser.ts
|
|
741
|
-
|
|
742
|
-
import Python from 'tree-sitter-python';
|
|
743
|
-
|
|
744
|
-
export class PythonParser extends TreeSitterParser {
|
|
745
|
-
readonly languageId = 'python';
|
|
746
|
-
readonly fileExtensions = ['.py', '.pyw', '.pyi'];
|
|
747
|
-
readonly name = 'Python Parser';
|
|
748
|
-
protected grammar = Python;
|
|
749
|
-
|
|
750
|
-
async extractImports(content: string): Promise<Import[]> {
|
|
751
|
-
const tree = this.parser!.parse(content);
|
|
752
|
-
const imports: Import[] = [];
|
|
753
|
-
|
|
754
|
-
// 查询 import 语句
|
|
755
|
-
const importQuery = new Parser.Query(Python, `
|
|
756
|
-
(import_statement
|
|
757
|
-
name: (dotted_name) @name)
|
|
758
|
-
|
|
759
|
-
(import_from_statement
|
|
760
|
-
module_name: (dotted_name) @module
|
|
761
|
-
name: (dotted_name) @name)
|
|
762
|
-
`);
|
|
763
|
-
|
|
764
|
-
const matches = importQuery.matches(tree.rootNode);
|
|
765
|
-
|
|
766
|
-
for (const match of matches) {
|
|
767
|
-
// 解析 import 信息
|
|
768
|
-
imports.push(this.parseImportMatch(match));
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
return imports;
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
async extractSymbols(content: string): Promise<Symbol[]> {
|
|
775
|
-
const tree = this.parser!.parse(content);
|
|
776
|
-
const symbols: Symbol[] = [];
|
|
777
|
-
|
|
778
|
-
// 查询类定义
|
|
779
|
-
const classQuery = new Parser.Query(Python, `
|
|
780
|
-
(class_definition
|
|
781
|
-
name: (identifier) @name) @class
|
|
782
|
-
`);
|
|
783
|
-
|
|
784
|
-
// 查询函数定义
|
|
785
|
-
const funcQuery = new Parser.Query(Python, `
|
|
786
|
-
(function_definition
|
|
787
|
-
name: (identifier) @name) @func
|
|
788
|
-
`);
|
|
789
|
-
|
|
790
|
-
// 处理类
|
|
791
|
-
const classMatches = classQuery.matches(tree.rootNode);
|
|
792
|
-
for (const match of classMatches) {
|
|
793
|
-
symbols.push(this.parseClassMatch(match));
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
// 处理函数
|
|
797
|
-
const funcMatches = funcQuery.matches(tree.rootNode);
|
|
798
|
-
for (const match of funcMatches) {
|
|
799
|
-
symbols.push(this.parseFunctionMatch(match));
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
return symbols;
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
supportsFeature(feature: LanguageFeature): boolean {
|
|
806
|
-
const supported: LanguageFeature[] = [
|
|
807
|
-
'type-inference',
|
|
808
|
-
'decorators',
|
|
809
|
-
'call-graph',
|
|
810
|
-
'cross-file-analysis',
|
|
811
|
-
'complexity-metrics'
|
|
812
|
-
];
|
|
813
|
-
return supported.includes(feature);
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
// ... 其他方法实现
|
|
817
|
-
}
|
|
818
|
-
```
|
|
186
|
+
### 6.1 当前结构
|
|
819
187
|
|
|
820
|
-
|
|
188
|
+
Server Layer 当前围绕以下组件组织:
|
|
821
189
|
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
private extToLanguage = new Map<string, LanguageId>();
|
|
828
|
-
|
|
829
|
-
constructor() {
|
|
830
|
-
this.registerBuiltInParsers();
|
|
831
|
-
}
|
|
832
|
-
|
|
833
|
-
private registerBuiltInParsers(): void {
|
|
834
|
-
// Phase 1: 已支持
|
|
835
|
-
this.register(new TypeScriptParser());
|
|
836
|
-
this.register(new JavaScriptParser());
|
|
837
|
-
this.register(new GoParser());
|
|
838
|
-
|
|
839
|
-
// Phase 2: MVP3 新增
|
|
840
|
-
this.register(new PythonParser());
|
|
841
|
-
this.register(new JavaParser());
|
|
842
|
-
this.register(new RustParser());
|
|
843
|
-
this.register(new CppParser());
|
|
844
|
-
|
|
845
|
-
// Phase 3: 后续添加
|
|
846
|
-
// this.register(new CSharpParser());
|
|
847
|
-
// ...
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
register(parser: ILanguageParser): void {
|
|
851
|
-
this.parsers.set(parser.languageId, parser);
|
|
852
|
-
|
|
853
|
-
for (const ext of parser.fileExtensions) {
|
|
854
|
-
this.extToLanguage.set(ext, parser.languageId);
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
getParser(language: LanguageId): ILanguageParser | undefined {
|
|
859
|
-
return this.parsers.get(language);
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
getParserByFile(filePath: string): ILanguageParser | undefined {
|
|
863
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
864
|
-
const language = this.extToLanguage.get(ext);
|
|
865
|
-
return language ? this.parsers.get(language) : undefined;
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
getSupportedExtensions(): string[] {
|
|
869
|
-
return Array.from(this.extToLanguage.keys());
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
getSupportedLanguages(): LanguageId[] {
|
|
873
|
-
return Array.from(this.parsers.keys());
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
```
|
|
190
|
+
- `CodeMapServer`
|
|
191
|
+
- `QueryHandler`
|
|
192
|
+
- `AnalysisHandler`
|
|
193
|
+
- `createApiRoutes`
|
|
194
|
+
- `server/types/*`
|
|
877
195
|
|
|
878
|
-
|
|
196
|
+
### 6.2 当前能力边界
|
|
879
197
|
|
|
880
|
-
|
|
198
|
+
当前 `Server Layer` 的真实状态不是“完整公共 API 产品面”,而是:
|
|
881
199
|
|
|
882
|
-
|
|
200
|
+
| 类别 | 当前状态 |
|
|
201
|
+
|------|----------|
|
|
202
|
+
| query / search / detail / callers / callees 等查询路由 | 已保留 |
|
|
203
|
+
| validate / export | 已保留 |
|
|
204
|
+
| analyze / refresh / incremental update 作为公共能力 | 明确返回 `501` unsupported |
|
|
883
205
|
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
private storageFactory: IStorageFactory,
|
|
890
|
-
private parserRegistry: IParserRegistry,
|
|
891
|
-
private analysisService: AnalysisService
|
|
892
|
-
) {}
|
|
893
|
-
|
|
894
|
-
async generate(request: GenerateRequest): Promise<GenerateResponse> {
|
|
895
|
-
const startTime = performance.now();
|
|
896
|
-
|
|
897
|
-
try {
|
|
898
|
-
// 1. 初始化存储
|
|
899
|
-
const storage = await this.storageFactory.createForProject(
|
|
900
|
-
request.projectPath,
|
|
901
|
-
request.storage || { type: 'filesystem' }
|
|
902
|
-
);
|
|
903
|
-
|
|
904
|
-
// 2. 发现文件
|
|
905
|
-
const files = await this.discoverFiles(request);
|
|
906
|
-
|
|
907
|
-
// 3. 解析文件
|
|
908
|
-
const parsedModules = await this.parseFiles(files, request, storage);
|
|
909
|
-
|
|
910
|
-
// 4. 构建代码图
|
|
911
|
-
const codeGraph = await this.buildCodeGraph(parsedModules, request);
|
|
912
|
-
|
|
913
|
-
// 5. 保存到存储
|
|
914
|
-
await storage.saveCodeGraph(codeGraph);
|
|
915
|
-
|
|
916
|
-
// 6. 生成输出文件
|
|
917
|
-
const generatedFiles = await this.generateOutputFiles(codeGraph, request);
|
|
918
|
-
|
|
919
|
-
const duration = performance.now() - startTime;
|
|
920
|
-
|
|
921
|
-
return {
|
|
922
|
-
success: true,
|
|
923
|
-
codeGraph,
|
|
924
|
-
generatedFiles,
|
|
925
|
-
statistics: {
|
|
926
|
-
totalFiles: files.length,
|
|
927
|
-
parsedFiles: parsedModules.length,
|
|
928
|
-
failedFiles: files.length - parsedModules.length,
|
|
929
|
-
totalSymbols: codeGraph.modules.reduce((sum, m) => sum + m.symbols.length, 0),
|
|
930
|
-
totalDependencies: codeGraph.dependencies.length,
|
|
931
|
-
duration
|
|
932
|
-
}
|
|
933
|
-
};
|
|
934
|
-
} catch (error) {
|
|
935
|
-
return {
|
|
936
|
-
success: false,
|
|
937
|
-
codeGraph: {} as CodeGraph,
|
|
938
|
-
generatedFiles: [],
|
|
939
|
-
statistics: {
|
|
940
|
-
totalFiles: 0,
|
|
941
|
-
parsedFiles: 0,
|
|
942
|
-
failedFiles: 0,
|
|
943
|
-
totalSymbols: 0,
|
|
944
|
-
totalDependencies: 0,
|
|
945
|
-
duration: performance.now() - startTime
|
|
946
|
-
},
|
|
947
|
-
error: error instanceof Error ? error.message : String(error)
|
|
948
|
-
};
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
private async discoverFiles(request: GenerateRequest): Promise<string[]> {
|
|
953
|
-
const include = request.include || ['src/**/*'];
|
|
954
|
-
const exclude = request.exclude || ['node_modules/**', 'dist/**'];
|
|
955
|
-
|
|
956
|
-
// 支持多语言扩展名
|
|
957
|
-
const extensions = this.parserRegistry.getSupportedExtensions();
|
|
958
|
-
const patterns = include.map(i =>
|
|
959
|
-
extensions.map(ext => `${i}${ext}`)
|
|
960
|
-
).flat();
|
|
961
|
-
|
|
962
|
-
return globby(patterns, {
|
|
963
|
-
cwd: request.projectPath,
|
|
964
|
-
ignore: exclude,
|
|
965
|
-
absolute: true
|
|
966
|
-
});
|
|
967
|
-
}
|
|
968
|
-
|
|
969
|
-
private async parseFiles(
|
|
970
|
-
files: string[],
|
|
971
|
-
request: GenerateRequest,
|
|
972
|
-
storage: IStorage
|
|
973
|
-
): Promise<Module[]> {
|
|
974
|
-
const modules: Module[] = [];
|
|
975
|
-
const batchSize = 50;
|
|
976
|
-
|
|
977
|
-
for (let i = 0; i < files.length; i += batchSize) {
|
|
978
|
-
const batch = files.slice(i, i + batchSize);
|
|
979
|
-
|
|
980
|
-
// 并行解析批次
|
|
981
|
-
const results = await Promise.all(
|
|
982
|
-
batch.map(async (file) => {
|
|
983
|
-
const parser = this.parserRegistry.getParserByFile(file);
|
|
984
|
-
if (!parser) return null;
|
|
985
|
-
|
|
986
|
-
try {
|
|
987
|
-
const content = await fs.readFile(file, 'utf-8');
|
|
988
|
-
const result = await parser.parseFile(file, content, {
|
|
989
|
-
includeCallGraph: request.mode === 'smart',
|
|
990
|
-
includeComplexity: request.mode === 'smart'
|
|
991
|
-
});
|
|
992
|
-
return result.module;
|
|
993
|
-
} catch (error) {
|
|
994
|
-
console.warn(`Failed to parse ${file}:`, error);
|
|
995
|
-
return null;
|
|
996
|
-
}
|
|
997
|
-
})
|
|
998
|
-
);
|
|
999
|
-
|
|
1000
|
-
modules.push(...results.filter((m): m is Module => m !== null));
|
|
1001
|
-
|
|
1002
|
-
// 进度回调
|
|
1003
|
-
if (request.onProgress) {
|
|
1004
|
-
request.onProgress({
|
|
1005
|
-
current: Math.min(i + batchSize, files.length),
|
|
1006
|
-
total: files.length,
|
|
1007
|
-
percentage: Math.round(((i + batchSize) / files.length) * 100),
|
|
1008
|
-
currentFile: batch[batch.length - 1]
|
|
1009
|
-
});
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
return modules;
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
|
-
// ... 其他方法
|
|
1017
|
-
}
|
|
1018
|
-
```
|
|
206
|
+
### 6.3 关键原则
|
|
207
|
+
|
|
208
|
+
- `Server Layer` 仍是内部架构层
|
|
209
|
+
- 公共 CLI 的 `server` 命令已移除
|
|
210
|
+
- 文档不能把 `src/server/` 的存在误写成“公共 HTTP API 已开放”
|
|
1019
211
|
|
|
1020
212
|
---
|
|
1021
213
|
|
|
1022
|
-
##
|
|
214
|
+
## 7. Public CLI 与 workflow 当前基线
|
|
1023
215
|
|
|
1024
|
-
###
|
|
216
|
+
### 7.1 公共命令面
|
|
1025
217
|
|
|
1026
|
-
```
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
import chalk from 'chalk';
|
|
1030
|
-
import { TreeNode, TreeOptions } from './types.js';
|
|
1031
|
-
|
|
1032
|
-
export class TreeVisualizer {
|
|
1033
|
-
private options: TreeOptions;
|
|
1034
|
-
|
|
1035
|
-
constructor(options: TreeOptions = {}) {
|
|
1036
|
-
this.options = {
|
|
1037
|
-
maxDepth: options.maxDepth ?? Infinity,
|
|
1038
|
-
showIcons: options.showIcons ?? true,
|
|
1039
|
-
showSize: options.showSize ?? false,
|
|
1040
|
-
...options
|
|
1041
|
-
};
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
visualize(root: TreeNode): string {
|
|
1045
|
-
return this.renderNode(root, '', 0, true);
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
|
-
private renderNode(
|
|
1049
|
-
node: TreeNode,
|
|
1050
|
-
prefix: string,
|
|
1051
|
-
depth: number,
|
|
1052
|
-
isLast: boolean
|
|
1053
|
-
): string {
|
|
1054
|
-
if (depth > this.options.maxDepth!) {
|
|
1055
|
-
return '';
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
const lines: string[] = [];
|
|
1059
|
-
|
|
1060
|
-
// 当前节点行
|
|
1061
|
-
const icon = this.getIcon(node);
|
|
1062
|
-
const name = this.formatName(node);
|
|
1063
|
-
const size = this.options.showSize && node.size
|
|
1064
|
-
? chalk.gray(` (${this.formatSize(node.size)})`)
|
|
1065
|
-
: '';
|
|
1066
|
-
|
|
1067
|
-
const line = prefix + (isLast ? '└── ' : '├── ') + icon + name + size;
|
|
1068
|
-
lines.push(line);
|
|
1069
|
-
|
|
1070
|
-
// 子节点
|
|
1071
|
-
if (node.children && node.children.length > 0) {
|
|
1072
|
-
const childPrefix = prefix + (isLast ? ' ' : '│ ');
|
|
1073
|
-
|
|
1074
|
-
for (let i = 0; i < node.children.length; i++) {
|
|
1075
|
-
const child = node.children[i];
|
|
1076
|
-
const childIsLast = i === node.children.length - 1;
|
|
1077
|
-
lines.push(this.renderNode(child, childPrefix, depth + 1, childIsLast));
|
|
1078
|
-
}
|
|
1079
|
-
}
|
|
1080
|
-
|
|
1081
|
-
return lines.join('\n');
|
|
1082
|
-
}
|
|
1083
|
-
|
|
1084
|
-
private getIcon(node: TreeNode): string {
|
|
1085
|
-
if (!this.options.showIcons) return '';
|
|
1086
|
-
|
|
1087
|
-
if (node.type === 'directory') {
|
|
1088
|
-
return chalk.blue('📁 ');
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
// 根据扩展名返回图标
|
|
1092
|
-
const ext = node.name.split('.').pop()?.toLowerCase();
|
|
1093
|
-
const iconMap: Record<string, string> = {
|
|
1094
|
-
'ts': '📘 ',
|
|
1095
|
-
'js': '📒 ',
|
|
1096
|
-
'py': '🐍 ',
|
|
1097
|
-
'java': '☕ ',
|
|
1098
|
-
'go': '🐹 ',
|
|
1099
|
-
'rs': '🦀 ',
|
|
1100
|
-
'json': '📋 ',
|
|
1101
|
-
'md': '📝 ',
|
|
1102
|
-
'default': '📄 '
|
|
1103
|
-
};
|
|
1104
|
-
|
|
1105
|
-
return iconMap[ext || 'default'] || iconMap.default;
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
|
-
private formatName(node: TreeNode): string {
|
|
1109
|
-
if (node.highlight) {
|
|
1110
|
-
return chalk.yellow(node.name);
|
|
1111
|
-
}
|
|
1112
|
-
return node.name;
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
|
-
private formatSize(bytes: number): string {
|
|
1116
|
-
if (bytes < 1024) return `${bytes}B`;
|
|
1117
|
-
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
1118
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
1119
|
-
}
|
|
1120
|
-
}
|
|
218
|
+
```text
|
|
219
|
+
init / generate / query / deps / cycles / complexity / impact
|
|
220
|
+
analyze / ci / workflow / export / ship
|
|
1121
221
|
```
|
|
1122
222
|
|
|
1123
|
-
###
|
|
223
|
+
### 7.2 已移除命令
|
|
1124
224
|
|
|
1125
|
-
|
|
1126
|
-
// src/cli/visualizers/GraphVisualizer.ts
|
|
1127
|
-
|
|
1128
|
-
export class GraphVisualizer {
|
|
1129
|
-
visualize(graph: DependencyGraph): string {
|
|
1130
|
-
const lines: string[] = [];
|
|
1131
|
-
const visited = new Set<string>();
|
|
1132
|
-
|
|
1133
|
-
// 找到根节点
|
|
1134
|
-
const roots = this.findRootNodes(graph);
|
|
1135
|
-
|
|
1136
|
-
for (const root of roots) {
|
|
1137
|
-
lines.push(...this.renderSubgraph(root, graph, visited, '', true));
|
|
1138
|
-
}
|
|
1139
|
-
|
|
1140
|
-
return lines.join('\n');
|
|
1141
|
-
}
|
|
1142
|
-
|
|
1143
|
-
private renderSubgraph(
|
|
1144
|
-
nodeId: string,
|
|
1145
|
-
graph: DependencyGraph,
|
|
1146
|
-
visited: Set<string>,
|
|
1147
|
-
prefix: string,
|
|
1148
|
-
isLast: boolean
|
|
1149
|
-
): string[] {
|
|
1150
|
-
const lines: string[] = [];
|
|
1151
|
-
|
|
1152
|
-
if (visited.has(nodeId)) {
|
|
1153
|
-
lines.push(prefix + (isLast ? '└── ' : '├── ') + chalk.gray(`${nodeId} (circular)`));
|
|
1154
|
-
return lines;
|
|
1155
|
-
}
|
|
1156
|
-
|
|
1157
|
-
visited.add(nodeId);
|
|
1158
|
-
|
|
1159
|
-
const node = graph.nodes[nodeId];
|
|
1160
|
-
const deps = graph.edges.filter(e => e.from === nodeId);
|
|
1161
|
-
|
|
1162
|
-
lines.push(prefix + (isLast ? '└── ' : '├── ') + node.path);
|
|
1163
|
-
|
|
1164
|
-
for (let i = 0; i < deps.length; i++) {
|
|
1165
|
-
const dep = deps[i];
|
|
1166
|
-
const childPrefix = prefix + (isLast ? ' ' : '│ ');
|
|
1167
|
-
const childIsLast = i === deps.length - 1;
|
|
1168
|
-
|
|
1169
|
-
lines.push(...this.renderSubgraph(dep.to, graph, new Set(visited), childPrefix, childIsLast));
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
|
-
return lines;
|
|
1173
|
-
}
|
|
1174
|
-
|
|
1175
|
-
private findRootNodes(graph: DependencyGraph): string[] {
|
|
1176
|
-
// 找到没有入边的节点
|
|
1177
|
-
const hasIncoming = new Set(graph.edges.map(e => e.to));
|
|
1178
|
-
return Object.keys(graph.nodes).filter(id => !hasIncoming.has(id));
|
|
1179
|
-
}
|
|
1180
|
-
}
|
|
1181
|
-
```
|
|
225
|
+
以下命令已从 public CLI 移除,并保留迁移提示:
|
|
1182
226
|
|
|
1183
|
-
|
|
227
|
+
- `server`
|
|
228
|
+
- `watch`
|
|
229
|
+
- `report`
|
|
230
|
+
- `logs`
|
|
1184
231
|
|
|
1185
|
-
|
|
1186
|
-
// src/cli/visualizers/HeatmapVisualizer.ts
|
|
1187
|
-
|
|
1188
|
-
import chalk from 'chalk';
|
|
1189
|
-
|
|
1190
|
-
export class HeatmapVisualizer {
|
|
1191
|
-
visualize(items: HeatmapItem[]): string {
|
|
1192
|
-
// 按值排序
|
|
1193
|
-
const sorted = [...items].sort((a, b) => b.value - a.value);
|
|
1194
|
-
|
|
1195
|
-
// 计算最大值用于归一化
|
|
1196
|
-
const maxValue = Math.max(...items.map(i => i.value));
|
|
1197
|
-
|
|
1198
|
-
const lines: string[] = [];
|
|
1199
|
-
|
|
1200
|
-
for (const item of sorted) {
|
|
1201
|
-
const intensity = item.value / maxValue;
|
|
1202
|
-
const color = this.getColor(intensity);
|
|
1203
|
-
const bar = this.renderBar(intensity);
|
|
1204
|
-
|
|
1205
|
-
lines.push(`${color(item.name.padEnd(40))} ${bar} ${chalk.gray(item.value)}`);
|
|
1206
|
-
}
|
|
1207
|
-
|
|
1208
|
-
return lines.join('\n');
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
private getColor(intensity: number): chalk.Chalk {
|
|
1212
|
-
if (intensity > 0.75) return chalk.red;
|
|
1213
|
-
if (intensity > 0.5) return chalk.yellow;
|
|
1214
|
-
if (intensity > 0.25) return chalk.green;
|
|
1215
|
-
return chalk.blue;
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
private renderBar(intensity: number): string {
|
|
1219
|
-
const width = 20;
|
|
1220
|
-
const filled = Math.round(intensity * width);
|
|
1221
|
-
const empty = width - filled;
|
|
1222
|
-
|
|
1223
|
-
return '█'.repeat(filled) + '░'.repeat(empty);
|
|
1224
|
-
}
|
|
1225
|
-
}
|
|
232
|
+
### 7.3 `workflow` 的当前边界
|
|
1226
233
|
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
234
|
+
`workflow` 当前是 analysis-only 能力:
|
|
235
|
+
|
|
236
|
+
```text
|
|
237
|
+
find → read → link → show
|
|
1231
238
|
```
|
|
1232
239
|
|
|
240
|
+
它不再承担:
|
|
241
|
+
|
|
242
|
+
- 代码实现 phase 编排
|
|
243
|
+
- commit / CI / release 流程编排
|
|
244
|
+
- 更通用的工程代理 orchestrator 产品面
|
|
245
|
+
|
|
1233
246
|
---
|
|
1234
247
|
|
|
1235
|
-
##
|
|
248
|
+
## 8. 测试与验证基线
|
|
1236
249
|
|
|
1237
|
-
|
|
250
|
+
当前与架构边界直接相关的验证链路包括:
|
|
1238
251
|
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
│ └─────┬─────┘ │
|
|
1248
|
-
│ │ │
|
|
1249
|
-
│ ┌────────┴────────┐ │
|
|
1250
|
-
│ │ Integration Tests│ < 50 个场景 │
|
|
1251
|
-
│ │ (Server + Infra) │ │
|
|
1252
|
-
│ └────────┬────────┘ │
|
|
1253
|
-
│ │ │
|
|
1254
|
-
│ ┌─────────────┴─────────────┐ │
|
|
1255
|
-
│ │ Unit Tests │ > 500 个测试 │
|
|
1256
|
-
│ │ (Domain + Infrastructure) │ │
|
|
1257
|
-
│ └───────────────────────────┘ │
|
|
1258
|
-
│ │
|
|
1259
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
1260
|
-
```
|
|
252
|
+
| 命令 | 目的 |
|
|
253
|
+
|------|------|
|
|
254
|
+
| `npm run docs:check` | 文档与 AI 文档护栏 |
|
|
255
|
+
| `npm run typecheck` | TypeScript 契约验证 |
|
|
256
|
+
| `npm run lint` | 代码质量检查(当前允许 warning baseline) |
|
|
257
|
+
| `npm test` | 单元/集成测试 |
|
|
258
|
+
| `npm run build` | 构建验证 |
|
|
259
|
+
| `node dist/cli/index.js ci check-docs-sync` | docs guardrail + analyze docs sync |
|
|
1261
260
|
|
|
1262
|
-
|
|
261
|
+
`v1.3` 里程碑审计结果:
|
|
1263
262
|
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
{ name: 'FileSystemStorage', factory: () => new FileSystemStorage() },
|
|
1269
|
-
{ name: 'KuzuDBStorage', factory: () => new KuzuDBStorage() },
|
|
1270
|
-
];
|
|
1271
|
-
|
|
1272
|
-
for (const { name, factory } of implementations) {
|
|
1273
|
-
describe(name, () => {
|
|
1274
|
-
let storage: IStorage;
|
|
1275
|
-
|
|
1276
|
-
beforeEach(async () => {
|
|
1277
|
-
storage = factory();
|
|
1278
|
-
await storage.initialize('/tmp/test-project');
|
|
1279
|
-
});
|
|
1280
|
-
|
|
1281
|
-
it('should save and load code graph', async () => {
|
|
1282
|
-
const graph = createMockCodeGraph();
|
|
1283
|
-
await storage.saveCodeGraph(graph);
|
|
1284
|
-
const loaded = await storage.loadCodeGraph();
|
|
1285
|
-
expect(loaded).toEqual(graph);
|
|
1286
|
-
});
|
|
1287
|
-
|
|
1288
|
-
it('should find symbols by name', async () => {
|
|
1289
|
-
// ... 测试实现
|
|
1290
|
-
});
|
|
1291
|
-
|
|
1292
|
-
it('should detect cycles', async () => {
|
|
1293
|
-
// ... 测试实现
|
|
1294
|
-
});
|
|
1295
|
-
});
|
|
1296
|
-
}
|
|
1297
|
-
});
|
|
1298
|
-
```
|
|
263
|
+
- requirements: `12/12`
|
|
264
|
+
- phases: `4/4`
|
|
265
|
+
- integration: `4/4`
|
|
266
|
+
- flows: `4/4`
|
|
1299
267
|
|
|
1300
268
|
---
|
|
1301
269
|
|
|
1302
|
-
##
|
|
270
|
+
## 9. 当前技术债与 Deferred
|
|
1303
271
|
|
|
1304
|
-
###
|
|
272
|
+
### 9.1 非阻断技术债
|
|
1305
273
|
|
|
1306
|
-
|
|
|
1307
|
-
|
|
1308
|
-
|
|
|
1309
|
-
| `src/core/analyzer.ts` | `src/domain/services/AnalysisService.ts` | 重构 |
|
|
1310
|
-
| `src/parser/index.ts` | `src/infrastructure/parser/` | 拆分 |
|
|
1311
|
-
| `src/cache/*.ts` | `src/infrastructure/cache/` | 移动 |
|
|
1312
|
-
| `src/generator/*.ts` | `src/server/services/` | 重构 |
|
|
1313
|
-
| `src/cli/commands/*.ts` | `src/cli/commands/` | 适配新接口 |
|
|
274
|
+
| 项目 | 当前状态 |
|
|
275
|
+
|------|----------|
|
|
276
|
+
| repo-wide ESLint warnings baseline | 仍存在,但不阻断当前里程碑 |
|
|
1314
277
|
|
|
1315
|
-
###
|
|
278
|
+
### 9.2 Deferred 技术项
|
|
1316
279
|
|
|
1317
|
-
|
|
1318
|
-
|
|
280
|
+
| 项目 | 说明 |
|
|
281
|
+
|------|------|
|
|
282
|
+
| 更强的 auto storage heuristic | 当前仍保守返回 `filesystem` |
|
|
283
|
+
| 更多 parser 实现 | 接口预留,当前未交付 |
|
|
284
|
+
| 公共 HTTP API 产品化 | 当前不在范围内 |
|
|
285
|
+
| `viz` / `tui` / 更强交互可视化 | 当前不在公共 CLI 基线中 |
|
|
286
|
+
| Kùzu-native 深度查询优化 | 后续候选,不属于 `v1.3` 已交付事实 |
|
|
1319
287
|
|
|
1320
|
-
|
|
1321
|
-
export { analyze } from './domain/services/AnalysisService.js';
|
|
1322
|
-
export { parseFile } from './infrastructure/parser/adapters/LegacyParserAdapter.js';
|
|
288
|
+
---
|
|
1323
289
|
|
|
1324
|
-
|
|
1325
|
-
export { CodeMapService } from './server/services/CodeMapService.js';
|
|
1326
|
-
export { StorageFactory } from './infrastructure/storage/StorageFactory.js';
|
|
1327
|
-
export { ParserRegistry } from './infrastructure/parser/ParserRegistry.js';
|
|
1328
|
-
```
|
|
290
|
+
## 10. 迁移与兼容性结论
|
|
1329
291
|
|
|
1330
|
-
|
|
292
|
+
### 10.1 已稳定的迁移规则
|
|
1331
293
|
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
```json
|
|
1337
|
-
{
|
|
1338
|
-
"dependencies": {
|
|
1339
|
-
"kuzu": "^0.8.0",
|
|
1340
|
-
"neo4j-driver": "^5.28.0",
|
|
1341
|
-
"tree-sitter": "^0.22.0",
|
|
1342
|
-
"tree-sitter-python": "^0.23.0",
|
|
1343
|
-
"tree-sitter-java": "^0.23.0",
|
|
1344
|
-
"tree-sitter-rust": "^0.23.0",
|
|
1345
|
-
"tree-sitter-cpp": "^0.23.0",
|
|
1346
|
-
"chalk": "^5.4.0",
|
|
1347
|
-
"cli-progress": "^3.12.0",
|
|
1348
|
-
"ink": "^5.1.0"
|
|
1349
|
-
},
|
|
1350
|
-
"devDependencies": {
|
|
1351
|
-
"@types/cli-progress": "^3.11.6"
|
|
1352
|
-
}
|
|
1353
|
-
}
|
|
1354
|
-
```
|
|
294
|
+
- 配置文件主入口为 `mycodemap.config.json`
|
|
295
|
+
- 旧 `codemap.config.json` 仍可被识别,但应迁移到新名称
|
|
296
|
+
- 旧 `neo4j` 配置会收到显式迁移错误
|
|
1355
297
|
|
|
1356
|
-
|
|
298
|
+
### 10.2 当前不应再继续传播的旧说法
|
|
1357
299
|
|
|
1358
|
-
|
|
300
|
+
以下表述已不准确:
|
|
1359
301
|
|
|
1360
|
-
|
|
302
|
+
- “MVP3 当前已支持 14 种语言”
|
|
303
|
+
- “`viz` / `tui` 是当前 public CLI 的一部分”
|
|
304
|
+
- “`src/server/` 等同于公共 `mycodemap server` 产品面”
|
|
305
|
+
- “`auto` 已完成智能切换图存储”
|
|
306
|
+
- “Neo4j 仍是正式支持 backend”
|
|
1361
307
|
|
|
1362
|
-
|
|
1363
|
-
|------|------|
|
|
1364
|
-
| Server Layer | 应用服务层,协调用例和基础设施 |
|
|
1365
|
-
| Storage Abstraction | 存储抽象,支持多种后端实现 |
|
|
1366
|
-
| Tree-sitter | 增量解析器生成工具 |
|
|
1367
|
-
| KùzuDB | 高性能嵌入式图数据库 |
|
|
1368
|
-
| CLI Visualizer | 命令行可视化组件 |
|
|
308
|
+
---
|
|
1369
309
|
|
|
1370
|
-
|
|
310
|
+
## 11. 参考文档
|
|
1371
311
|
|
|
1372
|
-
-
|
|
1373
|
-
-
|
|
1374
|
-
-
|
|
312
|
+
- `docs/product-specs/MVP3-ARCHITECTURE-COMPARISON.md`
|
|
313
|
+
- `docs/product-specs/MVP3-ARCHITECTURE-REDESIGN-PRD.md`
|
|
314
|
+
- `.planning/PROJECT.md`
|
|
315
|
+
- `.planning/REQUIREMENTS.md`
|
|
316
|
+
- `.planning/v1.3-MILESTONE-AUDIT.md`
|