autosnippet 3.2.18 → 3.2.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/README.md +73 -104
  2. package/dashboard/dist/assets/{index-CKMy5LY6.js → index-DdvZE4Yd.js} +1 -1
  3. package/dashboard/dist/index.html +1 -1
  4. package/dist/bin/cli.js +45 -10
  5. package/dist/lib/agent/AgentEventBus.js +3 -3
  6. package/dist/lib/agent/AgentFactory.d.ts +3 -3
  7. package/dist/lib/agent/AgentFactory.js +4 -4
  8. package/dist/lib/agent/AgentMessage.d.ts +8 -8
  9. package/dist/lib/agent/AgentMessage.js +8 -8
  10. package/dist/lib/agent/AgentRuntime.js +2 -2
  11. package/dist/lib/agent/AgentState.js +4 -4
  12. package/dist/lib/agent/ConversationStore.d.ts +1 -1
  13. package/dist/lib/agent/ConversationStore.js +1 -1
  14. package/dist/lib/agent/PipelineStrategy.js +1 -1
  15. package/dist/lib/agent/context/ContextWindow.d.ts +2 -2
  16. package/dist/lib/agent/context/ContextWindow.js +7 -7
  17. package/dist/lib/agent/context/ExplorationTracker.js +9 -9
  18. package/dist/lib/agent/context/exploration/PlanTracker.js +2 -2
  19. package/dist/lib/agent/context/exploration/SignalDetector.d.ts +1 -1
  20. package/dist/lib/agent/context/exploration/SignalDetector.js +1 -1
  21. package/dist/lib/agent/core/LoopContext.d.ts +21 -21
  22. package/dist/lib/agent/core/LoopContext.js +21 -21
  23. package/dist/lib/agent/core/SystemPromptBuilder.js +4 -4
  24. package/dist/lib/agent/domain/EvidenceCollector.js +5 -5
  25. package/dist/lib/agent/memory/ActiveContext.js +1 -1
  26. package/dist/lib/agent/memory/MemoryRetriever.js +1 -1
  27. package/dist/lib/agent/memory/MemoryStore.js +2 -2
  28. package/dist/lib/agent/memory/SessionStore.js +3 -3
  29. package/dist/lib/agent/policies.d.ts +1 -1
  30. package/dist/lib/agent/policies.js +1 -1
  31. package/dist/lib/agent/strategies.d.ts +1 -1
  32. package/dist/lib/agent/strategies.js +4 -4
  33. package/dist/lib/agent/tools/_shared.d.ts +1 -1
  34. package/dist/lib/agent/tools/_shared.js +1 -1
  35. package/dist/lib/agent/tools/infrastructure.js +2 -2
  36. package/dist/lib/cli/SetupService.d.ts +25 -25
  37. package/dist/lib/cli/SetupService.js +28 -15
  38. package/dist/lib/cli/deploy/FileDeployer.d.ts +9 -2
  39. package/dist/lib/cli/deploy/FileDeployer.js +139 -46
  40. package/dist/lib/cli/deploy/FileManifest.d.ts +23 -39
  41. package/dist/lib/cli/deploy/FileManifest.js +22 -27
  42. package/dist/lib/core/AstAnalyzer.d.ts +2 -2
  43. package/dist/lib/core/AstAnalyzer.js +2 -2
  44. package/dist/lib/core/analysis/CallEdgeResolver.d.ts +7 -7
  45. package/dist/lib/core/analysis/CallEdgeResolver.js +9 -9
  46. package/dist/lib/core/analysis/CallGraphAnalyzer.d.ts +4 -4
  47. package/dist/lib/core/analysis/CallGraphAnalyzer.js +2 -2
  48. package/dist/lib/core/analysis/ImportPathResolver.d.ts +0 -2
  49. package/dist/lib/core/analysis/ImportPathResolver.js +2 -4
  50. package/dist/lib/core/ast/ProjectGraph.js +7 -7
  51. package/dist/lib/core/capability/CapabilityProbe.js +6 -14
  52. package/dist/lib/domain/knowledge/UnifiedValidator.js +2 -2
  53. package/dist/lib/domain/knowledge/values/Constraints.js +4 -4
  54. package/dist/lib/domain/knowledge/values/Content.js +6 -6
  55. package/dist/lib/domain/knowledge/values/Quality.js +5 -5
  56. package/dist/lib/domain/knowledge/values/Reasoning.js +5 -5
  57. package/dist/lib/domain/knowledge/values/Relations.js +1 -1
  58. package/dist/lib/domain/knowledge/values/Stats.js +6 -6
  59. package/dist/lib/domain/task/TaskIdGenerator.d.ts +4 -4
  60. package/dist/lib/domain/task/TaskIdGenerator.js +2 -2
  61. package/dist/lib/external/lark/LarkTransport.js +4 -4
  62. package/dist/lib/external/mcp/McpServer.d.ts +3 -7
  63. package/dist/lib/external/mcp/McpServer.js +9 -13
  64. package/dist/lib/external/mcp/handlers/bootstrap/ExternalSubmissionTracker.js +5 -5
  65. package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.js +4 -3
  66. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.d.ts +3 -3
  67. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +3 -3
  68. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.d.ts +1 -1
  69. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.js +1 -1
  70. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.js +3 -3
  71. package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-sop.js +27 -14
  72. package/dist/lib/external/mcp/handlers/bootstrap-external.js +6 -0
  73. package/dist/lib/external/mcp/handlers/dimension-complete-external.js +55 -1
  74. package/dist/lib/external/mcp/handlers/skill.js +9 -31
  75. package/dist/lib/external/mcp/handlers/system.js +2 -2
  76. package/dist/lib/external/mcp/handlers/task.js +16 -1
  77. package/dist/lib/external/mcp/tools.d.ts +12 -10
  78. package/dist/lib/external/mcp/tools.js +97 -69
  79. package/dist/lib/http/utils/routeHelpers.d.ts +1 -1
  80. package/dist/lib/http/utils/routeHelpers.js +1 -1
  81. package/dist/lib/http/utils/sse-sessions.d.ts +1 -1
  82. package/dist/lib/http/utils/sse-sessions.js +1 -1
  83. package/dist/lib/infrastructure/cache/CacheService.js +1 -1
  84. package/dist/lib/infrastructure/vector/AsyncPersistence.js +8 -8
  85. package/dist/lib/infrastructure/vector/BatchEmbedder.d.ts +1 -1
  86. package/dist/lib/infrastructure/vector/BatchEmbedder.js +2 -2
  87. package/dist/lib/infrastructure/vector/HnswIndex.d.ts +4 -4
  88. package/dist/lib/infrastructure/vector/HnswIndex.js +5 -5
  89. package/dist/lib/infrastructure/vector/HnswVectorAdapter.js +8 -8
  90. package/dist/lib/infrastructure/vector/ScalarQuantizer.d.ts +1 -1
  91. package/dist/lib/infrastructure/vector/ScalarQuantizer.js +4 -4
  92. package/dist/lib/infrastructure/vector/VectorStore.d.ts +1 -1
  93. package/dist/lib/infrastructure/vector/VectorStore.js +1 -1
  94. package/dist/lib/injection/ServiceContainer.d.ts +1 -1
  95. package/dist/lib/injection/ServiceContainer.js +1 -1
  96. package/dist/lib/platform/NativeUi.d.ts +1 -1
  97. package/dist/lib/platform/NativeUi.js +1 -1
  98. package/dist/lib/platform/ios/spm/DependencyGraph.d.ts +1 -1
  99. package/dist/lib/platform/ios/spm/DependencyGraph.js +1 -1
  100. package/dist/lib/platform/ios/spm/PolicyEngine.d.ts +1 -1
  101. package/dist/lib/platform/ios/spm/PolicyEngine.js +1 -1
  102. package/dist/lib/platform/ios/spm/SpmDiscoverer.js +1 -1
  103. package/dist/lib/platform/ios/spm/SpmHelper.js +3 -3
  104. package/dist/lib/platform/ios/xcode/SaveEventFilter.js +2 -2
  105. package/dist/lib/platform/ios/xcode/XcodeIntegration.js +1 -1
  106. package/dist/lib/repository/base/BaseRepository.js +1 -1
  107. package/dist/lib/repository/task/TaskRepository.impl.d.ts +2 -2
  108. package/dist/lib/repository/task/TaskRepository.impl.js +1 -1
  109. package/dist/lib/repository/token/TokenUsageStore.js +1 -1
  110. package/dist/lib/service/automation/ActionPipeline.d.ts +1 -1
  111. package/dist/lib/service/automation/ActionPipeline.js +1 -1
  112. package/dist/lib/service/bootstrap/BootstrapEventEmitter.js +2 -2
  113. package/dist/lib/service/bootstrap/BootstrapTaskManager.d.ts +1 -1
  114. package/dist/lib/service/bootstrap/BootstrapTaskManager.js +2 -2
  115. package/dist/lib/service/bootstrap/DimensionCopyRegistry.d.ts +2 -2
  116. package/dist/lib/service/bootstrap/DimensionCopyRegistry.js +2 -2
  117. package/dist/lib/service/delivery/AgentInstructionsGenerator.d.ts +6 -15
  118. package/dist/lib/service/delivery/AgentInstructionsGenerator.js +53 -189
  119. package/dist/lib/service/delivery/CursorDeliveryPipeline.d.ts +6 -16
  120. package/dist/lib/service/delivery/CursorDeliveryPipeline.js +14 -19
  121. package/dist/lib/service/delivery/KnowledgeCompressor.d.ts +1 -1
  122. package/dist/lib/service/delivery/KnowledgeCompressor.js +1 -1
  123. package/dist/lib/service/delivery/RulesGenerator.d.ts +10 -3
  124. package/dist/lib/service/delivery/RulesGenerator.js +43 -3
  125. package/dist/lib/service/delivery/SkillsSyncer.d.ts +21 -7
  126. package/dist/lib/service/delivery/SkillsSyncer.js +46 -10
  127. package/dist/lib/service/delivery/TopicClassifier.d.ts +3 -6
  128. package/dist/lib/service/delivery/TopicClassifier.js +0 -3
  129. package/dist/lib/service/guard/ExclusionManager.d.ts +1 -1
  130. package/dist/lib/service/guard/ExclusionManager.js +1 -1
  131. package/dist/lib/service/guard/GuardCheckEngine.d.ts +3 -3
  132. package/dist/lib/service/guard/GuardCheckEngine.js +5 -5
  133. package/dist/lib/service/guard/GuardCrossFileChecks.d.ts +1 -1
  134. package/dist/lib/service/guard/GuardFeedbackLoop.d.ts +3 -3
  135. package/dist/lib/service/guard/GuardFeedbackLoop.js +3 -3
  136. package/dist/lib/service/guard/GuardPatternUtils.js +1 -1
  137. package/dist/lib/service/guard/GuardService.d.ts +1 -15
  138. package/dist/lib/service/guard/GuardService.js +0 -1
  139. package/dist/lib/service/guard/RuleLearner.d.ts +1 -1
  140. package/dist/lib/service/guard/RuleLearner.js +1 -1
  141. package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +3 -3
  142. package/dist/lib/service/knowledge/CodeEntityGraph.js +3 -3
  143. package/dist/lib/service/knowledge/KnowledgeService.d.ts +0 -1
  144. package/dist/lib/service/knowledge/KnowledgeService.js +0 -1
  145. package/dist/lib/service/module/ModuleService.d.ts +1 -1
  146. package/dist/lib/service/module/ModuleService.js +2 -2
  147. package/dist/lib/service/search/HybridRetriever.d.ts +2 -2
  148. package/dist/lib/service/search/HybridRetriever.js +2 -2
  149. package/dist/lib/service/search/SearchEngine.d.ts +1 -3
  150. package/dist/lib/service/search/SearchEngine.js +1 -3
  151. package/dist/lib/service/search/contextBoost.d.ts +1 -1
  152. package/dist/lib/service/skills/EventAggregator.js +2 -2
  153. package/dist/lib/service/skills/SignalCollector.js +1 -1
  154. package/dist/lib/service/snippet/codecs/VSCodeCodec.js +1 -1
  155. package/dist/lib/service/task/TaskGraphService.d.ts +0 -3
  156. package/dist/lib/service/task/TaskGraphService.js +0 -3
  157. package/dist/lib/service/task/TaskKnowledgeBridge.d.ts +8 -27
  158. package/dist/lib/service/task/TaskKnowledgeBridge.js +0 -8
  159. package/dist/lib/service/task/TaskReadyEngine.d.ts +1 -2
  160. package/dist/lib/service/task/TaskReadyEngine.js +0 -1
  161. package/dist/lib/service/wiki/WikiRenderers.js +0 -1
  162. package/dist/lib/service/wiki/WikiUtils.js +2 -7
  163. package/dist/lib/shared/PathGuard.js +6 -6
  164. package/dist/lib/shared/schemas/mcp-tools.js +84 -43
  165. package/dist/scripts/install-vscode-copilot.js +14 -4
  166. package/package.json +1 -1
  167. package/skills/autosnippet-create/SKILL.md +131 -131
  168. package/skills/autosnippet-devdocs/SKILL.md +1 -2
  169. package/skills/autosnippet-guard/SKILL.md +20 -89
  170. package/skills/autosnippet-recipes/SKILL.md +35 -117
  171. package/skills/autosnippet-structure/SKILL.md +23 -55
  172. package/templates/cursor-rules/autosnippet-skills.mdc +17 -33
  173. package/templates/instructions/agent-static.md +24 -0
  174. package/templates/instructions/conventions.md +42 -0
  175. package/skills/autosnippet-analysis/SKILL.md +0 -169
  176. package/skills/autosnippet-candidates/SKILL.md +0 -367
  177. package/skills/autosnippet-coldstart/SKILL.md +0 -988
  178. package/skills/autosnippet-concepts/SKILL.md +0 -630
  179. package/skills/autosnippet-intent/SKILL.md +0 -55
  180. package/skills/autosnippet-lifecycle/SKILL.md +0 -100
  181. package/templates/copilot-instructions.md +0 -66
  182. package/templates/cursor-rules/autosnippet-conventions.mdc +0 -172
  183. package/templates/cursor-rules/autosnippet-workflow.mdc +0 -76
package/README.md CHANGED
@@ -14,11 +14,13 @@ Extract code patterns from your codebase into a knowledge base, and serve them t
14
14
 
15
15
  ---
16
16
 
17
+ - [Why](#why) · [Get Started](#get-started) · [Using in Your IDE](#using-in-your-ide) · [More Capabilities](#more-capabilities) · [Dashboard](#dashboard) · [IDE Support](#ide-support) · [Architecture](docs/architecture.en.md)
18
+
17
19
  ## Why
18
20
 
19
21
  Copilot and Cursor don't know how your team writes code. They'll generate something that works, but it won't look like yours — wrong naming, wrong patterns, wrong abstractions. You end up rewriting the AI's output or explaining the same conventions in every PR review.
20
22
 
21
- AutoSnippet fixes this. It scans your codebase, extracts the patterns that matter (with your approval), and makes them available to any AI tool via [MCP](https://modelcontextprotocol.io/). Next time Cursor generates code, it actually follows your conventions.
23
+ AutoSnippet builds a **persistent local memory** for your project. It scans your codebase, extracts the patterns that matter (with your approval), and makes them available to any AI tool via [MCP](https://modelcontextprotocol.io/). This knowledge lives locally, doesn't consume your LLM context window, and is injected on demand when AI needs it — the more knowledge accumulates, the more your AI writes code that actually follows your conventions.
22
24
 
23
25
  ```
24
26
  Your code → AI extracts patterns → You review → Knowledge base
@@ -34,42 +36,84 @@ Your code → AI extracts patterns → You review → Knowledge base
34
36
  npm install -g autosnippet
35
37
 
36
38
  cd your-project
37
- asd setup # workspace + DB + IDE configs (Cursor, VS Code, Trae, Qoder)
38
- asd coldstart # scans your code, generates pattern candidates
39
- asd ui # open the dashboard to review what was found
39
+ asd setup # workspace + DB + MCP configs (auto-detects Cursor / VS Code / Trae / Qoder)
40
+ asd ui # start the background service (MCP Server + Dashboard) — IDE and MCP tools require this
40
41
  ```
41
42
 
42
- That's it. After you approve some candidates, they become **Recipes** structured knowledge entries that your IDE's AI can query in real time.
43
+ > **Trae / Qoder users:** After `asd setup`, run `asd mirror` to sync `.cursor/` config to `.trae/` / `.qoder/`.
43
44
 
44
- ## How It Works
45
+ ## Using in Your IDE
45
46
 
47
+ `asd setup` takes care of everything. Open your IDE's **Agent Mode** (Cursor Composer / VS Code Copilot Chat / Trae) and start talking.
48
+
49
+ > **First time:** Enable the `autosnippet` server in your IDE's MCP settings.
50
+
51
+ > **Tip:** The stronger your IDE Agent model, the better the results. Choose Claude Opus 4 / Sonnet 4, GPT-5, or Gemini 3 Pro in Cursor / Copilot for more accurate patterns and fewer false positives.
52
+
53
+ ### Cold Start: Build the project knowledge base
54
+
55
+ > 💬 *"Run a cold start, build the project knowledge base"*
56
+
57
+ The agent scans the entire project and extracts your team's coding patterns, architecture conventions, and call idioms, generating a project Wiki along the way. You only need to do this once, then it's daily use from here.
58
+
59
+ ### Daily: just say what you need
60
+
61
+ | You say | You get |
62
+ |---------|---------|
63
+ | ① *"How do we write API endpoints in this project?"* | Code that matches your project's style, not generic examples |
64
+ | ② *"Write a user registration endpoint"* | Generated code automatically follows the API conventions you just looked up |
65
+ | ③ *"Check if this file follows the project conventions"* | Pre-commit convention check — fewer round-trips in Code Review |
66
+ | ④ *"Save this error handling as a project convention"* | One save, and everyone's AI writes it this way from now on |
67
+
68
+ After the Agent writes code, the Guard compliance engine automatically checks the diff — violations are self-repaired without you lifting a finger.
69
+
70
+ ### It gets better over time
71
+
72
+ Review candidates in Dashboard (`asd ui`) → approve as **Recipe** → AI follows your conventions → you spot a good new pattern → save it → AI gets even better at writing code your team's way. Recipes are local Markdown files, tracked by git, never lost between conversations. AI queries them on demand without filling the context window — your knowledge base can grow without slowing AI down.
73
+
74
+ ## More Capabilities
75
+
76
+ ### Guard Compliance Engine
77
+
78
+ Beyond the Agent's automatic checks, Guard also plugs into your engineering workflow:
79
+
80
+ ```bash
81
+ asd guard src/ # Check a directory
82
+ asd guard:staged # Pre-commit: only staged files
83
+ asd guard:ci --threshold 90 # CI quality gate
46
84
  ```
47
- asd setup → asd coldstart → Dashboard review → IDE AI consumes Recipes → write code → asd ais rescan → loop
48
- ```
49
85
 
50
- 1. **`asd setup`** Creates workspace, SQLite DB, MCP configs, installs VS Code extension.
51
- 2. **`asd coldstart`** — Multi-angle codebase scan, produces **Candidates**.
52
- 3. **Review in Dashboard** — Approve, edit, or reject. Approved → Recipe.
53
- 4. **IDE picks them up** — Via MCP, Cursor Rules, Agent Skills, or TaskGraph task context.
54
- 5. **Keep going** `asd ais <target>` for targeted scans, or describe what you want in Cursor.
86
+ Built-in multi-language compliance rules (regex + AST) checking naming, deprecated APIs, thread safety, and more each violation comes with a fix example.
87
+
88
+ ### Call Graph
89
+
90
+ Want to know the blast radius before refactoring a function? Static call graph analysis across 8 languages — query any function's callers, callees, and impact radius via MCP tools `call_graph` and `call_context`.
91
+
92
+ ### Semantic Search
93
+
94
+ Keyword search only finds literal matches. With an LLM API Key, search upgrades to vector + BM25 hybrid retrieval — asking "how to manage memory" finds Recipes about garbage collection, semantically similar results rank first.
95
+
96
+ ### Knowledge Graph
55
97
 
56
- ## Dual PipelineInternal Agent & External Agent
98
+ Recipes have relationships. Query impact paths, dependency depth, and related Recipes for any module once you've accumulated enough knowledge, it helps you see the structure behind it.
57
99
 
58
- Every core capability works through two fully independent pipelines. Pick whichever fits your setup — or use both:
100
+ ### TaskGraph Orchestration
59
101
 
60
- | Capability | Internal Agent (built-in AI) | External Agent (IDE-driven) |
61
- |---|---|---|
62
- | **Cold Start** | Analyst/Producer dual-agent auto-scan | IDE agent reads Mission Briefing + MCP tools |
63
- | **Knowledge Extraction** | `asd ais` → built-in AI pipeline | Cursor/Copilot calls `submit_with_check` |
64
- | **Project Skills** | Auto-generated from analysis text | IDE agent calls `autosnippet_skill(create)` |
65
- | **Repo Wiki** | Auto-generated at end of cold start | IDE agent calls wiki MCP tools |
66
- | **Guard** | Built-in rule engine (no AI needed) | Same — shared infrastructure |
67
- | **Search & Retrieval** | MCP server serves results | Same — shared infrastructure |
68
- | **Requires** | AI provider API key | IDE with agent capabilities |
102
+ Break a large task into steps, declare dependencies between them, and each step auto-injects relevant Recipes as context. Team decisions (rationale, confidence) persist alongside tasks — they don't vanish with the conversation.
69
103
 
70
- If no AI is available at all, a rule-based fallback still extracts basic knowledge from AST and Guard data.
104
+ ### Self-Cycling Signal Mechanism
71
105
 
72
- > **LLM quality matters.** Higher-capability models (Claude Opus 4 / Sonnet 4, GPT-5, Gemini 3 Pro) produce significantly better resultsmore accurate patterns, richer architectural insights, fewer false positives.
106
+ AutoSnippet quietly collects your coding habit signals in the background (Guard violations, conversation topics, Recipe usage, candidate backlog, operation logs, git diff), and AI mines patterns to recommend Skills. Don't like one? Delete it zero commitment. But if a recommendation happens to nail a team habit you never wrote down — that's a freebie. Your adopt/dismiss actions feed back into the algorithm, making recommendations more precise over time.
107
+
108
+ ### Lark Remote Programming
109
+
110
+ Send a message on Lark (Feishu) from your phone — intent recognition auto-routes it to your local IDE, Copilot Agent Mode executes, results sent back to Lark. Refactor, screenshot, look up conventions — you don't need to be near your computer, as long as it's not asleep.
111
+
112
+ ### Recipe Remote Repository
113
+
114
+ `asd remote <url>` converts your knowledge base directory into an independent git sub-repository. Share Recipes across projects with separate access control, unified management, and version tracking.
115
+
116
+ > Semantic search, signal recommendations, Lark remote, and other AI-driven features require an LLM API Key. Set it up in the Dashboard's LLM Config panel, or add it to your `.env` — supports Google / OpenAI / Claude / DeepSeek / Ollama, with auto-fallback.
73
117
 
74
118
  ## Dashboard
75
119
 
@@ -79,17 +123,6 @@ Run `asd ui` to manage everything in one place:
79
123
  <img src="docs/images/dashboard-help-en.png" alt="Dashboard Help" width="800" />
80
124
  </div>
81
125
 
82
- ## Features
83
-
84
- | Feature | Description |
85
- |---------|-------------|
86
- | **Pattern Extraction** | AI reads code → identifies reusable patterns → structures as Recipe. 9 languages (Tree-sitter AST) |
87
- | **Search** | BM25 keyword → semantic rerank → quality score → multi-signal ranking. Chinese & English |
88
- | **Guard** | Regex + AST compliance rules. `asd guard:ci` for CI, `asd guard:staged` for pre-commit |
89
- | **CallGraph** | Static call graph analysis across 8 languages. MCP `call_graph` + `call_context` |
90
- | **TaskGraph** | DAG task orchestration + tokenBudget-aware + persistent team decisions |
91
- | **AI Providers** | Gemini, OpenAI, Claude, DeepSeek, Ollama, with auto-fallback |
92
-
93
126
  ## IDE Support
94
127
 
95
128
  | IDE | Integration | How it connects |
@@ -103,36 +136,6 @@ Run `asd ui` to manage everything in one place:
103
136
 
104
137
  All configs generated by `asd setup`. Run `asd upgrade` to refresh after updates.
105
138
 
106
- ## File Directives
107
-
108
- Write these in any source file:
109
-
110
- ```
111
- // as:s network timeout Search recipes and insert the match
112
- // as:c Create a candidate from surrounding code
113
- // as:a Run Guard audit on this file
114
- ```
115
-
116
- The VS Code extension and `asd watch` (Xcode) pick these up automatically.
117
-
118
- ## CLI
119
-
120
- | Command | What it does |
121
- |---------|-------------|
122
- | `asd setup` | Init workspace, DB, IDE configs |
123
- | `asd coldstart` | Full codebase scan → candidates |
124
- | `asd ais [target]` | Scan a specific module |
125
- | `asd ui` | Dashboard + API server |
126
- | `asd search <query>` | Search knowledge base |
127
- | `asd guard <file>` | Run compliance check |
128
- | `asd guard:ci` | CI mode with quality gate |
129
- | `asd guard:staged` | Pre-commit hook |
130
- | `asd watch` | Xcode file watcher |
131
- | `asd sync` | Sync recipe markdown → DB |
132
- | `asd task` | Task management (TaskGraph) |
133
- | `asd upgrade` | Update IDE integrations |
134
- | `asd status` | Health check |
135
-
136
139
  ## Project Structure
137
140
 
138
141
  After `asd setup`, your project gets:
@@ -152,47 +155,13 @@ your-project/
152
155
 
153
156
  Recipes are Markdown files. SQLite is a read cache. If the DB breaks, `asd sync` rebuilds it.
154
157
 
155
- ## Remote Programming via Lark
156
-
157
- Code from your phone. Send messages in Lark (Feishu) → they get injected into VS Code Copilot Agent Mode → results sent back to Lark. Task notifications with IDE screenshots are pushed back automatically.
158
-
159
- See [Lark Integration Guide](docs/lark-integration.en.md) for setup instructions.
160
-
161
- ## Configuration
158
+ ## Configuration Details
162
159
 
163
- Put a `.env` in your project root, or use Dashboard → LLM Config:
164
-
165
- ```env
166
- # Pick one (multiple = auto-fallback)
167
- ASD_GOOGLE_API_KEY=...
168
- ASD_OPENAI_API_KEY=...
169
- ASD_CLAUDE_API_KEY=...
170
- ASD_DEEPSEEK_API_KEY=...
171
-
172
- # Or run local
173
- ASD_AI_PROVIDER=ollama
174
- ASD_AI_MODEL=llama3
175
- ```
160
+ See [Configuration Guide](docs/configuration.en.md) for more LLM configuration options.
176
161
 
177
162
  ## Architecture
178
163
 
179
- ```
180
- IDE Layer Cursor · VS Code · Trae · Qoder · Xcode · Dashboard · Lark
181
-
182
- MCP Server (22 tools) + HTTP API
183
-
184
- Agent Layer AgentRouter → Preset → AgentRuntime (ReAct loop)
185
- ├── Strategy: Single / Pipeline / FanOut / Adaptive
186
- ├── Capability: Conversation · CodeAnalysis · KnowledgeProduction · System
187
- ├── Policy: Budget · Safety · QualityGate
188
- └── Memory: ActiveContext → SessionStore → PersistentMemory
189
-
190
- Service Layer Search · Knowledge · Guard · Chat · Bootstrap · Wiki · TaskGraph
191
-
192
- Core Layer AST (9 lang) · CallGraph (8 lang) · KnowledgeGraph · RetrievalFunnel · QualityScorer
193
-
194
- Infrastructure SQLite · VectorStore · EventBus · AuditLog · DI Container (40+) · ContextWindow
195
- ```
164
+ See [Architecture Documentation](docs/architecture.en.md) for the full system design.
196
165
 
197
166
  ## Requirements
198
167
 
@@ -79,7 +79,7 @@ Skill 文档格式要求:
79
79
  `):""}function Zo(t){return t==null?{ring:"stroke-slate-200",text:"text-[var(--fg-muted)]",bg:"bg-[var(--bg-subtle)]",labelKey:""}:t>=.8?{ring:"stroke-emerald-500",text:"text-emerald-700",bg:"bg-emerald-50",labelKey:"candidates.confidenceHighLabel"}:t>=.6?{ring:"stroke-blue-500",text:"text-blue-700",bg:"bg-blue-50",labelKey:"candidates.confidenceMediumLabel"}:t>=.4?{ring:"stroke-amber-500",text:"text-amber-700",bg:"bg-amber-50",labelKey:"candidates.confidenceMediumLowLabel"}:{ring:"stroke-red-500",text:"text-red-700",bg:"bg-red-50",labelKey:"candidates.confidenceLowLabel"}}const Ra={"bootstrap-scan":{labelKey:"candidates.sourceAiScanLabel",color:"text-violet-600 bg-violet-50 border-violet-200"},mcp:{labelKey:"candidates.sourceMcpLabel",color:"text-blue-600 bg-blue-50 border-blue-200"},manual:{labelKey:"candidates.sourceManualLabel",color:"text-emerald-600 bg-emerald-50 border-emerald-200"},"file-watcher":{labelKey:"candidates.sourceFileWatcherLabel",color:"text-orange-600 bg-orange-50 border-orange-200"},clipboard:{labelKey:"candidates.sourceClipboardLabel",color:"text-pink-600 bg-pink-50 border-pink-200"},cli:{labelKey:"CLI",color:"text-[var(--fg-secondary)] bg-[var(--bg-subtle)] border-[var(--border-default)]"},agent:{labelKey:"AI Agent",color:"text-violet-600 bg-violet-50 border-violet-200"},submit_with_check:{labelKey:"candidates.sourceSubmitCheckLabel",color:"text-teal-600 bg-teal-50 border-teal-200"},"bootstrap-fallback":{labelKey:"candidates.sourceFallbackLabel",color:"text-amber-600 bg-amber-50 border-amber-200"}},ei=({value:t,size:s=36})=>{const a=(s-6)/2,r=2*Math.PI*a,i=t!=null?Math.max(0,Math.min(1,t)):0,o=r*(1-i),{ring:u,text:p}=Zo(t);return e.jsxs("div",{className:"relative flex items-center justify-center",style:{width:s,height:s},children:[e.jsxs("svg",{width:s,height:s,className:"-rotate-90",children:[e.jsx("circle",{cx:s/2,cy:s/2,r:a,fill:"none",stroke:"currentColor",strokeWidth:3,className:"text-[var(--border-default)]"}),e.jsx("circle",{cx:s/2,cy:s/2,r:a,fill:"none",strokeWidth:3,strokeLinecap:"round",className:u,strokeDasharray:r,strokeDashoffset:o,style:{transition:"stroke-dashoffset 0.5s ease"}})]}),e.jsx("span",{className:`absolute text-[9px] font-bold ${p}`,children:t!=null?`${Math.round(t*100)}`:"—"})]})},ti=({data:t,isShellTarget:s,isSilentTarget:a=()=>!1,isPendingTarget:r=()=>!1,handleDeleteCandidate:i,handleDeleteAllInTarget:o,onAuditCandidate:u,onAuditAllInTarget:p,onEditRecipe:c,onColdStart:x,isScanning:h,isBootstrapping:g,onRefresh:d})=>{const{t:l}=Ae(),[f,y]=n.useState(null),{isWide:D,toggle:S}=da(),[T,z]=n.useState(new Set),[O]=n.useState(new Set),[G,le]=n.useState(!1),[w]=n.useState(!1),k=ns(),{refine:I,isRefining:q,isRefineDone:W,resetRefine:K}=Jo(),[C,v]=n.useState({}),[_,ae]=n.useState(null),[Q,me]=n.useState({}),[Se,ye]=n.useState(null),[j,N]=n.useState({}),[P,V]=n.useState({sort:"default",onlySimilar:!1}),[ne,ue]=n.useState(null),pe=n.useRef(new Set),Ne=n.useCallback(async(J,U)=>{if(!pe.current.has(U)){pe.current.add(U),ye(U);try{const m=await ee.getCandidateSimilarityEx({targetName:J,candidateId:U});me(b=>({...b,[U]:m.similar||[]}))}catch{me(b=>({...b,[U]:[]}))}finally{ye(null)}}},[]),De=n.useCallback(async(J,U,m,b=[])=>{const B=m.replace(/\.md$/i,"");let F="";const $=t?.recipes?.find(te=>te.name===B||te.name.endsWith("/"+B));if($?.content)F=[$.content.pattern,$.content.markdown].filter(Boolean).join(`
80
80
 
81
81
  `)||"";else try{F=(await ee.getRecipeContentByName(B)).content}catch(te){const fe=na(te),je=ve(te);fe===404?Z(`"${B}" ${l("common.operationFailed")}`,{title:l("common.operationFailed"),type:"error"}):Z(je,{title:l("common.loadFailed"),type:"error"});return}const E={[B]:F};y(J.id),ue({candidate:J,targetName:U,recipeName:B,recipeContent:F,similarList:b.slice(0,3),recipeContents:E})},[t?.recipes]),ke=t?.candidates?Object.entries(t.candidates):[],Me=Qo(ke,s,a,r),M=Me.map(([J])=>J),A=_&&M.includes(_)?_:M[0]??null;n.useEffect(()=>{M.length>0&&(!_||!M.includes(_))&&ae(M[0])},[M.join(","),_]),n.useEffect(()=>{f&&A&&Ne(A,f)},[f,A,Ne]);const L=n.useMemo(()=>{if(!A||!t?.candidates?.[A])return null;const J=t.candidates[A].items,U=J.length,m=J.reduce((F,$)=>F+($.reasoning?.confidence??0),0)/(U||1),b=J.filter(F=>F.content?.pattern&&F.content.pattern.trim().length>0||F.coreCode&&F.coreCode.trim().length>0).length,B=new Map;return J.forEach(F=>{const $=F.source||"unknown";B.set($,(B.get($)||0)+1)}),{total:U,avgConfidence:m,withCode:b,sources:B}},[A,t?.candidates]),oe=n.useMemo(()=>{const J=new Map;if(t?.idTitleMap)for(const[U,m]of Object.entries(t.idTitleMap))J.set(U,m);if(t?.candidates)for(const U of Object.values(t.candidates))for(const m of U.items)m.id&&m.title&&J.set(m.id,m.title);if(t?.recipes)for(const U of t.recipes)U.id&&U.name&&J.set(U.id,U.name.replace(/\.md$/i,""));return J},[t?.idTitleMap,t?.candidates,t?.recipes]),be=n.useCallback(async J=>{if(!T.has(J)){z(U=>new Set(U).add(J));try{const U=await ee.enrichCandidates([J]);U.enriched>0?Z(`${U.results?.[0]?.filledFields?.length||0} ${l("candidates.approveSuccess")}`,{title:l("candidates.aiRefine")}):Z(l("recipes.noContent"),{title:l("candidates.aiRefine"),type:"info"});try{const m=await ee.getCandidate(J);N(b=>({...b,[J]:m}))}catch{}}catch(U){Z(ve(U,l("common.operationFailed")),{title:l("common.operationFailed"),type:"error"})}finally{z(U=>{const m=new Set(U);return m.delete(J),m})}}},[T,d]),Te=n.useCallback(async()=>{if(G||!A||!t?.candidates?.[A])return;const J=t.candidates[A].items;if(J.length!==0){le(!0);try{let U=0;for(let m=0;m<J.length;m+=20){const b=J.slice(m,m+20).map(F=>F.id),B=await ee.enrichCandidates(b);U+=B.enriched}Z(`${U}/${J.length} ${l("candidates.batchDeleteDone",{count:U})}`,{title:l("candidates.aiRefine")}),d?.()}catch(U){Z(ve(U,l("common.operationFailed")),{title:l("common.operationFailed"),type:"error"})}finally{le(!1)}}},[G,A,t?.candidates,d]),ce=n.useCallback(async J=>{try{const U=await ee.getCandidate(J);N(m=>({...m,[J]:U}))}catch{}},[]),ge=n.useCallback(()=>{if(!A||!t?.candidates?.[A])return;const J=t.candidates[A].items,U=J.map(m=>m.id);k.openRefine({candidateIds:U,candidates:J,onCandidateUpdated:ce})},[A,t?.candidates,k,ce]),Ee=n.useCallback(J=>{if(!A||!t?.candidates?.[A])return;ue(null),y(J);const U=t.candidates[A].items;k.openRefine({candidateIds:[J],candidates:U,onCandidateUpdated:ce})},[A,t?.candidates,k,ce]);return e.jsxs("div",{className:"flex-1 flex flex-col overflow-hidden",children:[e.jsxs("div",{className:"mb-4 flex flex-wrap justify-between items-center gap-3 shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-3 min-w-0",children:[e.jsx("div",{className:"w-10 h-10 rounded-xl bg-blue-50 border border-blue-100 flex items-center justify-center shrink-0",children:e.jsx(He,{className:"text-blue-600",size:20})}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("h2",{className:"text-lg xl:text-xl font-bold text-[var(--fg-primary)]",children:"AI Scan Candidates"}),e.jsx("p",{className:"text-xs text-[var(--fg-muted)] mt-0.5 truncate",children:l("candidates.title")})]})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[x&&!g&&e.jsxs("button",{onClick:x,disabled:h,className:`flex items-center gap-1.5 px-3.5 py-2 rounded-lg text-xs font-bold transition-all ${h?"text-[var(--fg-muted)] bg-[var(--bg-subtle)] cursor-not-allowed":"text-white bg-gradient-to-r from-violet-500 to-purple-600 hover:from-violet-600 hover:to-purple-700 shadow-sm hover:shadow"}`,title:l("candidates.coldStartTitle"),children:[h?e.jsx(Ce,{size:14,className:"animate-spin"}):e.jsx(Zt,{size:14}),l(h?"common.loading":"candidates.sourceBootstrap")]}),L&&L.total>0&&e.jsxs("button",{onClick:Te,disabled:G||w,className:`flex items-center gap-1.5 px-3 py-2 rounded-lg text-xs font-bold transition-all ${G||w?"text-[var(--fg-muted)] bg-[var(--bg-subtle)] cursor-not-allowed":"text-amber-700 bg-amber-50 border border-amber-200 hover:bg-amber-100"}`,title:l("candidates.enrichTitle"),children:[G?e.jsx(Ce,{size:14,className:"animate-spin"}):e.jsx(gs,{size:14}),l(G?"common.loading":"candidates.aiEnrich")]}),L&&L.total>0&&e.jsxs("button",{onClick:ge,disabled:w||G||q,className:`flex items-center gap-1.5 px-3 py-2 rounded-lg text-xs font-bold transition-all ${w||G||q?"text-[var(--fg-muted)] bg-[var(--bg-subtle)] cursor-not-allowed":"text-emerald-700 bg-emerald-50 border border-emerald-200 hover:bg-emerald-100"}`,title:l("candidates.refineTitle"),children:[w||q?e.jsx(Ce,{size:14,className:"animate-spin"}):e.jsx(He,{size:14}),l(w||q?"common.loading":"candidates.aiRefine")]}),L&&e.jsxs("div",{className:"flex items-center gap-3 text-xs",children:[e.jsxs("div",{className:"flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-[var(--bg-subtle)] border border-[var(--border-default)]",children:[e.jsx(mr,{size:14,className:"text-[var(--fg-muted)]"}),e.jsx("span",{className:"text-[var(--fg-secondary)]",children:l("candidates.totalCount",{count:L.total})}),L.withCode<L.total&&e.jsx("span",{className:"text-[var(--fg-muted)] ml-1",children:l("candidates.withCode",{count:L.withCode})})]}),e.jsxs("div",{className:"flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-emerald-50 border border-emerald-100",children:[e.jsx("span",{className:"text-emerald-500",children:l("candidates.confidence")}),e.jsxs("strong",{className:"text-emerald-700",children:[Math.round(L.avgConfidence*100),"%"]})]})]})]})]}),I&&e.jsx(Yo,{refine:I,isRefineDone:W,onDismiss:()=>{K(),d?.()}}),ke.length>0&&e.jsx("div",{className:"shrink-0 bg-[var(--bg-surface)] border border-[var(--border-default)] rounded-xl px-3 py-2 mb-4 shadow-sm",children:e.jsx("div",{className:"flex items-center gap-1.5 overflow-x-auto no-scrollbar",children:M.map(J=>{const U=a(J),m=us[J]?l(us[J]):void 0,B=t?.candidates[J]?.items?.length??0,F=A===J,$=it[J]||it.All;return e.jsxs("button",{onClick:()=>ae(J),className:`flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-bold whitespace-nowrap transition-all border
82
- ${F?`${$?.bg||"bg-blue-50"} ${$?.color||"text-blue-700"} ${$?.border||"border-blue-200"} shadow-sm ring-1 ring-inset ${$?.border||"ring-blue-200"}`:"bg-[var(--bg-subtle)] text-[var(--fg-secondary)] border-[var(--border-default)] hover:border-[var(--border-emphasis)] hover:bg-[var(--bg-subtle)]"}`,children:[(()=>{const E=$?.icon||js;return e.jsx(E,{size:H.sm,className:F?"":"text-[var(--fg-muted)]"})})(),e.jsx("span",{children:ps[J]?l(ps[J]):J}),U&&m&&e.jsx("span",{className:"text-[9px] text-amber-600 border border-amber-200 px-1 rounded",children:m}),e.jsx("span",{className:`text-[10px] font-normal rounded-full px-1.5 ${F?"bg-white/60":"bg-[var(--bg-subtle)] text-[var(--fg-muted)]"}`,children:B})]},J)})})}),e.jsxs("div",{className:"flex-1 overflow-y-auto pr-1 pb-6",children:[(!t?.candidates||Object.keys(t.candidates).length===0)&&!g&&e.jsxs("div",{className:"h-72 flex flex-col items-center justify-center bg-[var(--bg-surface)] rounded-2xl border border-dashed border-[var(--border-default)] text-[var(--fg-muted)]",children:[e.jsx("div",{className:"w-16 h-16 rounded-2xl bg-[var(--bg-subtle)] flex items-center justify-center mb-4",children:e.jsx(Ks,{size:32,className:"text-[var(--fg-muted)]"})}),e.jsx("p",{className:"text-sm font-medium text-[var(--fg-secondary)]",children:l("candidates.noResults")}),e.jsx("p",{className:"mt-2 text-xs max-w-sm text-center leading-relaxed text-[var(--fg-muted)]",children:l("candidates.emptyHint")}),x&&e.jsxs("button",{onClick:x,disabled:h,className:`mt-4 flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-bold transition-all ${h?"text-[var(--fg-muted)] bg-[var(--bg-subtle)] cursor-not-allowed":"text-white bg-gradient-to-r from-violet-500 to-purple-600 hover:from-violet-600 hover:to-purple-700 shadow-md hover:shadow-lg"}`,children:[h?e.jsx(Ce,{size:16,className:"animate-spin"}):e.jsx(Zt,{size:16}),l(h?"common.loading":"candidates.sourceBootstrap")]}),e.jsxs("p",{className:"mt-3 text-[11px] text-[var(--fg-muted)]",children:[" ",e.jsx("code",{className:"text-blue-600 bg-blue-50 px-1 rounded",children:"asd ais --all"})," ",l("candidates.fullScanBtn"),e.jsx("code",{className:"text-blue-600 bg-blue-50 px-1 rounded ml-1",children:"asd candidate"})," ",l("candidates.clipboardCreate")]})]}),(!t?.candidates||Object.keys(t.candidates).length===0)&&g&&e.jsxs("div",{className:"h-72 flex flex-col items-center justify-center bg-[var(--bg-surface)] rounded-2xl border border-dashed border-violet-500/30 text-[var(--fg-muted)]",children:[e.jsx("div",{className:"w-16 h-16 rounded-2xl bg-violet-500/10 flex items-center justify-center mb-4",children:e.jsx(Ce,{size:32,className:"text-violet-400 animate-spin"})}),e.jsx("p",{className:"text-sm font-medium text-violet-400",children:l("common.loading")}),e.jsx("p",{className:"mt-2 text-xs max-w-sm text-center leading-relaxed text-[var(--fg-muted)]",children:l("candidates.scanningHint")})]}),t&&A&&Me.filter(([J])=>J===A).map(([J,U])=>{const m=s(J),b=a(J),B=us[J]?l(us[J]):l("candidates.silent"),F=C[J]||{page:1,pageSize:12},$=F.page,E=F.pageSize,te=U.items.filter(Y=>{if(P.onlySimilar){const _e=Q[Y.id];if(!Array.isArray(_e)||_e.length===0)return!1}return!0}).sort((Y,_e)=>{if(P.sort==="default")return 0;if(P.sort==="score-desc")return(_e.quality?.overall??0)-(Y.quality?.overall??0);if(P.sort==="score-asc")return(Y.quality?.overall??0)-(_e.quality?.overall??0);if(P.sort==="confidence-desc")return(_e.reasoning?.confidence??0)-(Y.reasoning?.confidence??0);if(P.sort==="date-desc"){const dt=typeof Y.createdAt=="number"?Y.createdAt:0;return(typeof _e.createdAt=="number"?_e.createdAt:0)-dt}return 0}),fe=te.length,je=Math.ceil(fe/E),Pe=($-1)*E,Le=te.slice(Pe,Pe+E),de=Y=>{v(_e=>({..._e,[J]:{...F,page:Y}}))},Oe=Y=>{v(_e=>({..._e,[J]:{page:1,pageSize:Y}}))},Be=it[J]||it.All;return e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-3 px-4 py-2.5 rounded-xl bg-[var(--bg-surface)] border border-[var(--border-default)] shadow-sm",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:[(()=>{const Y=Be?.icon||js;return e.jsx(Y,{size:18,className:Be?.color||"text-blue-600"})})(),e.jsx("span",{className:"text-base font-bold text-[var(--fg-primary)] truncate",children:ps[J]?l(ps[J]):J}),b&&e.jsx("span",{className:"text-[10px] font-bold text-amber-600 border border-amber-200 bg-amber-50 px-1.5 py-0.5 rounded",children:B}),m&&!b&&e.jsx("span",{className:"text-[10px] font-bold text-[var(--fg-muted)] border border-[var(--border-default)] bg-[var(--bg-subtle)] px-1.5 py-0.5 rounded",children:"SHELL"}),e.jsxs("span",{className:"text-[11px] text-[var(--fg-muted)] flex items-center gap-1",children:[e.jsx(tt,{size:11}),l("candidates.scannedAt",{time:Vt(U.scanTime,l)||new Date(U.scanTime).toLocaleString()})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("div",{className:"flex items-center gap-1 px-2 py-1 rounded-lg bg-[var(--bg-subtle)] border border-[var(--border-default)]",children:[e.jsx(Ln,{size:12,className:"text-[var(--fg-muted)]"}),e.jsx(Ze,{value:P.sort,onChange:Y=>V(_e=>({..._e,sort:Y})),options:[{value:"default",label:l("candidates.sortNewest")},{value:"score-desc",label:`${l("candidates.sortConfidence")} ↓`},{value:"score-asc",label:`${l("candidates.sortConfidence")} ↑`},{value:"confidence-desc",label:`${l("candidates.confidence")} ↓`},{value:"date-desc",label:l("candidates.sortOldest")}],size:"xs",className:"border-none bg-transparent"})]}),e.jsxs("label",{className:"text-[11px] font-medium text-[var(--fg-secondary)] flex items-center gap-1.5 px-2 py-1 rounded-lg bg-[var(--bg-subtle)] border border-[var(--border-default)] cursor-pointer hover:bg-[var(--bg-subtle)] transition-colors select-none",children:[e.jsx("input",{type:"checkbox",checked:P.onlySimilar,onChange:Y=>V(_e=>({..._e,onlySimilar:Y.target.checked})),className:"rounded text-blue-600 w-3 h-3"}),l("candidates.similarOnly")]}),(P.sort!=="default"||P.onlySimilar)&&e.jsx("button",{onClick:()=>V({sort:"default",onlySimilar:!1}),className:"text-[11px] font-medium text-[var(--fg-secondary)] hover:text-[var(--fg-primary)] px-2 py-1 rounded-lg border border-[var(--border-default)] bg-[var(--bg-surface)] hover:bg-[var(--bg-subtle)] transition-colors",children:l("candidates.resetFilters")})]}),e.jsx("div",{className:"h-5 w-px bg-[var(--border-default)]"}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-[11px] text-[var(--fg-muted)] font-medium",children:l("candidates.totalCount",{count:fe})}),e.jsx("button",{onClick:()=>p(Le,J),className:"text-[11px] font-bold text-blue-600 hover:text-blue-700 px-2.5 py-1.5 rounded-lg hover:bg-blue-50 transition-colors",children:l("candidates.approveCurrentPage")}),e.jsx("button",{onClick:async()=>{if(!window.confirm(l("candidates.batchDeleteConfirm",{count:Le.length})))return;const _e=(await Promise.allSettled(Le.map(dt=>i(J,dt.id)))).filter(dt=>dt.status==="rejected").length;_e>0&&Z(`${_e} ${l("common.deleteFailed")}`,{title:l("common.operationFailed"),type:"error"}),d?.()},className:"text-[11px] font-bold text-orange-500 hover:text-orange-600 px-2.5 py-1.5 rounded-lg hover:bg-orange-50 transition-colors",children:l("candidates.removeCurrentPage")}),e.jsx("button",{onClick:()=>o(J),className:"text-[11px] font-bold text-red-500 hover:text-red-600 px-2.5 py-1.5 rounded-lg hover:bg-red-50 transition-colors border border-red-200",children:l("candidates.deleteAll")})]})]}),e.jsx("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-3",children:Le.map(Y=>{const _e=f===Y.id,dt=Y.reasoning?.confidence??null,bt=(Y.quality?.overall??0)>0?Y.quality?.overall??null:null,zt=Q[Y.id]||[],Re=zt[0]||null,nt=Ra[Y.source||""]||{labelKey:Y.source||"",color:"text-[var(--fg-secondary)] bg-[var(--bg-subtle)] border-[var(--border-default)]"},Xe=it[Y.category||""]||it.All||{};return e.jsxs("div",{onClick:()=>y(_e?null:Y.id),className:`bg-[var(--bg-surface)] rounded-xl border overflow-hidden hover:shadow-lg transition-all duration-200 flex flex-col group cursor-pointer
82
+ ${F?`${$?.bg||"bg-blue-50"} ${$?.color||"text-blue-700"} ${$?.border||"border-blue-200"} shadow-sm ring-1 ring-inset ${$?.border||"ring-blue-200"}`:"bg-[var(--bg-subtle)] text-[var(--fg-secondary)] border-[var(--border-default)] hover:border-[var(--border-emphasis)] hover:bg-[var(--bg-subtle)]"}`,children:[(()=>{const E=$?.icon||js;return e.jsx(E,{size:H.sm,className:F?"":"text-[var(--fg-muted)]"})})(),e.jsx("span",{children:ps[J]?l(ps[J]):J}),U&&m&&e.jsx("span",{className:"text-[9px] text-amber-600 border border-amber-200 px-1 rounded",children:m}),e.jsx("span",{className:`text-[10px] font-normal rounded-full px-1.5 ${F?"bg-white/60":"bg-[var(--bg-subtle)] text-[var(--fg-muted)]"}`,children:B})]},J)})})}),e.jsxs("div",{className:"flex-1 overflow-y-auto pr-1 pb-6",children:[(!t?.candidates||Object.keys(t.candidates).length===0)&&!g&&e.jsxs("div",{className:"h-72 flex flex-col items-center justify-center bg-[var(--bg-surface)] rounded-2xl border border-dashed border-[var(--border-default)] text-[var(--fg-muted)]",children:[e.jsx("div",{className:"w-16 h-16 rounded-2xl bg-[var(--bg-subtle)] flex items-center justify-center mb-4",children:e.jsx(Ks,{size:32,className:"text-[var(--fg-muted)]"})}),e.jsx("p",{className:"text-sm font-medium text-[var(--fg-secondary)]",children:l("candidates.noResults")}),e.jsx("p",{className:"mt-2 text-xs max-w-sm text-center leading-relaxed text-[var(--fg-muted)]",children:l("candidates.emptyHint")}),x&&e.jsxs("button",{onClick:x,disabled:h,className:`mt-4 flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-bold transition-all ${h?"text-[var(--fg-muted)] bg-[var(--bg-subtle)] cursor-not-allowed":"text-white bg-gradient-to-r from-violet-500 to-purple-600 hover:from-violet-600 hover:to-purple-700 shadow-md hover:shadow-lg"}`,children:[h?e.jsx(Ce,{size:16,className:"animate-spin"}):e.jsx(Zt,{size:16}),l(h?"common.loading":"candidates.sourceBootstrap")]}),e.jsx("p",{className:"mt-3 text-[11px] text-[var(--fg-muted)]",children:"或在 IDE Agent Mode 中说「帮我冷启动」"})]}),(!t?.candidates||Object.keys(t.candidates).length===0)&&g&&e.jsxs("div",{className:"h-72 flex flex-col items-center justify-center bg-[var(--bg-surface)] rounded-2xl border border-dashed border-violet-500/30 text-[var(--fg-muted)]",children:[e.jsx("div",{className:"w-16 h-16 rounded-2xl bg-violet-500/10 flex items-center justify-center mb-4",children:e.jsx(Ce,{size:32,className:"text-violet-400 animate-spin"})}),e.jsx("p",{className:"text-sm font-medium text-violet-400",children:l("common.loading")}),e.jsx("p",{className:"mt-2 text-xs max-w-sm text-center leading-relaxed text-[var(--fg-muted)]",children:l("candidates.scanningHint")})]}),t&&A&&Me.filter(([J])=>J===A).map(([J,U])=>{const m=s(J),b=a(J),B=us[J]?l(us[J]):l("candidates.silent"),F=C[J]||{page:1,pageSize:12},$=F.page,E=F.pageSize,te=U.items.filter(Y=>{if(P.onlySimilar){const _e=Q[Y.id];if(!Array.isArray(_e)||_e.length===0)return!1}return!0}).sort((Y,_e)=>{if(P.sort==="default")return 0;if(P.sort==="score-desc")return(_e.quality?.overall??0)-(Y.quality?.overall??0);if(P.sort==="score-asc")return(Y.quality?.overall??0)-(_e.quality?.overall??0);if(P.sort==="confidence-desc")return(_e.reasoning?.confidence??0)-(Y.reasoning?.confidence??0);if(P.sort==="date-desc"){const dt=typeof Y.createdAt=="number"?Y.createdAt:0;return(typeof _e.createdAt=="number"?_e.createdAt:0)-dt}return 0}),fe=te.length,je=Math.ceil(fe/E),Pe=($-1)*E,Le=te.slice(Pe,Pe+E),de=Y=>{v(_e=>({..._e,[J]:{...F,page:Y}}))},Oe=Y=>{v(_e=>({..._e,[J]:{page:1,pageSize:Y}}))},Be=it[J]||it.All;return e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-3 px-4 py-2.5 rounded-xl bg-[var(--bg-surface)] border border-[var(--border-default)] shadow-sm",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:[(()=>{const Y=Be?.icon||js;return e.jsx(Y,{size:18,className:Be?.color||"text-blue-600"})})(),e.jsx("span",{className:"text-base font-bold text-[var(--fg-primary)] truncate",children:ps[J]?l(ps[J]):J}),b&&e.jsx("span",{className:"text-[10px] font-bold text-amber-600 border border-amber-200 bg-amber-50 px-1.5 py-0.5 rounded",children:B}),m&&!b&&e.jsx("span",{className:"text-[10px] font-bold text-[var(--fg-muted)] border border-[var(--border-default)] bg-[var(--bg-subtle)] px-1.5 py-0.5 rounded",children:"SHELL"}),e.jsxs("span",{className:"text-[11px] text-[var(--fg-muted)] flex items-center gap-1",children:[e.jsx(tt,{size:11}),l("candidates.scannedAt",{time:Vt(U.scanTime,l)||new Date(U.scanTime).toLocaleString()})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("div",{className:"flex items-center gap-1 px-2 py-1 rounded-lg bg-[var(--bg-subtle)] border border-[var(--border-default)]",children:[e.jsx(Ln,{size:12,className:"text-[var(--fg-muted)]"}),e.jsx(Ze,{value:P.sort,onChange:Y=>V(_e=>({..._e,sort:Y})),options:[{value:"default",label:l("candidates.sortNewest")},{value:"score-desc",label:`${l("candidates.sortConfidence")} ↓`},{value:"score-asc",label:`${l("candidates.sortConfidence")} ↑`},{value:"confidence-desc",label:`${l("candidates.confidence")} ↓`},{value:"date-desc",label:l("candidates.sortOldest")}],size:"xs",className:"border-none bg-transparent"})]}),e.jsxs("label",{className:"text-[11px] font-medium text-[var(--fg-secondary)] flex items-center gap-1.5 px-2 py-1 rounded-lg bg-[var(--bg-subtle)] border border-[var(--border-default)] cursor-pointer hover:bg-[var(--bg-subtle)] transition-colors select-none",children:[e.jsx("input",{type:"checkbox",checked:P.onlySimilar,onChange:Y=>V(_e=>({..._e,onlySimilar:Y.target.checked})),className:"rounded text-blue-600 w-3 h-3"}),l("candidates.similarOnly")]}),(P.sort!=="default"||P.onlySimilar)&&e.jsx("button",{onClick:()=>V({sort:"default",onlySimilar:!1}),className:"text-[11px] font-medium text-[var(--fg-secondary)] hover:text-[var(--fg-primary)] px-2 py-1 rounded-lg border border-[var(--border-default)] bg-[var(--bg-surface)] hover:bg-[var(--bg-subtle)] transition-colors",children:l("candidates.resetFilters")})]}),e.jsx("div",{className:"h-5 w-px bg-[var(--border-default)]"}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-[11px] text-[var(--fg-muted)] font-medium",children:l("candidates.totalCount",{count:fe})}),e.jsx("button",{onClick:()=>p(Le,J),className:"text-[11px] font-bold text-blue-600 hover:text-blue-700 px-2.5 py-1.5 rounded-lg hover:bg-blue-50 transition-colors",children:l("candidates.approveCurrentPage")}),e.jsx("button",{onClick:async()=>{if(!window.confirm(l("candidates.batchDeleteConfirm",{count:Le.length})))return;const _e=(await Promise.allSettled(Le.map(dt=>i(J,dt.id)))).filter(dt=>dt.status==="rejected").length;_e>0&&Z(`${_e} ${l("common.deleteFailed")}`,{title:l("common.operationFailed"),type:"error"}),d?.()},className:"text-[11px] font-bold text-orange-500 hover:text-orange-600 px-2.5 py-1.5 rounded-lg hover:bg-orange-50 transition-colors",children:l("candidates.removeCurrentPage")}),e.jsx("button",{onClick:()=>o(J),className:"text-[11px] font-bold text-red-500 hover:text-red-600 px-2.5 py-1.5 rounded-lg hover:bg-red-50 transition-colors border border-red-200",children:l("candidates.deleteAll")})]})]}),e.jsx("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-3",children:Le.map(Y=>{const _e=f===Y.id,dt=Y.reasoning?.confidence??null,bt=(Y.quality?.overall??0)>0?Y.quality?.overall??null:null,zt=Q[Y.id]||[],Re=zt[0]||null,nt=Ra[Y.source||""]||{labelKey:Y.source||"",color:"text-[var(--fg-secondary)] bg-[var(--bg-subtle)] border-[var(--border-default)]"},Xe=it[Y.category||""]||it.All||{};return e.jsxs("div",{onClick:()=>y(_e?null:Y.id),className:`bg-[var(--bg-surface)] rounded-xl border overflow-hidden hover:shadow-lg transition-all duration-200 flex flex-col group cursor-pointer
83
83
  ${m?"opacity-75":""}
84
84
  ${_e?"ring-2 ring-blue-300 border-blue-300 shadow-md":"border-[var(--border-default)] hover:border-[var(--border-emphasis)]"}`,children:[e.jsx("div",{className:"px-4 pt-3.5 pb-2",children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5 mb-1.5",children:[e.jsxs("span",{className:`text-[10px] font-bold px-1.5 py-0.5 rounded uppercase flex items-center gap-1 border ${Xe?.bg||"bg-[var(--bg-subtle)]"} ${Xe?.color||"text-[var(--fg-muted)]"} ${Xe?.border||"border-[var(--border-default)]"}`,children:[(()=>{const We=Xe?.icon||rt;return e.jsx(We,{size:10})})(),Y.category||"general"]}),Y.knowledgeType&&e.jsx("span",{className:"text-[10px] font-medium px-1.5 py-0.5 rounded bg-indigo-50 text-indigo-600 border border-indigo-100",children:Y.knowledgeType}),Y.source&&Y.source!=="unknown"&&e.jsx("span",{className:`text-[10px] font-medium px-1.5 py-0.5 rounded border ${nt.color}`,children:nt.labelKey.startsWith("candidates.")?l(nt.labelKey):nt.labelKey}),Y.complexity&&e.jsx("span",{className:`text-[10px] font-medium px-1.5 py-0.5 rounded border
85
85
  ${Y.complexity==="advanced"?"bg-red-50 text-red-600 border-red-100":Y.complexity==="intermediate"?"bg-amber-50 text-amber-600 border-amber-100":"bg-emerald-50 text-emerald-600 border-emerald-100"}`,children:Y.complexity==="advanced"?l("candidates.confidenceHigh"):Y.complexity==="intermediate"?l("candidates.confidenceMedium"):l("candidates.confidenceLow")})]}),e.jsx("h3",{className:"font-bold text-sm text-[var(--fg-primary)] leading-snug mb-1 line-clamp-1",children:Y.title}),e.jsx("p",{className:"text-xs text-[var(--fg-secondary)] line-clamp-2 leading-relaxed",children:Y.description||""})]}),e.jsxs("div",{className:"flex flex-col items-center gap-1 shrink-0",children:[e.jsx(ei,{value:dt}),e.jsx("span",{className:"text-[9px] text-[var(--fg-muted)] font-medium",children:l("candidates.confidence")})]})]})}),Y.reasoning?.whyStandard&&!/^Submitted via /i.test(Y.reasoning.whyStandard)&&e.jsx("div",{className:"px-4 py-2 bg-gradient-to-r from-indigo-50/50 to-transparent border-t border-indigo-50",children:e.jsxs("div",{className:"flex items-start gap-1.5",children:[e.jsx(qt,{size:12,className:"text-indigo-400 mt-0.5 shrink-0"}),e.jsx("p",{className:"text-[11px] text-indigo-600/80 line-clamp-1 leading-relaxed",children:Y.reasoning.whyStandard})]})}),(bt!=null||Re)&&e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5 px-4 py-2 border-t border-[var(--border-default)]",children:[bt!=null&&e.jsxs("span",{className:"text-[10px] font-bold px-2 py-0.5 rounded-full bg-emerald-50 text-emerald-700 border border-emerald-200 flex items-center gap-1",children:[e.jsx(rs,{size:10}),l("candidates.overallScore",{score:(bt*100).toFixed(0)+"%"})]}),Re&&e.jsxs("button",{onClick:We=>{We.stopPropagation();const Je=String(Re.recipeName||"").trim();Je&&De(Y,J,Je,zt)},className:"text-[10px] font-bold px-2 py-0.5 rounded-full bg-amber-50 text-amber-700 border border-amber-200 hover:bg-amber-100 transition-colors flex items-center gap-1",title:l("candidates.similarWith",{name:Re.recipeName,score:(Re.similarity*100).toFixed(0)}),children:[e.jsx(hs,{size:10}),l("candidates.similarPrefix")," ",Re.recipeName.replace(/\.md$/i,"")," ",(Re.similarity*100).toFixed(0),"%"]})]}),Y.content?.pattern&&e.jsxs("div",{className:"overflow-hidden border-t border-[var(--border-default)]/60",children:[e.jsxs("div",{className:"flex items-center justify-between px-3 py-1.5",style:{background:"#282c34"},children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ht,{size:11,className:"text-[var(--fg-secondary)]"}),e.jsx("span",{className:"text-[10px] text-[var(--fg-muted)] font-mono uppercase tracking-wide",children:Y.language||"code"})]}),e.jsx("span",{className:"text-[10px] text-[var(--fg-secondary)] font-mono tabular-nums",children:l("candidates.linesCount",{count:Y.content.pattern.split(`
@@ -5,7 +5,7 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>AutoSnippet Dashboard</title>
8
- <script type="module" crossorigin src="/assets/index-CKMy5LY6.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-DdvZE4Yd.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/yaml-qRaU8Ldn.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/vendor-BZEJEVBn.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/icons-C1dUryS-.js">
package/dist/bin/cli.js CHANGED
@@ -284,7 +284,9 @@ program
284
284
  }
285
285
  }
286
286
  else if (!opts.json) {
287
- cli.log(' 💡 AI 填充已在后台运行。用 --wait 等待完成,或用 asd ui 查看进度。');
287
+ cli.log('');
288
+ cli.log(' 📋 下一步:打开 IDE Agent Mode,告诉它「帮我冷启动」');
289
+ cli.log(' IDE 会自动调用 MCP 工具完成 AI 分析、提取知识模式、提交候选。');
288
290
  }
289
291
  await bootstrap.shutdown();
290
292
  // 等待 stdout 刷新完成后再退出 (避免管道输出截断)
@@ -670,7 +672,6 @@ program
670
672
  .command('ui')
671
673
  .description('启动 Dashboard UI(API 服务 + 前端开发服务器)')
672
674
  .option('-p, --port <port>', 'API 服务端口', '3000')
673
- .option('-b, --browser', '自动打开浏览器')
674
675
  .option('--no-open', '禁止自动打开浏览器(CI/CD 环境适用)')
675
676
  .option('-d, --dir <directory>', '指定 AutoSnippet 项目目录(默认:当前目录)')
676
677
  .option('--api-only', '仅启动 API 服务(不启动前端)')
@@ -698,6 +699,33 @@ program
698
699
  httpServer = new HttpServer({ port, host });
699
700
  await httpServer.initialize();
700
701
  await httpServer.start();
702
+ // ── MCP 配置检测 ──
703
+ const cursorMcpPath = join(projectRoot, '.cursor', 'mcp.json');
704
+ const vscodeMcpPath = join(projectRoot, '.vscode', 'mcp.json');
705
+ const hasMcpConfig = (() => {
706
+ try {
707
+ const c = JSON.parse(readFileSync(cursorMcpPath, 'utf8'));
708
+ if ('autosnippet' in (c.mcpServers || {})) {
709
+ return true;
710
+ }
711
+ }
712
+ catch {
713
+ /* */
714
+ }
715
+ try {
716
+ const v = JSON.parse(readFileSync(vscodeMcpPath, 'utf8'));
717
+ if ('autosnippet' in (v.servers || {})) {
718
+ return true;
719
+ }
720
+ }
721
+ catch {
722
+ /* */
723
+ }
724
+ return false;
725
+ })();
726
+ if (hasMcpConfig) {
727
+ console.log('💡 请确认 IDE 中 AutoSnippet MCP 开关已打开,否则 Agent 无法调用工具');
728
+ }
701
729
  // 启动 SignalCollector 后台 AI 分析服务
702
730
  try {
703
731
  const { SignalCollector } = await import('../lib/service/skills/SignalCollector.js');
@@ -835,9 +863,11 @@ program
835
863
  // ── 生产模式:npm 安装的包,在 API 服务器上直接托管预构建产物 ──
836
864
  // 同端口同 origin → /api 路由自然可达,无跨域问题
837
865
  httpServer.mountDashboard(distDir);
838
- if (opts.browser) {
866
+ const dashUrl = `http://127.0.0.1:${port}/`;
867
+ console.log(`\n 🚀 Dashboard: ${dashUrl}\n`);
868
+ if (opts.open !== false) {
839
869
  const open = (await import('open')).default;
840
- open(`http://127.0.0.1:${port}/`);
870
+ open(dashUrl);
841
871
  }
842
872
  }
843
873
  else {
@@ -849,7 +879,7 @@ program
849
879
  });
850
880
  }
851
881
  const viteArgs = ['--host'];
852
- if (opts.browser) {
882
+ if (opts.open !== false) {
853
883
  viteArgs.push('--open');
854
884
  }
855
885
  const vite = spawn('npx', ['vite', ...viteArgs], {
@@ -886,9 +916,14 @@ program
886
916
  // AI 配置
887
917
  const { getAiConfigInfo } = await import('../lib/external/ai/AiFactory.js');
888
918
  const aiInfo = getAiConfigInfo();
889
- cli.log(` AI Provider: ${aiInfo.provider || 'not configured'}`);
890
- if (aiInfo.model) {
891
- cli.log(` AI Model: ${aiInfo.model}`);
919
+ if (aiInfo.provider && aiInfo.provider !== 'none') {
920
+ cli.log(` AI Provider: ${aiInfo.provider}`);
921
+ if (aiInfo.model) {
922
+ cli.log(` AI Model: ${aiInfo.model}`);
923
+ }
924
+ }
925
+ else {
926
+ cli.log(' AI Provider: 通过 IDE Agent(无需配置)');
892
927
  }
893
928
  // 检查数据库
894
929
  const dbPath = join(process.cwd(), '.autosnippet', 'autosnippet.db');
@@ -915,7 +950,7 @@ program
915
950
  // ─────────────────────────────────────────────────────
916
951
  program
917
952
  .command('embed')
918
- .description('构建/重建语义向量索引')
953
+ .description('构建/重建语义向量索引(可选 — 增强搜索质量,非必需)')
919
954
  .option('-d, --dir <path>', '项目目录', '.')
920
955
  .option('--force', '忽略增量检测,全量重建')
921
956
  .option('--clear', '清空现有索引后重建')
@@ -1276,7 +1311,7 @@ program
1276
1311
  cli.log(` ✅ ${label}: ${count} item(s) mirrored`);
1277
1312
  }
1278
1313
  });
1279
- /** @private 递归复制目录(mirror 命令用) */
1314
+ /** 递归复制目录(mirror 命令用) */
1280
1315
  function _copyDirRecursive(src, dest) {
1281
1316
  mkdirSync(dest, { recursive: true });
1282
1317
  for (const entry of readdirSync(src, { withFileTypes: true })) {
@@ -41,11 +41,11 @@ export const AgentEvents = Object.freeze({
41
41
  export class AgentEventBus extends EventEmitter {
42
42
  static #instance = null;
43
43
  #logger;
44
- /** @type {Map<string, Function[]>} topic → handlers */
44
+ /** topic → handlers */
45
45
  #subscriptions = new Map();
46
- /** @type {Map<string, {resolve: Function, reject: Function, timer: NodeJS.Timeout}>} */
46
+ /** >} */
47
47
  #pendingReplies = new Map();
48
- /** @type {number} 事件计数 */
48
+ /** 事件计数 */
49
49
  #eventCount = 0;
50
50
  constructor() {
51
51
  super();
@@ -94,7 +94,7 @@ export declare class AgentFactory {
94
94
  createRuntime(presetName: string, overrides?: RuntimeOverrides): AgentRuntime;
95
95
  /**
96
96
  * 创建 ContextWindow (根据当前 AI Provider 自动解析 token 预算)
97
- * @param {{ isSystem?: boolean }} [opts]
97
+ * @param [opts]
98
98
  */
99
99
  createContextWindow(opts?: {
100
100
  isSystem?: boolean;
@@ -175,7 +175,7 @@ export declare class AgentFactory {
175
175
  * 关系发现请使用单独的 discoverRelations() 方法。
176
176
  *
177
177
  * @param opts.label 上下文标签(target 名 / 文件名)
178
- * @param {Array<{name, content, language?}>} opts.files 源文件
178
+ * @param opts.files 源文件
179
179
  * @param [opts.task='extract'] 任务类型
180
180
  * @param [opts.lang] 语言提示
181
181
  * @param [opts.comprehensive] 深度扫描标志
@@ -210,7 +210,7 @@ export declare class AgentFactory {
210
210
  * bootstrap_knowledge 是纯启发式工具:SPM Target 扫描 → 依赖图谱 → Guard 审计 →
211
211
  * Candidate 创建,全程无 AI 推理。直接调用 handler 即可,无需创建 Agent。
212
212
  *
213
- * @param {{ maxFiles?: number, skipGuard?: boolean, contentMaxLines?: number, loadSkills?: boolean, skipAsyncFill?: boolean }} [opts]
213
+ * @param [opts]
214
214
  */
215
215
  bootstrapKnowledge(opts?: BootstrapKnowledgeOptions): Promise<any>;
216
216
  /**
@@ -30,7 +30,7 @@ export class AgentFactory {
30
30
  #aiProvider;
31
31
  #logger;
32
32
  #router = null;
33
- /** @type {Object} 共享的 Capability 实例缓存 (如 MemoryCoordinator) */
33
+ /** 共享的 Capability 实例缓存 (如 MemoryCoordinator) */
34
34
  #sharedOpts;
35
35
  /**
36
36
  * @param opts.container ServiceContainer 实例
@@ -104,7 +104,7 @@ export class AgentFactory {
104
104
  // ─── 快捷方法 (语义化) ─────────────────────
105
105
  /**
106
106
  * 创建 ContextWindow (根据当前 AI Provider 自动解析 token 预算)
107
- * @param {{ isSystem?: boolean }} [opts]
107
+ * @param [opts]
108
108
  */
109
109
  createContextWindow(opts = {}) {
110
110
  const modelName = this.#aiProvider?.model || '';
@@ -212,7 +212,7 @@ export class AgentFactory {
212
212
  * 关系发现请使用单独的 discoverRelations() 方法。
213
213
  *
214
214
  * @param opts.label 上下文标签(target 名 / 文件名)
215
- * @param {Array<{name, content, language?}>} opts.files 源文件
215
+ * @param opts.files 源文件
216
216
  * @param [opts.task='extract'] 任务类型
217
217
  * @param [opts.lang] 语言提示
218
218
  * @param [opts.comprehensive] 深度扫描标志
@@ -376,7 +376,7 @@ export class AgentFactory {
376
376
  * bootstrap_knowledge 是纯启发式工具:SPM Target 扫描 → 依赖图谱 → Guard 审计 →
377
377
  * Candidate 创建,全程无 AI 推理。直接调用 handler 即可,无需创建 Agent。
378
378
  *
379
- * @param {{ maxFiles?: number, skipGuard?: boolean, contentMaxLines?: number, loadSkills?: boolean, skipAsyncFill?: boolean }} [opts]
379
+ * @param [opts]
380
380
  */
381
381
  async bootstrapKnowledge(opts = {}) {
382
382
  const { bootstrapKnowledge } = await import('#external/mcp/handlers/bootstrap-internal.js');
@@ -127,21 +127,21 @@ export declare const Channel: Readonly<{
127
127
  INTERNAL: "internal";
128
128
  }>;
129
129
  export declare class AgentMessage {
130
- /** @type {string} 消息唯一 ID */
130
+ /** 消息唯一 ID */
131
131
  id: `${string}-${string}-${string}-${string}-${string}`;
132
- /** @type {string} 用户输入内容 */
132
+ /** 用户输入内容 */
133
133
  content: string;
134
- /** @type {string} 通信渠道 */
134
+ /** 通信渠道 */
135
135
  channel: string;
136
- /** @type {Session} 会话信息 */
136
+ /** 会话信息 */
137
137
  session: Session;
138
- /** @type {Sender} 发送者 */
138
+ /** 发送者 */
139
139
  sender: Sender;
140
- /** @type {Record<string, any>} 渠道特定元数据 */
140
+ /** 渠道特定元数据 */
141
141
  metadata: Record<string, unknown>;
142
- /** @type {Function|null} 回复函数 (text: string) => Promise<void> */
142
+ /** 回复函数 (text: string) => Promise<void> */
143
143
  replyFn: ReplyFn | null;
144
- /** @type {number} 时间戳 */
144
+ /** 时间戳 */
145
145
  timestamp: number;
146
146
  /**
147
147
  * @param opts.content 用户输入
@@ -23,21 +23,21 @@ export const Channel = Object.freeze({
23
23
  INTERNAL: 'internal', // Agent 间通信
24
24
  });
25
25
  export class AgentMessage {
26
- /** @type {string} 消息唯一 ID */
26
+ /** 消息唯一 ID */
27
27
  id;
28
- /** @type {string} 用户输入内容 */
28
+ /** 用户输入内容 */
29
29
  content;
30
- /** @type {string} 通信渠道 */
30
+ /** 通信渠道 */
31
31
  channel;
32
- /** @type {Session} 会话信息 */
32
+ /** 会话信息 */
33
33
  session;
34
- /** @type {Sender} 发送者 */
34
+ /** 发送者 */
35
35
  sender;
36
- /** @type {Record<string, any>} 渠道特定元数据 */
36
+ /** 渠道特定元数据 */
37
37
  metadata;
38
- /** @type {Function|null} 回复函数 (text: string) => Promise<void> */
38
+ /** 回复函数 (text: string) => Promise<void> */
39
39
  replyFn;
40
- /** @type {number} 时间戳 */
40
+ /** 时间戳 */
41
41
  timestamp;
42
42
  /**
43
43
  * @param opts.content 用户输入
@@ -60,9 +60,9 @@ export class AgentRuntime {
60
60
  lang;
61
61
  logger;
62
62
  #projectRoot;
63
- /** @type {Array|null} 文件缓存 (bootstrap 场景注入) */
63
+ /** 文件缓存 (bootstrap 场景注入) */
64
64
  #fileCache = null;
65
- /** @type {string[]} 额外工具白名单 (调用方按需注入,不经 Capability) */
65
+ /** 额外工具白名单 (调用方按需注入,不经 Capability) */
66
66
  #additionalTools = [];
67
67
  #toolPipeline;
68
68
  #promptBuilder;
@@ -45,14 +45,14 @@ const DEFAULT_TRANSITIONS = [
45
45
  { from: '*', to: AgentPhase.FAILED, event: 'error' },
46
46
  ];
47
47
  export class AgentState extends EventEmitter {
48
- /** @type {string} 当前阶段 */
48
+ /** 当前阶段 */
49
49
  #phase;
50
- /** @type {Object} 用户自定义状态数据 */
50
+ /** 用户自定义状态数据 */
51
51
  #data;
52
52
  #transitions;
53
- /** @type {Array<{phase: string, data: Object, timestamp: number}>} */
53
+ /** >} */
54
54
  #history;
55
- /** @type {boolean} 是否保留历史 */
55
+ /** 是否保留历史 */
56
56
  #keepHistory;
57
57
  /**
58
58
  * @param [opts.initialData={}] 初始状态数据
@@ -45,7 +45,7 @@ export declare class ConversationStore {
45
45
  }): `${string}-${string}-${string}-${string}-${string}`;
46
46
  /**
47
47
  * 追加消息到对话
48
- * @param {{ role: string, content: string }} message
48
+ * @param message
49
49
  */
50
50
  append(conversationId: string, message: ConversationMessage): void;
51
51
  /**
@@ -73,7 +73,7 @@ export class ConversationStore {
73
73
  }
74
74
  /**
75
75
  * 追加消息到对话
76
- * @param {{ role: string, content: string }} message
76
+ * @param message
77
77
  */
78
78
  append(conversationId, message) {
79
79
  try {