autosnippet 3.3.5 → 3.3.7
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/dashboard/dist/assets/icons-FHns2ypa.js +1 -0
- package/dashboard/dist/assets/index-BRJv5Y3r.js +135 -0
- package/dashboard/dist/assets/index-DzoB7kxK.css +1 -0
- package/dashboard/dist/index.html +3 -3
- package/dist/bin/api-server.js +1 -0
- package/dist/bin/cli.d.ts +1 -0
- package/dist/bin/cli.js +137 -9
- package/dist/lib/agent/AgentFactory.d.ts +0 -17
- package/dist/lib/agent/AgentFactory.js +1 -25
- package/dist/lib/agent/AgentRuntime.d.ts +2 -2
- package/dist/lib/agent/AgentRuntime.js +26 -18
- package/dist/lib/agent/capabilities.d.ts +11 -0
- package/dist/lib/agent/capabilities.js +29 -5
- package/dist/lib/agent/context/ExplorationTracker.js +10 -1
- package/dist/lib/agent/context/exploration/ExplorationStrategies.d.ts +2 -0
- package/dist/lib/agent/context/exploration/ExplorationStrategies.js +2 -2
- package/dist/lib/agent/domain/ChatAgentTasks.js +4 -0
- package/dist/lib/agent/domain/insight-analyst.d.ts +47 -3
- package/dist/lib/agent/domain/insight-analyst.js +111 -11
- package/dist/lib/agent/domain/insight-evolver.d.ts +69 -0
- package/dist/lib/agent/domain/insight-evolver.js +230 -0
- package/dist/lib/agent/domain/insight-gate.d.ts +42 -0
- package/dist/lib/agent/domain/insight-gate.js +41 -0
- package/dist/lib/agent/domain/insight-producer.d.ts +27 -2
- package/dist/lib/agent/domain/insight-producer.js +60 -5
- package/dist/lib/agent/domain/scan-prompts.js +10 -7
- package/dist/lib/agent/forced-summary.js +7 -2
- package/dist/lib/agent/memory/ActiveContext.d.ts +2 -28
- package/dist/lib/agent/memory/MemoryCoordinator.d.ts +2 -2
- package/dist/lib/agent/memory/SessionStore.d.ts +6 -12
- package/dist/lib/agent/memory/SessionStore.js +9 -15
- package/dist/lib/agent/memory/memory-flush-contract.d.ts +49 -0
- package/dist/lib/agent/memory/memory-flush-contract.js +16 -0
- package/dist/lib/agent/memory/session-store-schema.d.ts +20 -0
- package/dist/lib/agent/memory/session-store-schema.js +41 -0
- package/dist/lib/agent/presets.d.ts +89 -1
- package/dist/lib/agent/presets.js +53 -5
- package/dist/lib/agent/tools/_shared.d.ts +7 -15
- package/dist/lib/agent/tools/_shared.js +20 -21
- package/dist/lib/agent/tools/composite.d.ts +25 -22
- package/dist/lib/agent/tools/composite.js +108 -109
- package/dist/lib/agent/tools/evolution-tools.d.ts +145 -0
- package/dist/lib/agent/tools/evolution-tools.js +161 -0
- package/dist/lib/agent/tools/index.d.ts +163 -92
- package/dist/lib/agent/tools/index.js +9 -1
- package/dist/lib/agent/tools/lifecycle.d.ts +7 -1
- package/dist/lib/agent/tools/lifecycle.js +59 -75
- package/dist/lib/cli/AiScanService.js +5 -5
- package/dist/lib/cli/KnowledgeSyncService.js +1 -1
- package/dist/lib/core/AstAnalyzer.d.ts +1 -0
- package/dist/lib/core/discovery/ConfigWatcher.d.ts +64 -0
- package/dist/lib/core/discovery/ConfigWatcher.js +336 -0
- package/dist/lib/core/discovery/CustomConfigDiscoverer.d.ts +30 -0
- package/dist/lib/core/discovery/CustomConfigDiscoverer.js +1305 -0
- package/dist/lib/core/discovery/DiscovererPreference.d.ts +44 -0
- package/dist/lib/core/discovery/DiscovererPreference.js +141 -0
- package/dist/lib/core/discovery/DiscovererRegistry.d.ts +10 -1
- package/dist/lib/core/discovery/DiscovererRegistry.js +42 -2
- package/dist/lib/core/discovery/ProjectDiscoverer.d.ts +19 -0
- package/dist/lib/core/discovery/index.d.ts +2 -0
- package/dist/lib/core/discovery/index.js +4 -0
- package/dist/lib/core/discovery/parsers/CMakeParser.d.ts +32 -0
- package/dist/lib/core/discovery/parsers/CMakeParser.js +148 -0
- package/dist/lib/core/discovery/parsers/GradleDslParser.d.ts +43 -0
- package/dist/lib/core/discovery/parsers/GradleDslParser.js +171 -0
- package/dist/lib/core/discovery/parsers/JsonConfigParser.d.ts +45 -0
- package/dist/lib/core/discovery/parsers/JsonConfigParser.js +122 -0
- package/dist/lib/core/discovery/parsers/RubyDslParser.d.ts +49 -0
- package/dist/lib/core/discovery/parsers/RubyDslParser.js +282 -0
- package/dist/lib/core/discovery/parsers/StarlarkParser.d.ts +33 -0
- package/dist/lib/core/discovery/parsers/StarlarkParser.js +229 -0
- package/dist/lib/core/discovery/parsers/YamlConfigParser.d.ts +37 -0
- package/dist/lib/core/discovery/parsers/YamlConfigParser.js +212 -0
- package/dist/lib/{service/bootstrap/DimensionCopyRegistry.d.ts → domain/dimension/DimensionCopy.d.ts} +2 -2
- package/dist/lib/{service/bootstrap/DimensionCopyRegistry.js → domain/dimension/DimensionCopy.js} +22 -72
- package/dist/lib/domain/dimension/DimensionRegistry.d.ts +54 -0
- package/dist/lib/domain/dimension/DimensionRegistry.js +620 -0
- package/dist/lib/domain/dimension/DimensionSop.d.ts +55 -0
- package/dist/lib/domain/dimension/DimensionSop.js +1604 -0
- package/dist/lib/domain/dimension/UnifiedDimension.d.ts +61 -0
- package/dist/lib/domain/dimension/UnifiedDimension.js +53 -0
- package/dist/lib/domain/dimension/index.d.ts +10 -0
- package/dist/lib/domain/dimension/index.js +9 -0
- package/dist/lib/domain/knowledge/FieldSpec.d.ts +1 -1
- package/dist/lib/domain/knowledge/FieldSpec.js +29 -16
- package/dist/lib/domain/knowledge/KnowledgeEntry.d.ts +40 -112
- package/dist/lib/domain/knowledge/KnowledgeEntry.js +44 -9
- package/dist/lib/domain/knowledge/KnowledgeRepository.d.ts +1 -0
- package/dist/lib/domain/knowledge/KnowledgeRepository.js +3 -0
- package/dist/lib/domain/knowledge/Lifecycle.js +1 -1
- package/dist/lib/domain/knowledge/StyleGuide.d.ts +1 -1
- package/dist/lib/domain/knowledge/StyleGuide.js +1 -1
- package/dist/lib/domain/knowledge/UnifiedValidator.js +15 -0
- package/dist/lib/external/ai/AiProvider.d.ts +12 -0
- package/dist/lib/external/ai/AiProvider.js +24 -0
- package/dist/lib/external/ai/AiProviderManager.d.ts +101 -0
- package/dist/lib/external/ai/AiProviderManager.js +193 -0
- package/dist/lib/external/ai/providers/ClaudeProvider.js +11 -0
- package/dist/lib/external/ai/providers/GoogleGeminiProvider.js +18 -0
- package/dist/lib/external/ai/providers/MockProvider.d.ts +21 -3
- package/dist/lib/external/ai/providers/MockProvider.js +290 -14
- package/dist/lib/external/ai/providers/OpenAiProvider.js +16 -0
- package/dist/lib/external/lark/LarkTransport.d.ts +5 -1
- package/dist/lib/external/lark/LarkTransport.js +10 -2
- package/dist/lib/external/mcp/McpServer.js +4 -0
- package/dist/lib/external/mcp/handlers/TargetClassifier.d.ts +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap/BootstrapSession.d.ts +8 -16
- package/dist/lib/external/mcp/handlers/bootstrap/BootstrapSession.js +10 -10
- package/dist/lib/external/mcp/handlers/bootstrap/ExternalSubmissionTracker.d.ts +7 -0
- package/dist/lib/external/mcp/handlers/bootstrap/ExternalSubmissionTracker.js +20 -0
- package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.d.ts +52 -132
- package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.js +204 -17
- package/dist/lib/external/mcp/handlers/bootstrap/base-dimensions.d.ts +11 -75
- package/dist/lib/external/mcp/handlers/bootstrap/base-dimensions.js +40 -191
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-configs.d.ts +13 -78
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-configs.js +30 -52
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.d.ts +0 -1
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/mock-pipeline.d.ts +20 -0
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/mock-pipeline.js +432 -0
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.d.ts +99 -12
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +188 -169
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/tier-scheduler.js +7 -17
- package/dist/lib/external/mcp/handlers/bootstrap/refine.js +8 -0
- package/dist/lib/external/mcp/handlers/bootstrap/shared/async-fill-helpers.d.ts +46 -0
- package/dist/lib/external/mcp/handlers/bootstrap/shared/async-fill-helpers.js +58 -0
- package/dist/lib/external/mcp/handlers/bootstrap/shared/audit-helpers.d.ts +25 -0
- package/dist/lib/external/mcp/handlers/bootstrap/shared/audit-helpers.js +47 -0
- package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +50 -12
- package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +30 -10
- package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-text.js +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap/shared/handler-types.d.ts +24 -0
- package/dist/lib/external/mcp/handlers/bootstrap/shared/handler-types.js +14 -0
- package/dist/lib/external/mcp/handlers/bootstrap/shared/panorama-utils.d.ts +14 -0
- package/dist/lib/external/mcp/handlers/bootstrap/shared/panorama-utils.js +48 -0
- package/dist/lib/external/mcp/handlers/bootstrap/shared/session-helpers.d.ts +21 -0
- package/dist/lib/external/mcp/handlers/bootstrap/shared/session-helpers.js +45 -0
- package/dist/lib/external/mcp/handlers/bootstrap/shared/skill-generator.d.ts +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap/shared/target-file-map.d.ts +27 -0
- package/dist/lib/external/mcp/handlers/bootstrap/shared/target-file-map.js +44 -0
- package/dist/lib/external/mcp/handlers/bootstrap-external.d.ts +23 -10
- package/dist/lib/external/mcp/handlers/bootstrap-external.js +41 -51
- package/dist/lib/external/mcp/handlers/bootstrap-internal.d.ts +2 -0
- package/dist/lib/external/mcp/handlers/bootstrap-internal.js +117 -82
- package/dist/lib/external/mcp/handlers/consolidated.d.ts +4 -4
- package/dist/lib/external/mcp/handlers/consolidated.js +108 -332
- package/dist/lib/external/mcp/handlers/dimension-complete-external.js +71 -2
- package/dist/lib/external/mcp/handlers/evolve-external.d.ts +54 -0
- package/dist/lib/external/mcp/handlers/evolve-external.js +229 -0
- package/dist/lib/external/mcp/handlers/knowledge.js +30 -5
- package/dist/lib/external/mcp/handlers/rescan-external.d.ts +76 -0
- package/dist/lib/external/mcp/handlers/rescan-external.js +335 -0
- package/dist/lib/external/mcp/handlers/rescan-internal.d.ts +120 -0
- package/dist/lib/external/mcp/handlers/rescan-internal.js +359 -0
- package/dist/lib/external/mcp/handlers/search.d.ts +6 -5
- package/dist/lib/external/mcp/handlers/search.js +6 -5
- package/dist/lib/external/mcp/handlers/types.d.ts +2 -1
- package/dist/lib/external/mcp/handlers/wiki-external.js +2 -2
- package/dist/lib/external/mcp/tools.d.ts +8 -18
- package/dist/lib/external/mcp/tools.js +58 -2
- package/dist/lib/http/routes/ai.js +111 -30
- package/dist/lib/http/routes/candidates.js +11 -4
- package/dist/lib/http/routes/commands.js +10 -1
- package/dist/lib/http/routes/health.js +11 -0
- package/dist/lib/http/routes/knowledge.js +122 -1
- package/dist/lib/http/routes/modules.js +52 -3
- package/dist/lib/http/routes/panorama.js +16 -4
- package/dist/lib/http/routes/recipes.js +7 -0
- package/dist/lib/http/utils/routeHelpers.js +2 -1
- package/dist/lib/infrastructure/cache/CacheCoordinator.d.ts +41 -0
- package/dist/lib/infrastructure/cache/CacheCoordinator.js +105 -0
- package/dist/lib/infrastructure/database/migrations/006_lifecycle_transition_events.d.ts +7 -0
- package/dist/lib/infrastructure/database/migrations/006_lifecycle_transition_events.js +28 -0
- package/dist/lib/infrastructure/vector/HnswVectorAdapter.js +1 -1
- package/dist/lib/injection/ServiceContainer.d.ts +6 -5
- package/dist/lib/injection/ServiceContainer.js +64 -25
- package/dist/lib/injection/ServiceMap.d.ts +10 -1
- package/dist/lib/injection/modules/AiModule.d.ts +6 -9
- package/dist/lib/injection/modules/AiModule.js +82 -39
- package/dist/lib/injection/modules/KnowledgeModule.js +15 -1
- package/dist/lib/injection/modules/PanoramaModule.js +1 -1
- package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +4 -0
- package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +16 -1
- package/dist/lib/service/bootstrap/BootstrapEventEmitter.d.ts +3 -2
- package/dist/lib/service/bootstrap/BootstrapEventEmitter.js +1 -1
- package/dist/lib/service/bootstrap/DeliveryVerifier.d.ts +51 -0
- package/dist/lib/service/bootstrap/DeliveryVerifier.js +163 -0
- package/dist/lib/service/bootstrap/UiStartupTasks.d.ts +5 -0
- package/dist/lib/service/bootstrap/UiStartupTasks.js +20 -0
- package/dist/lib/service/bootstrap/bootstrap-event-types.d.ts +54 -0
- package/dist/lib/service/bootstrap/bootstrap-event-types.js +10 -0
- package/dist/lib/service/cleanup/CleanupService.d.ts +132 -0
- package/dist/lib/service/cleanup/CleanupService.js +571 -0
- package/dist/lib/service/delivery/AgentInstructionsGenerator.js +39 -43
- package/dist/lib/service/delivery/FileProtection.d.ts +20 -0
- package/dist/lib/service/delivery/FileProtection.js +54 -0
- package/dist/lib/service/delivery/SkillsSyncer.js +16 -21
- package/dist/lib/service/evolution/ContentPatcher.d.ts +44 -0
- package/dist/lib/service/evolution/ContentPatcher.js +310 -0
- package/dist/lib/service/evolution/ProposalExecutor.d.ts +4 -0
- package/dist/lib/service/evolution/ProposalExecutor.js +77 -13
- package/dist/lib/service/evolution/RecipeLifecycleSupervisor.d.ts +64 -0
- package/dist/lib/service/evolution/RecipeLifecycleSupervisor.js +458 -0
- package/dist/lib/service/evolution/RecipeRelevanceAuditor.d.ts +89 -0
- package/dist/lib/service/evolution/RecipeRelevanceAuditor.js +492 -0
- package/dist/lib/service/evolution/createSupersedeProposal.d.ts +44 -0
- package/dist/lib/service/evolution/createSupersedeProposal.js +81 -0
- package/dist/lib/service/guard/ComplianceReporter.d.ts +4 -0
- package/dist/lib/service/guard/ComplianceReporter.js +51 -0
- package/dist/lib/service/guard/GuardCheckEngine.js +5 -4
- package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +6 -0
- package/dist/lib/service/knowledge/CodeEntityGraph.js +16 -0
- package/dist/lib/service/knowledge/ConfidenceRouter.js +1 -1
- package/dist/lib/service/knowledge/KnowledgeService.d.ts +11 -1
- package/dist/lib/service/knowledge/KnowledgeService.js +67 -14
- package/dist/lib/service/knowledge/RecipeProductionGateway.d.ts +225 -0
- package/dist/lib/service/knowledge/RecipeProductionGateway.js +384 -0
- package/dist/lib/service/module/ModuleService.js +10 -19
- package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +10 -1
- package/dist/lib/service/panorama/CouplingAnalyzer.js +44 -2
- package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +4 -3
- package/dist/lib/service/panorama/DimensionAnalyzer.js +40 -151
- package/dist/lib/service/panorama/LayerInferrer.d.ts +16 -1
- package/dist/lib/service/panorama/LayerInferrer.js +118 -1
- package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +9 -0
- package/dist/lib/service/panorama/ModuleDiscoverer.js +58 -2
- package/dist/lib/service/panorama/PanoramaAggregator.d.ts +6 -2
- package/dist/lib/service/panorama/PanoramaAggregator.js +84 -6
- package/dist/lib/service/panorama/PanoramaScanner.js +28 -0
- package/dist/lib/service/panorama/PanoramaService.js +10 -5
- package/dist/lib/service/panorama/PanoramaTypes.d.ts +38 -0
- package/dist/lib/service/panorama/RoleRefiner.d.ts +2 -0
- package/dist/lib/service/panorama/RoleRefiner.js +41 -0
- package/dist/lib/service/panorama/TechStackProfiler.d.ts +13 -0
- package/dist/lib/service/panorama/TechStackProfiler.js +191 -0
- package/dist/lib/service/search/BM25Scorer.d.ts +2 -2
- package/dist/lib/service/search/SearchEngine.d.ts +11 -10
- package/dist/lib/service/search/SearchEngine.js +38 -36
- package/dist/lib/service/search/SearchTypes.d.ts +14 -8
- package/dist/lib/service/search/SearchTypes.js +1 -1
- package/dist/lib/service/search/tokenizer.d.ts +1 -1
- package/dist/lib/service/search/tokenizer.js +2 -2
- package/dist/lib/service/skills/SignalCollector.d.ts +1 -0
- package/dist/lib/service/skills/SignalCollector.js +6 -5
- package/dist/lib/service/vector/ContextualEnricher.d.ts +1 -0
- package/dist/lib/service/vector/ContextualEnricher.js +4 -0
- package/dist/lib/shared/LanguageService.js +3 -0
- package/dist/lib/shared/developer-identity.d.ts +18 -0
- package/dist/lib/shared/developer-identity.js +62 -0
- package/dist/lib/shared/schemas/common.d.ts +4 -4
- package/dist/lib/shared/schemas/http-requests.d.ts +20 -18
- package/dist/lib/shared/schemas/http-requests.js +17 -6
- package/dist/lib/shared/schemas/mcp-tools.d.ts +32 -2
- package/dist/lib/shared/schemas/mcp-tools.js +38 -0
- package/dist/lib/types/evolution.d.ts +135 -0
- package/dist/lib/types/evolution.js +6 -0
- package/dist/lib/types/graph-shared.d.ts +25 -0
- package/dist/lib/types/graph-shared.js +7 -0
- package/dist/lib/types/knowledge-wire.d.ts +132 -0
- package/dist/lib/types/knowledge-wire.js +7 -0
- package/dist/lib/types/project-snapshot-builder.d.ts +19 -0
- package/dist/lib/types/project-snapshot-builder.js +189 -0
- package/dist/lib/types/project-snapshot.d.ts +399 -0
- package/dist/lib/types/project-snapshot.js +17 -0
- package/dist/lib/types/search-wire.d.ts +46 -0
- package/dist/lib/types/search-wire.js +7 -0
- package/dist/lib/types/snapshot-views.d.ts +58 -0
- package/dist/lib/types/snapshot-views.js +103 -0
- package/package.json +1 -1
- package/skills/autosnippet-recipes/SKILL.md +1 -1
- package/templates/instructions/agent-static.md +2 -0
- package/templates/instructions/conventions.md +3 -1
- package/templates/recipes-setup/README.md +2 -2
- package/dashboard/dist/assets/icons-BJ2mUBi8.js +0 -1
- package/dashboard/dist/assets/index-B659K9t5.js +0 -128
- package/dashboard/dist/assets/index-NCm40PMD.css +0 -1
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/noAiFallback.d.ts +0 -169
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/noAiFallback.js +0 -727
- package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-sop.d.ts +0 -370
- package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-sop.js +0 -821
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* autosnippet_bootstrap 已迁移到 bootstrap-external.js(外部 Agent 路径)。
|
|
10
10
|
*/
|
|
11
11
|
import { getRequiredFieldsDescription } from '#domain/knowledge/FieldSpec.js';
|
|
12
|
+
import { getDeveloperIdentity } from '#shared/developer-identity.js';
|
|
12
13
|
import { envelope } from '../envelope.js';
|
|
13
14
|
import * as browseHandlers from './browse.js';
|
|
14
15
|
import * as guardHandlers from './guard.js';
|
|
@@ -192,10 +193,10 @@ export async function consolidatedSkill(ctx, args) {
|
|
|
192
193
|
* 统一提交管线:单条与批量走同一代码路径。
|
|
193
194
|
*
|
|
194
195
|
* 流程:
|
|
195
|
-
* 1.
|
|
196
|
-
* 2.
|
|
197
|
-
* 3.
|
|
198
|
-
* 4.
|
|
196
|
+
* 1. 限流
|
|
197
|
+
* 2. V3 字段增强(MCP 特有预处理)
|
|
198
|
+
* 3. RecipeProductionGateway.create() — 统一管道
|
|
199
|
+
* 4. Bootstrap session 追踪
|
|
199
200
|
* 5. 返回统一结果
|
|
200
201
|
*
|
|
201
202
|
* 设计原则:
|
|
@@ -205,8 +206,7 @@ export async function consolidatedSkill(ctx, args) {
|
|
|
205
206
|
* - 单条/批量完全一致的校验与融合逻辑
|
|
206
207
|
*/
|
|
207
208
|
export async function enhancedSubmitKnowledge(ctx, args) {
|
|
208
|
-
const {
|
|
209
|
-
const { UnifiedValidator } = await import('#domain/knowledge/UnifiedValidator.js');
|
|
209
|
+
const { RecipeProductionGateway } = await import('#service/knowledge/RecipeProductionGateway.js');
|
|
210
210
|
const items = args.items;
|
|
211
211
|
if (!items || !Array.isArray(items) || items.length === 0) {
|
|
212
212
|
return envelope({
|
|
@@ -234,259 +234,85 @@ export async function enhancedSubmitKnowledge(ctx, args) {
|
|
|
234
234
|
meta: { tool: 'autosnippet_submit_knowledge' },
|
|
235
235
|
});
|
|
236
236
|
}
|
|
237
|
-
// ── Step 2:
|
|
238
|
-
|
|
239
|
-
const
|
|
240
|
-
const rejectedItems = [];
|
|
241
|
-
for (let i = 0; i < items.length; i++) {
|
|
242
|
-
const item = items[i];
|
|
243
|
-
// 合并批次级选项到条目
|
|
237
|
+
// ── Step 2: MCP 特有预处理 ──
|
|
238
|
+
// 注入批次级选项到各条目
|
|
239
|
+
for (const item of items) {
|
|
244
240
|
if (!item.source) {
|
|
245
241
|
item.source = source;
|
|
246
242
|
}
|
|
247
243
|
if (dimensionId && !item.dimensionId) {
|
|
248
244
|
item.dimensionId = dimensionId;
|
|
249
245
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
index: i,
|
|
259
|
-
title: item.title || '(untitled)',
|
|
260
|
-
errors: validation.errors,
|
|
261
|
-
warnings: validation.warnings,
|
|
262
|
-
});
|
|
263
|
-
// 记录拒绝到 BootstrapSession tracker
|
|
264
|
-
_trackRejection(ctx, item, dimensionId);
|
|
265
|
-
// 仍然记录标题/指纹防止后续条目重复
|
|
266
|
-
validator.recordSubmission(item.title, item.content?.pattern);
|
|
246
|
+
}
|
|
247
|
+
// 获取 bootstrapSession 已提交标题用于跨维度去重
|
|
248
|
+
let existingTitles;
|
|
249
|
+
try {
|
|
250
|
+
const sessionManager = ctx.container.get('bootstrapSessionManager');
|
|
251
|
+
const bsSession = sessionManager?.getSession?.();
|
|
252
|
+
if (bsSession?.submissionTracker?.getAllSubmittedTitles) {
|
|
253
|
+
existingTitles = bsSession.submissionTracker.getAllSubmittedTitles();
|
|
267
254
|
}
|
|
268
255
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
const allMissing = [...new Set(rejectedItems.flatMap((it) => it.errors))];
|
|
272
|
-
return envelope({
|
|
273
|
-
success: false,
|
|
274
|
-
errorCode: 'INCOMPLETE_SUBMISSION',
|
|
275
|
-
message: `全部 ${items.length} 条知识条目被拒绝。请在单次调用中补齐所有字段后重新提交。`,
|
|
276
|
-
data: {
|
|
277
|
-
rejectedItems,
|
|
278
|
-
requiredFields: getRequiredFieldsDescription(),
|
|
279
|
-
commonErrors: allMissing,
|
|
280
|
-
},
|
|
281
|
-
meta: { tool: 'autosnippet_submit_knowledge' },
|
|
282
|
-
});
|
|
256
|
+
catch {
|
|
257
|
+
/* best effort */
|
|
283
258
|
}
|
|
284
|
-
// ── Step 3:
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
submittableItems.push(...validItems);
|
|
290
|
-
}
|
|
291
|
-
else {
|
|
292
|
-
const advisor = ctx.container.get('consolidationAdvisor');
|
|
293
|
-
if (!advisor || typeof advisor.analyzeBatch !== 'function') {
|
|
294
|
-
// DI 未注册时降级放行
|
|
295
|
-
submittableItems.push(...validItems);
|
|
296
|
-
}
|
|
297
|
-
else {
|
|
298
|
-
try {
|
|
299
|
-
const candidates = validItems.map((v) => ({
|
|
300
|
-
title: v.item.title || '',
|
|
301
|
-
description: v.item.description || '',
|
|
302
|
-
doClause: v.item.doClause,
|
|
303
|
-
dontClause: v.item.dontClause,
|
|
304
|
-
coreCode: v.item.coreCode,
|
|
305
|
-
category: v.item.category,
|
|
306
|
-
trigger: v.item.trigger,
|
|
307
|
-
whenClause: v.item.whenClause,
|
|
308
|
-
kind: v.item.kind,
|
|
309
|
-
content: v.item.content,
|
|
310
|
-
}));
|
|
311
|
-
const batchAdvice = advisor.analyzeBatch(candidates);
|
|
312
|
-
// 尝试获取 ProposalRepository 以创建 Proposal(降级容忍)
|
|
313
|
-
let proposalRepo = null;
|
|
314
|
-
try {
|
|
315
|
-
proposalRepo = ctx.container.get('proposalRepository') ?? null;
|
|
316
|
-
}
|
|
317
|
-
catch {
|
|
318
|
-
/* ProposalRepository 未注册,降级为旧的 blocked 模式 */
|
|
319
|
-
}
|
|
320
|
-
for (const { index: adviceIdx, advice } of batchAdvice.items) {
|
|
321
|
-
const validEntry = validItems[adviceIdx];
|
|
322
|
-
if (advice.action === 'create') {
|
|
323
|
-
submittableItems.push(validEntry);
|
|
324
|
-
}
|
|
325
|
-
else if (proposalRepo &&
|
|
326
|
-
(advice.action === 'merge' ||
|
|
327
|
-
advice.action === 'reorganize' ||
|
|
328
|
-
advice.action === 'insufficient')) {
|
|
329
|
-
// 创建 Proposal 而非简单 block — 系统后续自动处理
|
|
330
|
-
const proposal = _createProposalFromAdvice(proposalRepo, advice, validEntry.item);
|
|
331
|
-
if (proposal) {
|
|
332
|
-
createdProposals.push(proposal);
|
|
333
|
-
}
|
|
334
|
-
else {
|
|
335
|
-
// Proposal 创建失败(可能去重)→ 仍作为 blocked 返回
|
|
336
|
-
blockedItems.push({
|
|
337
|
-
index: validEntry.index,
|
|
338
|
-
title: validEntry.item.title || '(untitled)',
|
|
339
|
-
consolidation: advice,
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
else {
|
|
344
|
-
blockedItems.push({
|
|
345
|
-
index: validEntry.index,
|
|
346
|
-
title: validEntry.item.title || '(untitled)',
|
|
347
|
-
consolidation: advice,
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
// 将批次内重叠信息附加到 blockedItems
|
|
352
|
-
if (batchAdvice.internalOverlaps.length > 0) {
|
|
353
|
-
for (const overlap of batchAdvice.internalOverlaps) {
|
|
354
|
-
const entryB = validItems[overlap.indexB];
|
|
355
|
-
// 如果 B 已经被放行,降级为 blocked(批次内碎片化警告)
|
|
356
|
-
const alreadyBlocked = blockedItems.some((b) => b.index === entryB.index);
|
|
357
|
-
if (!alreadyBlocked) {
|
|
358
|
-
const entryA = validItems[overlap.indexA];
|
|
359
|
-
blockedItems.push({
|
|
360
|
-
index: entryB.index,
|
|
361
|
-
title: entryB.item.title || '(untitled)',
|
|
362
|
-
consolidation: {
|
|
363
|
-
action: 'merge',
|
|
364
|
-
reason: `与同批次候选「${entryA.item.title || ''}」高度重叠(${(overlap.similarity * 100).toFixed(0)}%),建议合并后再提交。`,
|
|
365
|
-
internalOverlap: true,
|
|
366
|
-
overlapWith: {
|
|
367
|
-
index: entryA.index,
|
|
368
|
-
title: entryA.item.title,
|
|
369
|
-
similarity: overlap.similarity,
|
|
370
|
-
},
|
|
371
|
-
},
|
|
372
|
-
});
|
|
373
|
-
// 从 submittable 中移除
|
|
374
|
-
const subIdx = submittableItems.findIndex((s) => s.index === entryB.index);
|
|
375
|
-
if (subIdx >= 0) {
|
|
376
|
-
submittableItems.splice(subIdx, 1);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
catch {
|
|
383
|
-
// 分析失败时静默降级放行
|
|
384
|
-
submittableItems.push(...validItems.filter((v) => !submittableItems.some((s) => s.index === v.index)));
|
|
385
|
-
}
|
|
386
|
-
}
|
|
259
|
+
// ── Step 3: 委托 RecipeProductionGateway 统一管道 ──
|
|
260
|
+
const knowledgeService = ctx.container.get('knowledgeService');
|
|
261
|
+
let consolidationAdvisor = null;
|
|
262
|
+
try {
|
|
263
|
+
consolidationAdvisor = ctx.container.get('consolidationAdvisor');
|
|
387
264
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
const successIds = [];
|
|
391
|
-
const submitErrors = [];
|
|
392
|
-
for (const { index, item } of submittableItems) {
|
|
393
|
-
try {
|
|
394
|
-
const result = await submitKnowledge(ctx, {
|
|
395
|
-
...item,
|
|
396
|
-
source: item.source || source,
|
|
397
|
-
client_id: clientId,
|
|
398
|
-
});
|
|
399
|
-
if (result?.success && result.data?.id) {
|
|
400
|
-
successCount++;
|
|
401
|
-
const recipeId = result.data.id;
|
|
402
|
-
successIds.push(recipeId);
|
|
403
|
-
_trackSubmission(ctx, item, dimensionId, recipeId);
|
|
404
|
-
}
|
|
405
|
-
else {
|
|
406
|
-
submitErrors.push({
|
|
407
|
-
index,
|
|
408
|
-
title: item.title || '(untitled)',
|
|
409
|
-
error: result?.message || 'unknown error',
|
|
410
|
-
});
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
catch (err) {
|
|
414
|
-
submitErrors.push({
|
|
415
|
-
index,
|
|
416
|
-
title: item.title || '(untitled)',
|
|
417
|
-
error: err instanceof Error ? err.message : String(err),
|
|
418
|
-
});
|
|
419
|
-
}
|
|
265
|
+
catch {
|
|
266
|
+
/* not registered */
|
|
420
267
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
targetRecipeId: supersedes,
|
|
453
|
-
relatedRecipeIds: successIds,
|
|
454
|
-
confidence: 0.8,
|
|
455
|
-
source: 'ide-agent',
|
|
456
|
-
description: `Agent 声明新 Recipe [${successIds.join(', ')}] 替代旧 Recipe [${supersedes}]。观察窗口内将对比新旧表现。`,
|
|
457
|
-
evidence: [
|
|
458
|
-
{
|
|
459
|
-
snapshotAt: Date.now(),
|
|
460
|
-
newRecipeIds: successIds,
|
|
461
|
-
declaredBy: 'agent',
|
|
462
|
-
},
|
|
463
|
-
],
|
|
464
|
-
});
|
|
465
|
-
if (proposal) {
|
|
466
|
-
createdProposals.push({
|
|
467
|
-
proposalId: proposal.id,
|
|
468
|
-
type: 'supersede',
|
|
469
|
-
targetRecipe: { id: supersedes, title: supersedes },
|
|
470
|
-
status: proposal.status,
|
|
471
|
-
expiresAt: proposal.expiresAt,
|
|
472
|
-
message: `已创建替代提案:新 Recipe 将在观察窗口到期后自动替代旧 Recipe [${supersedes}]。`,
|
|
473
|
-
});
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
}
|
|
268
|
+
let proposalRepository = null;
|
|
269
|
+
try {
|
|
270
|
+
proposalRepository = ctx.container.get('proposalRepository');
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
/* not registered */
|
|
274
|
+
}
|
|
275
|
+
const gateway = new RecipeProductionGateway({
|
|
276
|
+
knowledgeService,
|
|
277
|
+
projectRoot,
|
|
278
|
+
consolidationAdvisor: consolidationAdvisor ?? null,
|
|
279
|
+
proposalRepository: proposalRepository ?? null,
|
|
280
|
+
});
|
|
281
|
+
const gatewayResult = await gateway.create({
|
|
282
|
+
source: 'mcp-external',
|
|
283
|
+
items: items,
|
|
284
|
+
options: {
|
|
285
|
+
skipSimilarityCheck: true,
|
|
286
|
+
skipConsolidation,
|
|
287
|
+
supersedes,
|
|
288
|
+
existingTitles,
|
|
289
|
+
userId: getDeveloperIdentity(),
|
|
290
|
+
},
|
|
291
|
+
});
|
|
292
|
+
// ── Step 4: Bootstrap session 追踪 ──
|
|
293
|
+
for (const created of gatewayResult.created) {
|
|
294
|
+
_trackSubmission(ctx, items.find((it) => it.title === created.title) || {}, dimensionId, created.id);
|
|
295
|
+
}
|
|
296
|
+
for (const rej of gatewayResult.rejected) {
|
|
297
|
+
const item = items[rej.index] || {};
|
|
298
|
+
_trackRejection(ctx, item, dimensionId);
|
|
477
299
|
}
|
|
478
300
|
// ── Step 5: 构建统一响应 ──
|
|
301
|
+
const successCount = gatewayResult.created.length;
|
|
479
302
|
const data = {
|
|
480
303
|
count: successCount,
|
|
481
304
|
total: items.length,
|
|
482
305
|
};
|
|
483
|
-
if (
|
|
484
|
-
data.ids =
|
|
485
|
-
}
|
|
486
|
-
if (
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
306
|
+
if (gatewayResult.created.length > 0) {
|
|
307
|
+
data.ids = gatewayResult.created.map((c) => c.id);
|
|
308
|
+
}
|
|
309
|
+
if (gatewayResult.rejected.length > 0) {
|
|
310
|
+
const rejectedItems = gatewayResult.rejected.map((r) => ({
|
|
311
|
+
index: r.index,
|
|
312
|
+
title: r.title,
|
|
313
|
+
errors: r.errors,
|
|
314
|
+
warnings: r.warnings,
|
|
315
|
+
}));
|
|
490
316
|
const allMissing = [...new Set(rejectedItems.flatMap((it) => it.errors))];
|
|
491
317
|
data.rejectedItems = rejectedItems;
|
|
492
318
|
data.rejectedSummary = {
|
|
@@ -495,13 +321,34 @@ export async function enhancedSubmitKnowledge(ctx, args) {
|
|
|
495
321
|
message: `${rejectedItems.length}/${items.length} 条知识条目因校验未通过被拒绝。`,
|
|
496
322
|
};
|
|
497
323
|
}
|
|
498
|
-
if (
|
|
499
|
-
data.blockedItems =
|
|
324
|
+
if (gatewayResult.blocked.length > 0) {
|
|
325
|
+
data.blockedItems = gatewayResult.blocked;
|
|
500
326
|
data.blockedSummary = {
|
|
501
|
-
blockedCount:
|
|
502
|
-
message: `${
|
|
327
|
+
blockedCount: gatewayResult.blocked.length,
|
|
328
|
+
message: `${gatewayResult.blocked.length} 条因融合分析被阻塞(与已有 Recipe 重叠或实质性不足)。设 skipConsolidation: true 可跳过。`,
|
|
503
329
|
};
|
|
504
330
|
}
|
|
331
|
+
const createdProposals = [];
|
|
332
|
+
for (const m of gatewayResult.merged) {
|
|
333
|
+
createdProposals.push({
|
|
334
|
+
proposalId: m.proposalId,
|
|
335
|
+
type: m.type,
|
|
336
|
+
targetRecipe: { id: m.targetRecipeId, title: m.targetTitle },
|
|
337
|
+
status: m.status,
|
|
338
|
+
expiresAt: m.expiresAt,
|
|
339
|
+
message: m.message,
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
if (gatewayResult.supersedeProposal) {
|
|
343
|
+
createdProposals.push({
|
|
344
|
+
proposalId: gatewayResult.supersedeProposal.proposalId,
|
|
345
|
+
type: 'supersede',
|
|
346
|
+
targetRecipe: { id: supersedes, title: supersedes },
|
|
347
|
+
status: 'observing',
|
|
348
|
+
expiresAt: 0,
|
|
349
|
+
message: `已创建替代提案。`,
|
|
350
|
+
});
|
|
351
|
+
}
|
|
505
352
|
if (createdProposals.length > 0) {
|
|
506
353
|
data.proposals = createdProposals;
|
|
507
354
|
data.proposalSummary = {
|
|
@@ -509,6 +356,21 @@ export async function enhancedSubmitKnowledge(ctx, args) {
|
|
|
509
356
|
message: `${createdProposals.length} 条已创建进化提案,系统将在观察窗口到期后自动执行。无需额外操作。`,
|
|
510
357
|
};
|
|
511
358
|
}
|
|
359
|
+
// 全部拒绝 → 特殊错误响应
|
|
360
|
+
if (successCount === 0 && gatewayResult.rejected.length === items.length) {
|
|
361
|
+
const allMissing = [...new Set(gatewayResult.rejected.flatMap((it) => it.errors))];
|
|
362
|
+
return envelope({
|
|
363
|
+
success: false,
|
|
364
|
+
errorCode: 'INCOMPLETE_SUBMISSION',
|
|
365
|
+
message: `全部 ${items.length} 条知识条目被拒绝。请在单次调用中补齐所有字段后重新提交。`,
|
|
366
|
+
data: {
|
|
367
|
+
rejectedItems: data.rejectedItems,
|
|
368
|
+
requiredFields: getRequiredFieldsDescription(),
|
|
369
|
+
commonErrors: allMissing,
|
|
370
|
+
},
|
|
371
|
+
meta: { tool: 'autosnippet_submit_knowledge' },
|
|
372
|
+
});
|
|
373
|
+
}
|
|
512
374
|
const allOk = successCount === items.length;
|
|
513
375
|
return envelope({
|
|
514
376
|
success: successCount > 0,
|
|
@@ -559,89 +421,3 @@ function _trackRejection(ctx, item, dimensionId) {
|
|
|
559
421
|
/* best effort */
|
|
560
422
|
}
|
|
561
423
|
}
|
|
562
|
-
// ── Proposal 创建辅助函数 ───────────────────────────
|
|
563
|
-
/**
|
|
564
|
-
* 将 ConsolidationAdvisor 分析结果转为 evolution_proposals 记录。
|
|
565
|
-
*
|
|
566
|
-
* merge → Proposal(type: merge, target: 已有 Recipe)
|
|
567
|
-
* reorganize → Proposal(type: reorganize, 高风险 → pending 等开发者确认)
|
|
568
|
-
* insufficient → Proposal(type: enhance, target: 最相似 Recipe)
|
|
569
|
-
*/
|
|
570
|
-
function _createProposalFromAdvice(repo, advice, candidateItem) {
|
|
571
|
-
const evidence = [
|
|
572
|
-
{
|
|
573
|
-
snapshotAt: Date.now(),
|
|
574
|
-
candidateTitle: candidateItem.title,
|
|
575
|
-
candidateCategory: candidateItem.category,
|
|
576
|
-
analysisReason: advice.reason,
|
|
577
|
-
mergeDirection: advice.mergeDirection,
|
|
578
|
-
},
|
|
579
|
-
];
|
|
580
|
-
if (advice.action === 'merge' && advice.targetRecipe) {
|
|
581
|
-
const proposal = repo.create({
|
|
582
|
-
type: 'merge',
|
|
583
|
-
targetRecipeId: advice.targetRecipe.id,
|
|
584
|
-
confidence: advice.confidence,
|
|
585
|
-
source: 'ide-agent',
|
|
586
|
-
description: advice.reason,
|
|
587
|
-
evidence,
|
|
588
|
-
});
|
|
589
|
-
if (!proposal) {
|
|
590
|
-
return null;
|
|
591
|
-
}
|
|
592
|
-
return {
|
|
593
|
-
proposalId: proposal.id,
|
|
594
|
-
type: 'merge',
|
|
595
|
-
targetRecipe: { id: advice.targetRecipe.id, title: advice.targetRecipe.title },
|
|
596
|
-
status: proposal.status,
|
|
597
|
-
expiresAt: proposal.expiresAt,
|
|
598
|
-
message: `已为「${advice.targetRecipe.title}」创建融合提案,${proposal.status === 'observing' ? '观察窗口 72h 后自动执行' : '等待开发者确认'}。`,
|
|
599
|
-
};
|
|
600
|
-
}
|
|
601
|
-
if (advice.action === 'reorganize' && advice.reorganizeTargets?.length) {
|
|
602
|
-
const target = advice.reorganizeTargets[0];
|
|
603
|
-
const proposal = repo.create({
|
|
604
|
-
type: 'reorganize',
|
|
605
|
-
targetRecipeId: target.id,
|
|
606
|
-
relatedRecipeIds: advice.reorganizeTargets.slice(1).map((t) => t.id),
|
|
607
|
-
confidence: advice.confidence,
|
|
608
|
-
source: 'ide-agent',
|
|
609
|
-
description: advice.reason,
|
|
610
|
-
evidence,
|
|
611
|
-
});
|
|
612
|
-
if (!proposal) {
|
|
613
|
-
return null;
|
|
614
|
-
}
|
|
615
|
-
return {
|
|
616
|
-
proposalId: proposal.id,
|
|
617
|
-
type: 'reorganize',
|
|
618
|
-
targetRecipe: { id: target.id, title: target.title },
|
|
619
|
-
status: proposal.status,
|
|
620
|
-
expiresAt: proposal.expiresAt,
|
|
621
|
-
message: `已为 ${advice.reorganizeTargets.length} 条 Recipe 创建重组提案,需开发者在 Dashboard 确认。`,
|
|
622
|
-
};
|
|
623
|
-
}
|
|
624
|
-
if (advice.action === 'insufficient' && advice.coveredBy?.length) {
|
|
625
|
-
const target = advice.coveredBy[0];
|
|
626
|
-
const proposal = repo.create({
|
|
627
|
-
type: 'enhance',
|
|
628
|
-
targetRecipeId: target.id,
|
|
629
|
-
confidence: advice.confidence,
|
|
630
|
-
source: 'ide-agent',
|
|
631
|
-
description: advice.reason,
|
|
632
|
-
evidence,
|
|
633
|
-
});
|
|
634
|
-
if (!proposal) {
|
|
635
|
-
return null;
|
|
636
|
-
}
|
|
637
|
-
return {
|
|
638
|
-
proposalId: proposal.id,
|
|
639
|
-
type: 'enhance',
|
|
640
|
-
targetRecipe: { id: target.id, title: target.title },
|
|
641
|
-
status: proposal.status,
|
|
642
|
-
expiresAt: proposal.expiresAt,
|
|
643
|
-
message: `候选独立价值不足,已创建增强提案建议补充到「${target.title}」。`,
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
return null;
|
|
647
|
-
}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import Logger from '#infra/logging/Logger.js';
|
|
18
18
|
import { BootstrapEventEmitter } from '#service/bootstrap/BootstrapEventEmitter.js';
|
|
19
|
+
import { getDeveloperIdentity } from '#shared/developer-identity.js';
|
|
19
20
|
import { envelope } from '../envelope.js';
|
|
20
21
|
import { saveDimensionCheckpoint } from './bootstrap/pipeline/checkpoint.js';
|
|
21
22
|
import { BOOTSTRAP_COMPLETE_ACTIONS } from './bootstrap/shared/dimension-text.js';
|
|
@@ -160,7 +161,7 @@ export async function dimensionComplete(ctx, args) {
|
|
|
160
161
|
await knowledgeService.update(recipeId, {
|
|
161
162
|
category: dimensionId,
|
|
162
163
|
tags: newTags,
|
|
163
|
-
}, { userId:
|
|
164
|
+
}, { userId: getDeveloperIdentity() });
|
|
164
165
|
recipesBound++;
|
|
165
166
|
}
|
|
166
167
|
}
|
|
@@ -298,8 +299,9 @@ export async function dimensionComplete(ctx, args) {
|
|
|
298
299
|
emitter.emitAllComplete(session.id, progress.total, 'external-agent');
|
|
299
300
|
}
|
|
300
301
|
// ═══════════════════════════════════════════════════════════
|
|
301
|
-
// 6.5 Bootstrap 完成后,自动触发 Delivery / Wiki / SemanticMemory (R4/R5/R6)
|
|
302
|
+
// 6.5 Bootstrap 完成后,自动触发 Delivery / Panorama / Wiki / SemanticMemory (R4/R4.5/R5/R6)
|
|
302
303
|
// ═══════════════════════════════════════════════════════════
|
|
304
|
+
let deliveryVerification = null;
|
|
303
305
|
if (isComplete) {
|
|
304
306
|
// R4: 自动触发 Cursor Delivery
|
|
305
307
|
try {
|
|
@@ -318,6 +320,44 @@ export async function dimensionComplete(ctx, args) {
|
|
|
318
320
|
catch (e) {
|
|
319
321
|
logger.warn(`[DimensionComplete] Auto CursorDelivery failed (non-blocking): ${e instanceof Error ? e.message : String(e)}`);
|
|
320
322
|
}
|
|
323
|
+
// R4+: DeliveryVerifier — 交付完整性检查
|
|
324
|
+
try {
|
|
325
|
+
const { DeliveryVerifier } = await import('#service/bootstrap/DeliveryVerifier.js');
|
|
326
|
+
const { resolveProjectRoot } = await import('#shared/resolveProjectRoot.js');
|
|
327
|
+
const projectRoot = resolveProjectRoot(ctx.container);
|
|
328
|
+
const verifier = new DeliveryVerifier(projectRoot);
|
|
329
|
+
const verification = verifier.verify();
|
|
330
|
+
if (!verification.allPassed) {
|
|
331
|
+
logger.warn('[DimensionComplete] Delivery verification incomplete', {
|
|
332
|
+
failures: verification.failures,
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
logger.info('[DimensionComplete] Delivery verification passed — all channels OK');
|
|
337
|
+
}
|
|
338
|
+
// 附加到响应中的 completionExtras
|
|
339
|
+
deliveryVerification = verification;
|
|
340
|
+
}
|
|
341
|
+
catch (e) {
|
|
342
|
+
logger.warn(`[DimensionComplete] DeliveryVerifier failed (non-blocking): ${e instanceof Error ? e.message : String(e)}`);
|
|
343
|
+
}
|
|
344
|
+
// R4.5: Panorama 数据刷新(冷启动完成后知识库已填充,需重新计算全景)
|
|
345
|
+
try {
|
|
346
|
+
const { getServiceContainer: getPanoramaContainer } = await import('#inject/ServiceContainer.js');
|
|
347
|
+
const panoramaContainer = getPanoramaContainer();
|
|
348
|
+
const panoramaService = panoramaContainer.services.panoramaService
|
|
349
|
+
? panoramaContainer.get('panoramaService')
|
|
350
|
+
: null;
|
|
351
|
+
if (panoramaService &&
|
|
352
|
+
typeof panoramaService.rescan === 'function') {
|
|
353
|
+
await panoramaService.rescan();
|
|
354
|
+
const overview = panoramaService.getOverview();
|
|
355
|
+
logger.info(`[DimensionComplete] Panorama refreshed — ${overview.moduleCount} modules, ${overview.gapCount} gaps`);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
catch (e) {
|
|
359
|
+
logger.warn(`[DimensionComplete] Panorama refresh failed (non-blocking): ${e instanceof Error ? e.message : String(e)}`);
|
|
360
|
+
}
|
|
321
361
|
// R5: 自动触发 Wiki 生成 (fire-and-forget)
|
|
322
362
|
setImmediate(async () => {
|
|
323
363
|
try {
|
|
@@ -392,6 +432,31 @@ export async function dimensionComplete(ctx, args) {
|
|
|
392
432
|
}
|
|
393
433
|
// Wiki 生成提示(冷启动完成时)
|
|
394
434
|
const nextActions = isComplete ? BOOTSTRAP_COMPLETE_ACTIONS : undefined;
|
|
435
|
+
// §9: 子包覆盖校验 — 检查 referencedFiles 是否覆盖了关键本地子包
|
|
436
|
+
let subpackageCoverageWarning;
|
|
437
|
+
try {
|
|
438
|
+
const snapshotCache = session.getSnapshotCache?.();
|
|
439
|
+
const localPkgs = snapshotCache?.localPackageModules;
|
|
440
|
+
if (localPkgs && localPkgs.length > 0 && referencedFiles.length > 0) {
|
|
441
|
+
const uncoveredPkgs = [];
|
|
442
|
+
for (const pkg of localPkgs) {
|
|
443
|
+
const pkgPrefix = pkg.packageName.replace(/\/$/, '');
|
|
444
|
+
const covered = referencedFiles.some((f) => f.includes(pkgPrefix) || f.includes(pkg.name));
|
|
445
|
+
if (!covered) {
|
|
446
|
+
uncoveredPkgs.push(pkg.name);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
if (uncoveredPkgs.length > 0) {
|
|
450
|
+
subpackageCoverageWarning =
|
|
451
|
+
`本维度未覆盖以下本地子包: ${uncoveredPkgs.join(', ')}。` +
|
|
452
|
+
`建议在分析中纳入这些模块的源码,以确保知识库完整性。`;
|
|
453
|
+
logger.info(`[DimensionComplete] Subpackage coverage gap for "${dimensionId}": ${uncoveredPkgs.join(', ')}`);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
catch {
|
|
458
|
+
/* best effort */
|
|
459
|
+
}
|
|
395
460
|
// v2: 为下游维度构建结构化提示 (基于累积证据)
|
|
396
461
|
let evidenceHints;
|
|
397
462
|
if (!isComplete &&
|
|
@@ -450,6 +515,10 @@ export async function dimensionComplete(ctx, args) {
|
|
|
450
515
|
qualityFeedback,
|
|
451
516
|
// v2: 跨维度证据 (供后续维度利用)
|
|
452
517
|
evidenceHints,
|
|
518
|
+
// v3: 子包覆盖校验警告
|
|
519
|
+
subpackageCoverageWarning,
|
|
520
|
+
// v3.1: 交付完整性验证 (仅 bootstrap 完成时)
|
|
521
|
+
deliveryVerification: isComplete ? deliveryVerification : undefined,
|
|
453
522
|
nextActions,
|
|
454
523
|
},
|
|
455
524
|
meta: {
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Handler — autosnippet_evolve (批量 Recipe 进化决策)
|
|
3
|
+
*
|
|
4
|
+
* 双入口工具:
|
|
5
|
+
* - Rescan 模式: 每个维度内先 evolve 再 gap-fill,与内部 Agent Pipeline 一致
|
|
6
|
+
* - 独立模式: 用户通过提示词触发,验证已有 Recipe 的有效性
|
|
7
|
+
*
|
|
8
|
+
* 三种决策委托给 evolution-tools.ts 中已有的 handler 实现:
|
|
9
|
+
* - propose_evolution → ProposalRepository.create (观察窗口)
|
|
10
|
+
* - confirm_deprecation → RecipeLifecycleSupervisor.transition → deprecated (优先) / KnowledgeService.deprecate (回退)
|
|
11
|
+
* - skip → 不变更状态,skip(still_valid) 刷新 stats.lastVerifiedAt
|
|
12
|
+
*
|
|
13
|
+
* @module handlers/evolve-external
|
|
14
|
+
*/
|
|
15
|
+
import type { ServiceContainer } from '#inject/ServiceContainer.js';
|
|
16
|
+
import type { EvolveInput } from '#shared/schemas/mcp-tools.js';
|
|
17
|
+
/** MCP handler context */
|
|
18
|
+
interface McpContext {
|
|
19
|
+
container: ServiceContainer;
|
|
20
|
+
logger: {
|
|
21
|
+
info(msg: string, meta?: Record<string, unknown>): void;
|
|
22
|
+
warn(msg: string, meta?: Record<string, unknown>): void;
|
|
23
|
+
};
|
|
24
|
+
startedAt?: number;
|
|
25
|
+
[key: string]: unknown;
|
|
26
|
+
}
|
|
27
|
+
interface EvolveResult {
|
|
28
|
+
processed: number;
|
|
29
|
+
proposed: number;
|
|
30
|
+
deprecated: number;
|
|
31
|
+
skipped: number;
|
|
32
|
+
refreshed: number;
|
|
33
|
+
quotaChange: {
|
|
34
|
+
freed: number;
|
|
35
|
+
occupied: number;
|
|
36
|
+
};
|
|
37
|
+
errors: Array<{
|
|
38
|
+
recipeId: string;
|
|
39
|
+
error: string;
|
|
40
|
+
}>;
|
|
41
|
+
}
|
|
42
|
+
export declare function evolveExternal(ctx: McpContext, args: EvolveInput): Promise<{
|
|
43
|
+
success: boolean;
|
|
44
|
+
errorCode: string | null;
|
|
45
|
+
message: string;
|
|
46
|
+
data: EvolveResult | null;
|
|
47
|
+
meta: {
|
|
48
|
+
source?: string | undefined;
|
|
49
|
+
responseTimeMs?: number | undefined;
|
|
50
|
+
version: string;
|
|
51
|
+
tool?: string | undefined;
|
|
52
|
+
};
|
|
53
|
+
}>;
|
|
54
|
+
export {};
|