autosnippet 3.2.18 → 3.2.21
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/LICENSE +1 -1
- package/README.md +73 -104
- package/config/default.json +1 -1
- package/dashboard/dist/assets/{index-CKMy5LY6.js → index-DdvZE4Yd.js} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/dist/bin/cli.js +45 -10
- package/dist/lib/agent/AgentEventBus.js +3 -3
- package/dist/lib/agent/AgentFactory.d.ts +3 -3
- package/dist/lib/agent/AgentFactory.js +4 -4
- package/dist/lib/agent/AgentMessage.d.ts +8 -8
- package/dist/lib/agent/AgentMessage.js +8 -8
- package/dist/lib/agent/AgentRuntime.js +2 -2
- package/dist/lib/agent/AgentState.js +4 -4
- package/dist/lib/agent/ConversationStore.d.ts +1 -1
- package/dist/lib/agent/ConversationStore.js +1 -1
- package/dist/lib/agent/PipelineStrategy.js +1 -1
- package/dist/lib/agent/context/ContextWindow.d.ts +2 -2
- package/dist/lib/agent/context/ContextWindow.js +7 -7
- package/dist/lib/agent/context/ExplorationTracker.js +9 -9
- package/dist/lib/agent/context/exploration/PlanTracker.js +2 -2
- package/dist/lib/agent/context/exploration/SignalDetector.d.ts +1 -1
- package/dist/lib/agent/context/exploration/SignalDetector.js +1 -1
- package/dist/lib/agent/core/LoopContext.d.ts +21 -21
- package/dist/lib/agent/core/LoopContext.js +21 -21
- package/dist/lib/agent/core/SystemPromptBuilder.js +4 -4
- package/dist/lib/agent/domain/EvidenceCollector.js +5 -5
- package/dist/lib/agent/memory/ActiveContext.js +1 -1
- package/dist/lib/agent/memory/MemoryRetriever.js +1 -1
- package/dist/lib/agent/memory/MemoryStore.js +2 -2
- package/dist/lib/agent/memory/SessionStore.js +3 -3
- package/dist/lib/agent/policies.d.ts +1 -1
- package/dist/lib/agent/policies.js +1 -1
- package/dist/lib/agent/strategies.d.ts +1 -1
- package/dist/lib/agent/strategies.js +4 -4
- package/dist/lib/agent/tools/_shared.d.ts +1 -1
- package/dist/lib/agent/tools/_shared.js +1 -1
- package/dist/lib/agent/tools/infrastructure.js +2 -2
- package/dist/lib/cli/SetupService.d.ts +25 -25
- package/dist/lib/cli/SetupService.js +28 -15
- package/dist/lib/cli/deploy/FileDeployer.d.ts +9 -2
- package/dist/lib/cli/deploy/FileDeployer.js +139 -46
- package/dist/lib/cli/deploy/FileManifest.d.ts +23 -39
- package/dist/lib/cli/deploy/FileManifest.js +22 -33
- package/dist/lib/core/AstAnalyzer.d.ts +2 -2
- package/dist/lib/core/AstAnalyzer.js +2 -2
- package/dist/lib/core/analysis/CallEdgeResolver.d.ts +7 -7
- package/dist/lib/core/analysis/CallEdgeResolver.js +9 -9
- package/dist/lib/core/analysis/CallGraphAnalyzer.d.ts +4 -4
- package/dist/lib/core/analysis/CallGraphAnalyzer.js +2 -2
- package/dist/lib/core/analysis/ImportPathResolver.d.ts +0 -2
- package/dist/lib/core/analysis/ImportPathResolver.js +2 -4
- package/dist/lib/core/ast/ProjectGraph.js +7 -7
- package/dist/lib/core/capability/CapabilityProbe.js +6 -14
- package/dist/lib/domain/knowledge/UnifiedValidator.js +2 -2
- package/dist/lib/domain/knowledge/values/Constraints.js +4 -4
- package/dist/lib/domain/knowledge/values/Content.js +6 -6
- package/dist/lib/domain/knowledge/values/Quality.js +5 -5
- package/dist/lib/domain/knowledge/values/Reasoning.js +5 -5
- package/dist/lib/domain/knowledge/values/Relations.js +1 -1
- package/dist/lib/domain/knowledge/values/Stats.js +6 -6
- package/dist/lib/domain/task/TaskIdGenerator.d.ts +4 -4
- package/dist/lib/domain/task/TaskIdGenerator.js +2 -2
- package/dist/lib/external/lark/LarkTransport.js +4 -4
- package/dist/lib/external/mcp/McpServer.d.ts +3 -7
- package/dist/lib/external/mcp/McpServer.js +9 -13
- package/dist/lib/external/mcp/handlers/bootstrap/ExternalSubmissionTracker.js +5 -5
- package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.js +4 -3
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.d.ts +3 -3
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +3 -3
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.d.ts +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.js +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.js +3 -3
- package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-sop.js +27 -14
- package/dist/lib/external/mcp/handlers/bootstrap-external.js +6 -0
- package/dist/lib/external/mcp/handlers/dimension-complete-external.js +55 -1
- package/dist/lib/external/mcp/handlers/skill.js +9 -31
- package/dist/lib/external/mcp/handlers/system.js +6 -4
- package/dist/lib/external/mcp/handlers/task.js +16 -1
- package/dist/lib/external/mcp/tools.d.ts +12 -10
- package/dist/lib/external/mcp/tools.js +97 -69
- package/dist/lib/http/utils/routeHelpers.d.ts +1 -1
- package/dist/lib/http/utils/routeHelpers.js +1 -1
- package/dist/lib/http/utils/sse-sessions.d.ts +1 -1
- package/dist/lib/http/utils/sse-sessions.js +1 -1
- package/dist/lib/infrastructure/cache/CacheService.js +1 -1
- package/dist/lib/infrastructure/logging/Logger.js +1 -1
- package/dist/lib/infrastructure/monitoring/ErrorTracker.js +1 -1
- package/dist/lib/infrastructure/vector/AsyncPersistence.js +8 -8
- package/dist/lib/infrastructure/vector/BatchEmbedder.d.ts +1 -1
- package/dist/lib/infrastructure/vector/BatchEmbedder.js +2 -2
- package/dist/lib/infrastructure/vector/HnswIndex.d.ts +4 -4
- package/dist/lib/infrastructure/vector/HnswIndex.js +5 -5
- package/dist/lib/infrastructure/vector/HnswVectorAdapter.js +8 -8
- package/dist/lib/infrastructure/vector/ScalarQuantizer.d.ts +1 -1
- package/dist/lib/infrastructure/vector/ScalarQuantizer.js +4 -4
- package/dist/lib/infrastructure/vector/VectorStore.d.ts +1 -1
- package/dist/lib/infrastructure/vector/VectorStore.js +1 -1
- package/dist/lib/injection/ServiceContainer.d.ts +1 -1
- package/dist/lib/injection/ServiceContainer.js +1 -1
- package/dist/lib/injection/modules/KnowledgeModule.js +4 -5
- package/dist/lib/platform/NativeUi.d.ts +1 -1
- package/dist/lib/platform/NativeUi.js +1 -1
- package/dist/lib/platform/ios/spm/DependencyGraph.d.ts +1 -1
- package/dist/lib/platform/ios/spm/DependencyGraph.js +1 -1
- package/dist/lib/platform/ios/spm/PolicyEngine.d.ts +1 -1
- package/dist/lib/platform/ios/spm/PolicyEngine.js +1 -1
- package/dist/lib/platform/ios/spm/SpmDiscoverer.js +1 -1
- package/dist/lib/platform/ios/spm/SpmHelper.js +3 -3
- package/dist/lib/platform/ios/xcode/SaveEventFilter.js +2 -2
- package/dist/lib/platform/ios/xcode/XcodeIntegration.js +1 -1
- package/dist/lib/repository/base/BaseRepository.js +1 -1
- package/dist/lib/repository/task/TaskRepository.impl.d.ts +2 -2
- package/dist/lib/repository/task/TaskRepository.impl.js +1 -1
- package/dist/lib/repository/token/TokenUsageStore.js +1 -1
- package/dist/lib/service/automation/ActionPipeline.d.ts +1 -1
- package/dist/lib/service/automation/ActionPipeline.js +1 -1
- package/dist/lib/service/bootstrap/BootstrapEventEmitter.js +2 -2
- package/dist/lib/service/bootstrap/BootstrapTaskManager.d.ts +1 -1
- package/dist/lib/service/bootstrap/BootstrapTaskManager.js +2 -2
- package/dist/lib/service/bootstrap/DimensionCopyRegistry.d.ts +2 -2
- package/dist/lib/service/bootstrap/DimensionCopyRegistry.js +2 -2
- package/dist/lib/service/delivery/AgentInstructionsGenerator.d.ts +6 -15
- package/dist/lib/service/delivery/AgentInstructionsGenerator.js +53 -189
- package/dist/lib/service/delivery/CursorDeliveryPipeline.d.ts +6 -16
- package/dist/lib/service/delivery/CursorDeliveryPipeline.js +14 -19
- package/dist/lib/service/delivery/KnowledgeCompressor.d.ts +1 -1
- package/dist/lib/service/delivery/KnowledgeCompressor.js +1 -1
- package/dist/lib/service/delivery/RulesGenerator.d.ts +10 -3
- package/dist/lib/service/delivery/RulesGenerator.js +43 -3
- package/dist/lib/service/delivery/SkillsSyncer.d.ts +21 -7
- package/dist/lib/service/delivery/SkillsSyncer.js +46 -10
- package/dist/lib/service/delivery/TopicClassifier.d.ts +3 -6
- package/dist/lib/service/delivery/TopicClassifier.js +0 -3
- package/dist/lib/service/guard/ExclusionManager.d.ts +1 -1
- package/dist/lib/service/guard/ExclusionManager.js +1 -1
- package/dist/lib/service/guard/GuardCheckEngine.d.ts +3 -3
- package/dist/lib/service/guard/GuardCheckEngine.js +5 -5
- package/dist/lib/service/guard/GuardCrossFileChecks.d.ts +1 -1
- package/dist/lib/service/guard/GuardFeedbackLoop.d.ts +3 -3
- package/dist/lib/service/guard/GuardFeedbackLoop.js +3 -3
- package/dist/lib/service/guard/GuardPatternUtils.js +1 -1
- package/dist/lib/service/guard/GuardService.d.ts +1 -15
- package/dist/lib/service/guard/GuardService.js +0 -1
- package/dist/lib/service/guard/RuleLearner.d.ts +1 -1
- package/dist/lib/service/guard/RuleLearner.js +1 -1
- package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +3 -3
- package/dist/lib/service/knowledge/CodeEntityGraph.js +3 -3
- package/dist/lib/service/knowledge/KnowledgeService.d.ts +0 -1
- package/dist/lib/service/knowledge/KnowledgeService.js +0 -1
- package/dist/lib/service/module/ModuleService.d.ts +1 -1
- package/dist/lib/service/module/ModuleService.js +2 -2
- package/dist/lib/service/search/HybridRetriever.d.ts +2 -2
- package/dist/lib/service/search/HybridRetriever.js +2 -2
- package/dist/lib/service/search/SearchEngine.d.ts +1 -3
- package/dist/lib/service/search/SearchEngine.js +1 -3
- package/dist/lib/service/search/contextBoost.d.ts +1 -1
- package/dist/lib/service/skills/EventAggregator.js +2 -2
- package/dist/lib/service/skills/SignalCollector.js +1 -1
- package/dist/lib/service/snippet/codecs/VSCodeCodec.js +1 -1
- package/dist/lib/service/task/TaskGraphService.d.ts +0 -3
- package/dist/lib/service/task/TaskGraphService.js +0 -3
- package/dist/lib/service/task/TaskKnowledgeBridge.d.ts +8 -27
- package/dist/lib/service/task/TaskKnowledgeBridge.js +0 -8
- package/dist/lib/service/task/TaskReadyEngine.d.ts +1 -2
- package/dist/lib/service/task/TaskReadyEngine.js +0 -1
- package/dist/lib/service/wiki/WikiRenderers.js +0 -1
- package/dist/lib/service/wiki/WikiUtils.js +2 -7
- package/dist/lib/shared/PathGuard.js +6 -6
- package/dist/lib/shared/schemas/config.js +1 -1
- package/dist/lib/shared/schemas/mcp-tools.js +84 -43
- package/dist/scripts/install-vscode-copilot.js +14 -4
- package/package.json +1 -1
- package/skills/autosnippet-create/SKILL.md +131 -131
- package/skills/autosnippet-devdocs/SKILL.md +1 -2
- package/skills/autosnippet-guard/SKILL.md +20 -89
- package/skills/autosnippet-recipes/SKILL.md +35 -117
- package/skills/autosnippet-structure/SKILL.md +23 -55
- package/templates/cursor-rules/autosnippet-skills.mdc +17 -33
- package/templates/instructions/agent-static.md +24 -0
- package/templates/instructions/conventions.md +42 -0
- package/skills/autosnippet-analysis/SKILL.md +0 -169
- package/skills/autosnippet-candidates/SKILL.md +0 -367
- package/skills/autosnippet-coldstart/SKILL.md +0 -988
- package/skills/autosnippet-concepts/SKILL.md +0 -630
- package/skills/autosnippet-intent/SKILL.md +0 -55
- package/skills/autosnippet-lifecycle/SKILL.md +0 -100
- package/templates/copilot-instructions.md +0 -66
- package/templates/cursor-rules/autosnippet-conventions.mdc +0 -172
- package/templates/cursor-rules/autosnippet-workflow.mdc +0 -76
package/LICENSE
CHANGED
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
|
|
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
|
|
38
|
-
asd
|
|
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
|
-
|
|
43
|
+
> **Trae / Qoder users:** After `asd setup`, run `asd mirror` to sync `.cursor/` config to `.trae/` / `.qoder/`.
|
|
43
44
|
|
|
44
|
-
##
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
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
|
-
|
|
100
|
+
### TaskGraph Orchestration
|
|
59
101
|
|
|
60
|
-
|
|
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
|
-
|
|
104
|
+
### Self-Cycling Signal Mechanism
|
|
71
105
|
|
|
72
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
|
package/config/default.json
CHANGED
|
@@ -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.
|
|
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-
|
|
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('
|
|
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
|
-
|
|
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(
|
|
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.
|
|
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
|
-
|
|
890
|
-
|
|
891
|
-
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
44
|
+
/** topic → handlers */
|
|
45
45
|
#subscriptions = new Map();
|
|
46
|
-
/**
|
|
46
|
+
/** >} */
|
|
47
47
|
#pendingReplies = new Map();
|
|
48
|
-
/**
|
|
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
|
|
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
|
|
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
|
|
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
|
-
/**
|
|
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
|
|
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
|
|
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
|
|
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
|
-
/**
|
|
130
|
+
/** 消息唯一 ID */
|
|
131
131
|
id: `${string}-${string}-${string}-${string}-${string}`;
|
|
132
|
-
/**
|
|
132
|
+
/** 用户输入内容 */
|
|
133
133
|
content: string;
|
|
134
|
-
/**
|
|
134
|
+
/** 通信渠道 */
|
|
135
135
|
channel: string;
|
|
136
|
-
/**
|
|
136
|
+
/** 会话信息 */
|
|
137
137
|
session: Session;
|
|
138
|
-
/**
|
|
138
|
+
/** 发送者 */
|
|
139
139
|
sender: Sender;
|
|
140
|
-
/**
|
|
140
|
+
/** 渠道特定元数据 */
|
|
141
141
|
metadata: Record<string, unknown>;
|
|
142
|
-
/**
|
|
142
|
+
/** 回复函数 (text: string) => Promise<void> */
|
|
143
143
|
replyFn: ReplyFn | null;
|
|
144
|
-
/**
|
|
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
|
-
/**
|
|
26
|
+
/** 消息唯一 ID */
|
|
27
27
|
id;
|
|
28
|
-
/**
|
|
28
|
+
/** 用户输入内容 */
|
|
29
29
|
content;
|
|
30
|
-
/**
|
|
30
|
+
/** 通信渠道 */
|
|
31
31
|
channel;
|
|
32
|
-
/**
|
|
32
|
+
/** 会话信息 */
|
|
33
33
|
session;
|
|
34
|
-
/**
|
|
34
|
+
/** 发送者 */
|
|
35
35
|
sender;
|
|
36
|
-
/**
|
|
36
|
+
/** 渠道特定元数据 */
|
|
37
37
|
metadata;
|
|
38
|
-
/**
|
|
38
|
+
/** 回复函数 (text: string) => Promise<void> */
|
|
39
39
|
replyFn;
|
|
40
|
-
/**
|
|
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
|
-
/**
|
|
63
|
+
/** 文件缓存 (bootstrap 场景注入) */
|
|
64
64
|
#fileCache = null;
|
|
65
|
-
/**
|
|
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
|
-
/**
|
|
48
|
+
/** 当前阶段 */
|
|
49
49
|
#phase;
|
|
50
|
-
/**
|
|
50
|
+
/** 用户自定义状态数据 */
|
|
51
51
|
#data;
|
|
52
52
|
#transitions;
|
|
53
|
-
/**
|
|
53
|
+
/** >} */
|
|
54
54
|
#history;
|
|
55
|
-
/**
|
|
55
|
+
/** 是否保留历史 */
|
|
56
56
|
#keepHistory;
|
|
57
57
|
/**
|
|
58
58
|
* @param [opts.initialData={}] 初始状态数据
|