autosnippet 3.3.0 → 3.3.3
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-BJ2mUBi8.js +1 -0
- package/dashboard/dist/assets/index-B659K9t5.js +128 -0
- package/dashboard/dist/assets/index-NCm40PMD.css +1 -0
- package/dashboard/dist/index.html +3 -3
- package/dist/bin/cli.d.ts +1 -0
- package/dist/bin/cli.js +284 -142
- package/dist/lib/agent/context/ExplorationTracker.d.ts +2 -0
- package/dist/lib/agent/context/ExplorationTracker.js +21 -3
- package/dist/lib/agent/core/ToolExecutionPipeline.d.ts +3 -1
- package/dist/lib/agent/core/ToolExecutionPipeline.js +8 -1
- package/dist/lib/agent/forge/DynamicComposer.d.ts +58 -0
- package/dist/lib/agent/forge/DynamicComposer.js +99 -0
- package/dist/lib/agent/forge/SandboxRunner.d.ts +60 -0
- package/dist/lib/agent/forge/SandboxRunner.js +251 -0
- package/dist/lib/agent/forge/TemporaryToolRegistry.d.ts +76 -0
- package/dist/lib/agent/forge/TemporaryToolRegistry.js +154 -0
- package/dist/lib/agent/forge/ToolForge.d.ts +92 -0
- package/dist/lib/agent/forge/ToolForge.js +239 -0
- package/dist/lib/agent/forge/ToolRequirementAnalyzer.d.ts +44 -0
- package/dist/lib/agent/forge/ToolRequirementAnalyzer.js +119 -0
- package/dist/lib/agent/tools/ToolRegistry.d.ts +2 -0
- package/dist/lib/agent/tools/ToolRegistry.js +4 -0
- package/dist/lib/agent/tools/composite.js +0 -1
- package/dist/lib/agent/tools/index.d.ts +2 -50
- package/dist/lib/agent/tools/index.js +2 -3
- package/dist/lib/agent/tools/lifecycle.d.ts +1 -58
- package/dist/lib/agent/tools/lifecycle.js +2 -75
- package/dist/lib/cli/KnowledgeSyncService.d.ts +26 -0
- package/dist/lib/cli/KnowledgeSyncService.js +33 -1
- package/dist/lib/cli/deploy/FileManifest.d.ts +0 -21
- package/dist/lib/cli/deploy/FileManifest.js +0 -11
- package/dist/lib/domain/knowledge/KnowledgeEntry.d.ts +10 -0
- package/dist/lib/domain/knowledge/KnowledgeEntry.js +2 -0
- package/dist/lib/domain/knowledge/Lifecycle.d.ts +19 -2
- package/dist/lib/domain/knowledge/Lifecycle.js +32 -6
- package/dist/lib/domain/knowledge/UnifiedValidator.d.ts +1 -5
- package/dist/lib/domain/knowledge/UnifiedValidator.js +7 -44
- package/dist/lib/domain/knowledge/values/Stats.d.ts +29 -0
- package/dist/lib/domain/knowledge/values/Stats.js +41 -0
- package/dist/lib/external/mcp/McpServer.d.ts +19 -38
- package/dist/lib/external/mcp/McpServer.js +145 -117
- package/dist/lib/external/mcp/autoApproveInjector.js +0 -2
- package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.d.ts +26 -1
- package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.js +41 -0
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +49 -0
- package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +3 -0
- package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +27 -0
- package/dist/lib/external/mcp/handlers/bootstrap/skills.js +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap-external.js +1 -0
- package/dist/lib/external/mcp/handlers/bootstrap-internal.js +2 -0
- package/dist/lib/external/mcp/handlers/browse.d.ts +1 -0
- package/dist/lib/external/mcp/handlers/browse.js +2 -1
- package/dist/lib/external/mcp/handlers/consolidated.d.ts +117 -6
- package/dist/lib/external/mcp/handlers/consolidated.js +251 -71
- package/dist/lib/external/mcp/handlers/guard.d.ts +150 -0
- package/dist/lib/external/mcp/handlers/guard.js +239 -5
- package/dist/lib/external/mcp/handlers/knowledge.d.ts +0 -29
- package/dist/lib/external/mcp/handlers/knowledge.js +1 -76
- package/dist/lib/external/mcp/handlers/panorama.d.ts +36 -0
- package/dist/lib/external/mcp/handlers/panorama.js +156 -0
- package/dist/lib/external/mcp/handlers/system.d.ts +2 -54
- package/dist/lib/external/mcp/handlers/system.js +3 -113
- package/dist/lib/external/mcp/handlers/task.d.ts +13 -24
- package/dist/lib/external/mcp/handlers/task.js +218 -557
- package/dist/lib/external/mcp/handlers/types.d.ts +91 -8
- package/dist/lib/external/mcp/handlers/types.js +18 -1
- package/dist/lib/external/mcp/handlers/wiki-external.d.ts +18 -1
- package/dist/lib/external/mcp/handlers/wiki-external.js +16 -1
- package/dist/lib/external/mcp/tools.d.ts +18 -24
- package/dist/lib/external/mcp/tools.js +132 -159
- package/dist/lib/http/HttpServer.js +52 -0
- package/dist/lib/http/middleware/validate.js +7 -3
- package/dist/lib/http/routes/audit.d.ts +8 -0
- package/dist/lib/http/routes/audit.js +51 -0
- package/dist/lib/http/routes/guardReport.d.ts +10 -0
- package/dist/lib/http/routes/guardReport.js +143 -0
- package/dist/lib/http/routes/knowledge.js +32 -1
- package/dist/lib/http/routes/panorama.d.ts +11 -0
- package/dist/lib/http/routes/panorama.js +322 -0
- package/dist/lib/http/routes/signals.d.ts +10 -0
- package/dist/lib/http/routes/signals.js +104 -0
- package/dist/lib/http/routes/task.d.ts +2 -3
- package/dist/lib/http/routes/task.js +17 -347
- package/dist/lib/http/routes/violations.js +1 -1
- package/dist/lib/infrastructure/audit/AuditLogger.d.ts +6 -1
- package/dist/lib/infrastructure/audit/AuditLogger.js +14 -1
- package/dist/lib/infrastructure/database/drizzle/schema.d.ts +202 -504
- package/dist/lib/infrastructure/database/drizzle/schema.js +38 -69
- package/dist/lib/infrastructure/database/migrations/004_evolution_proposals.d.ts +8 -0
- package/dist/lib/infrastructure/database/migrations/004_evolution_proposals.js +43 -0
- package/dist/lib/infrastructure/database/migrations/005_recipe_source_refs.d.ts +9 -0
- package/dist/lib/infrastructure/database/migrations/005_recipe_source_refs.js +24 -0
- package/dist/lib/infrastructure/logging/Logger.d.ts +2 -0
- package/dist/lib/infrastructure/logging/Logger.js +34 -7
- package/dist/lib/infrastructure/monitoring/ErrorTracker.js +3 -1
- package/dist/lib/infrastructure/monitoring/PerformanceMonitor.d.ts +2 -2
- package/dist/lib/infrastructure/monitoring/PerformanceMonitor.js +12 -10
- package/dist/lib/infrastructure/notification/LarkNotifier.d.ts +24 -0
- package/dist/lib/infrastructure/notification/LarkNotifier.js +97 -0
- package/dist/lib/infrastructure/report/ReportStore.d.ts +45 -0
- package/dist/lib/infrastructure/report/ReportStore.js +133 -0
- package/dist/lib/infrastructure/signal/SignalAggregator.d.ts +18 -0
- package/dist/lib/infrastructure/signal/SignalAggregator.js +84 -0
- package/dist/lib/infrastructure/signal/SignalBridge.d.ts +13 -0
- package/dist/lib/infrastructure/signal/SignalBridge.js +20 -0
- package/dist/lib/infrastructure/signal/SignalBus.d.ts +63 -0
- package/dist/lib/infrastructure/signal/SignalBus.js +106 -0
- package/dist/lib/infrastructure/signal/SignalTraceWriter.d.ts +36 -0
- package/dist/lib/infrastructure/signal/SignalTraceWriter.js +130 -0
- package/dist/lib/infrastructure/vector/HnswVectorAdapter.js +18 -2
- package/dist/lib/injection/ServiceContainer.js +8 -0
- package/dist/lib/injection/ServiceMap.d.ts +16 -10
- package/dist/lib/injection/modules/AgentModule.d.ts +1 -1
- package/dist/lib/injection/modules/AgentModule.js +7 -1
- package/dist/lib/injection/modules/AppModule.d.ts +1 -1
- package/dist/lib/injection/modules/AppModule.js +4 -13
- package/dist/lib/injection/modules/GuardModule.js +27 -2
- package/dist/lib/injection/modules/InfraModule.d.ts +0 -1
- package/dist/lib/injection/modules/InfraModule.js +9 -7
- package/dist/lib/injection/modules/KnowledgeModule.d.ts +5 -0
- package/dist/lib/injection/modules/KnowledgeModule.js +131 -0
- package/dist/lib/injection/modules/PanoramaModule.d.ts +18 -0
- package/dist/lib/injection/modules/PanoramaModule.js +76 -0
- package/dist/lib/injection/modules/SignalModule.d.ts +10 -0
- package/dist/lib/injection/modules/SignalModule.js +84 -0
- package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +1 -0
- package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +6 -0
- package/dist/lib/service/bootstrap/BootstrapTaskManager.d.ts +3 -1
- package/dist/lib/service/bootstrap/BootstrapTaskManager.js +20 -1
- package/dist/lib/service/bootstrap/UiStartupTasks.d.ts +45 -0
- package/dist/lib/service/bootstrap/UiStartupTasks.js +101 -0
- package/dist/lib/service/delivery/AgentInstructionsGenerator.js +4 -5
- package/dist/lib/service/delivery/CursorDeliveryPipeline.d.ts +3 -1
- package/dist/lib/service/delivery/CursorDeliveryPipeline.js +13 -10
- package/dist/lib/service/delivery/RulesGenerator.js +3 -2
- package/dist/lib/service/evolution/ConsolidationAdvisor.d.ts +114 -0
- package/dist/lib/service/evolution/ConsolidationAdvisor.js +542 -0
- package/dist/lib/service/evolution/ContradictionDetector.d.ts +54 -0
- package/dist/lib/service/evolution/ContradictionDetector.js +253 -0
- package/dist/lib/service/evolution/DecayDetector.d.ts +71 -0
- package/dist/lib/service/evolution/DecayDetector.js +244 -0
- package/dist/lib/service/evolution/EnhancementSuggester.d.ts +38 -0
- package/dist/lib/service/evolution/EnhancementSuggester.js +220 -0
- package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +82 -0
- package/dist/lib/service/evolution/KnowledgeMetabolism.js +167 -0
- package/dist/lib/service/evolution/RedundancyAnalyzer.d.ts +53 -0
- package/dist/lib/service/evolution/RedundancyAnalyzer.js +210 -0
- package/dist/lib/service/evolution/StagingManager.d.ts +57 -0
- package/dist/lib/service/evolution/StagingManager.js +201 -0
- package/dist/lib/service/guard/ComplianceReporter.d.ts +42 -2
- package/dist/lib/service/guard/ComplianceReporter.js +43 -5
- package/dist/lib/service/guard/CoverageAnalyzer.d.ts +54 -0
- package/dist/lib/service/guard/CoverageAnalyzer.js +149 -0
- package/dist/lib/service/guard/GuardCheckEngine.d.ts +42 -0
- package/dist/lib/service/guard/GuardCheckEngine.js +465 -14
- package/dist/lib/service/guard/GuardFeedbackLoop.d.ts +3 -0
- package/dist/lib/service/guard/GuardFeedbackLoop.js +9 -0
- package/dist/lib/service/guard/ReverseGuard.d.ts +73 -0
- package/dist/lib/service/guard/ReverseGuard.js +256 -0
- package/dist/lib/service/guard/RuleLearner.d.ts +12 -0
- package/dist/lib/service/guard/RuleLearner.js +38 -0
- package/dist/lib/service/guard/UncertaintyCollector.d.ts +83 -0
- package/dist/lib/service/guard/UncertaintyCollector.js +149 -0
- package/dist/lib/service/guard/ViolationsStore.d.ts +1 -0
- package/dist/lib/service/guard/ViolationsStore.js +33 -3
- package/dist/lib/service/knowledge/ConfidenceRouter.d.ts +13 -0
- package/dist/lib/service/knowledge/ConfidenceRouter.js +14 -0
- package/dist/lib/service/knowledge/KnowledgeService.js +22 -4
- package/dist/lib/service/knowledge/SourceRefReconciler.d.ts +68 -0
- package/dist/lib/service/knowledge/SourceRefReconciler.js +309 -0
- package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +27 -0
- package/dist/lib/service/panorama/CouplingAnalyzer.js +192 -0
- package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +28 -0
- package/dist/lib/service/panorama/DimensionAnalyzer.js +320 -0
- package/dist/lib/service/panorama/LayerInferrer.d.ts +19 -0
- package/dist/lib/service/panorama/LayerInferrer.js +182 -0
- package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +24 -0
- package/dist/lib/service/panorama/ModuleDiscoverer.js +185 -0
- package/dist/lib/service/panorama/PanoramaAggregator.d.ts +29 -0
- package/dist/lib/service/panorama/PanoramaAggregator.js +228 -0
- package/dist/lib/service/panorama/PanoramaScanner.d.ts +52 -0
- package/dist/lib/service/panorama/PanoramaScanner.js +188 -0
- package/dist/lib/service/panorama/PanoramaService.d.ts +125 -0
- package/dist/lib/service/panorama/PanoramaService.js +363 -0
- package/dist/lib/service/panorama/PanoramaTypes.d.ts +134 -0
- package/dist/lib/service/panorama/PanoramaTypes.js +6 -0
- package/dist/lib/service/panorama/RoleRefiner.d.ts +48 -0
- package/dist/lib/service/panorama/RoleRefiner.js +535 -0
- package/dist/lib/service/search/BM25Scorer.d.ts +2 -2
- package/dist/lib/service/search/CoarseRanker.d.ts +7 -6
- package/dist/lib/service/search/CoarseRanker.js +11 -10
- package/dist/lib/service/search/FieldWeightedScorer.d.ts +81 -0
- package/dist/lib/service/search/FieldWeightedScorer.js +318 -0
- package/dist/lib/service/search/MultiSignalRanker.d.ts +3 -2
- package/dist/lib/service/search/MultiSignalRanker.js +17 -1
- package/dist/lib/service/search/SearchEngine.d.ts +9 -7
- package/dist/lib/service/search/SearchEngine.js +67 -10
- package/dist/lib/service/search/SearchTypes.d.ts +25 -3
- package/dist/lib/service/search/SearchTypes.js +6 -1
- package/dist/lib/service/signal/HitRecorder.d.ts +68 -0
- package/dist/lib/service/signal/HitRecorder.js +173 -0
- package/dist/lib/service/skills/SignalCollector.d.ts +3 -1
- package/dist/lib/service/skills/SignalCollector.js +31 -1
- package/dist/lib/service/task/IntentExtractor.d.ts +66 -0
- package/dist/lib/service/task/IntentExtractor.js +256 -0
- package/dist/lib/service/task/PrimeSearchPipeline.d.ts +54 -0
- package/dist/lib/service/task/PrimeSearchPipeline.js +113 -0
- package/dist/lib/service/vector/VectorService.d.ts +3 -0
- package/dist/lib/service/vector/VectorService.js +38 -4
- package/dist/lib/shared/schemas/mcp-tools.d.ts +41 -96
- package/dist/lib/shared/schemas/mcp-tools.js +59 -119
- package/dist/scripts/analyze-signals.d.ts +20 -0
- package/dist/scripts/analyze-signals.js +155 -0
- package/dist/scripts/diagnose-mcp.js +1 -1
- package/package.json +1 -1
- package/skills/autosnippet-create/SKILL.md +98 -89
- package/skills/autosnippet-devdocs/SKILL.md +55 -57
- package/templates/claude-code/hooks/autosnippet-session.sh +10 -15
- package/templates/cursor-hooks/hooks/session-start.sh +1 -1
- package/templates/guard-ci.yml +2 -2
- package/templates/instructions/agent-static.md +2 -1
- package/templates/instructions/conventions.md +5 -6
- package/templates/recipes-setup/README.md +1 -2
- package/templates/recipes-setup/_template.md +39 -39
- package/dashboard/dist/assets/icons-BofcEZ3f.js +0 -1
- package/dashboard/dist/assets/index-D0whuycy.css +0 -1
- package/dashboard/dist/assets/index-SiN1GChm.js +0 -128
- package/dist/lib/domain/task/Task.d.ts +0 -140
- package/dist/lib/domain/task/Task.js +0 -254
- package/dist/lib/domain/task/TaskDependency.d.ts +0 -23
- package/dist/lib/domain/task/TaskDependency.js +0 -34
- package/dist/lib/domain/task/TaskIdGenerator.d.ts +0 -40
- package/dist/lib/domain/task/TaskIdGenerator.js +0 -75
- package/dist/lib/domain/task/index.d.ts +0 -4
- package/dist/lib/domain/task/index.js +0 -4
- package/dist/lib/infrastructure/database/migrations/002_add_tasks.d.ts +0 -11
- package/dist/lib/infrastructure/database/migrations/002_add_tasks.js +0 -86
- package/dist/lib/repository/task/TaskRepository.impl.d.ts +0 -171
- package/dist/lib/repository/task/TaskRepository.impl.js +0 -347
- package/dist/lib/service/task/TaskGraphService.d.ts +0 -222
- package/dist/lib/service/task/TaskGraphService.js +0 -597
- package/dist/lib/service/task/TaskKnowledgeBridge.d.ts +0 -95
- package/dist/lib/service/task/TaskKnowledgeBridge.js +0 -298
- package/dist/lib/service/task/TaskReadyEngine.d.ts +0 -84
- package/dist/lib/service/task/TaskReadyEngine.js +0 -115
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* lifecycle.js — 生命周期操作类工具 (
|
|
2
|
+
* lifecycle.js — 生命周期操作类工具 (10)
|
|
3
3
|
*
|
|
4
4
|
* 16. submit_knowledge 提交候选项
|
|
5
|
-
* 16b. save_document 保存开发文档
|
|
6
5
|
* 17. approve_candidate 批准候选
|
|
7
6
|
* 18. reject_candidate 驳回候选
|
|
8
7
|
* 19. publish_recipe 发布 Recipe
|
|
@@ -45,13 +44,6 @@ export interface SubmitKnowledgeParams {
|
|
|
45
44
|
_category?: string;
|
|
46
45
|
[key: string]: unknown;
|
|
47
46
|
}
|
|
48
|
-
export interface SaveDocumentParams {
|
|
49
|
-
title: string;
|
|
50
|
-
markdown: string;
|
|
51
|
-
description?: string;
|
|
52
|
-
tags?: string[];
|
|
53
|
-
scope?: string;
|
|
54
|
-
}
|
|
55
47
|
export declare const submitCandidate: {
|
|
56
48
|
name: string;
|
|
57
49
|
description: string;
|
|
@@ -145,55 +137,6 @@ export declare const submitCandidate: {
|
|
|
145
137
|
};
|
|
146
138
|
handler: (params: SubmitKnowledgeParams, ctx: ToolHandlerContext) => Promise<any>;
|
|
147
139
|
};
|
|
148
|
-
export declare const saveDocument: {
|
|
149
|
-
name: string;
|
|
150
|
-
description: string;
|
|
151
|
-
parameters: {
|
|
152
|
-
type: string;
|
|
153
|
-
properties: {
|
|
154
|
-
title: {
|
|
155
|
-
type: string;
|
|
156
|
-
description: string;
|
|
157
|
-
};
|
|
158
|
-
markdown: {
|
|
159
|
-
type: string;
|
|
160
|
-
description: string;
|
|
161
|
-
};
|
|
162
|
-
description: {
|
|
163
|
-
type: string;
|
|
164
|
-
description: string;
|
|
165
|
-
};
|
|
166
|
-
tags: {
|
|
167
|
-
type: string;
|
|
168
|
-
items: {
|
|
169
|
-
type: string;
|
|
170
|
-
};
|
|
171
|
-
description: string;
|
|
172
|
-
};
|
|
173
|
-
scope: {
|
|
174
|
-
type: string;
|
|
175
|
-
enum: string[];
|
|
176
|
-
description: string;
|
|
177
|
-
};
|
|
178
|
-
};
|
|
179
|
-
required: string[];
|
|
180
|
-
};
|
|
181
|
-
handler: (params: SaveDocumentParams, ctx: ToolHandlerContext) => Promise<{
|
|
182
|
-
error: boolean;
|
|
183
|
-
message: string;
|
|
184
|
-
id?: undefined;
|
|
185
|
-
title?: undefined;
|
|
186
|
-
lifecycle?: undefined;
|
|
187
|
-
knowledgeType?: undefined;
|
|
188
|
-
} | {
|
|
189
|
-
id: any;
|
|
190
|
-
title: any;
|
|
191
|
-
lifecycle: string;
|
|
192
|
-
knowledgeType: string;
|
|
193
|
-
message: string;
|
|
194
|
-
error?: undefined;
|
|
195
|
-
}>;
|
|
196
|
-
};
|
|
197
140
|
export declare const approveCandidate: {
|
|
198
141
|
name: string;
|
|
199
142
|
description: string;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* lifecycle.js — 生命周期操作类工具 (
|
|
2
|
+
* lifecycle.js — 生命周期操作类工具 (10)
|
|
3
3
|
*
|
|
4
4
|
* 16. submit_knowledge 提交候选项
|
|
5
|
-
* 16b. save_document 保存开发文档
|
|
6
5
|
* 17. approve_candidate 批准候选
|
|
7
6
|
* 18. reject_candidate 驳回候选
|
|
8
7
|
* 19. publish_recipe 发布 Recipe
|
|
@@ -106,7 +105,6 @@ export const submitCandidate = {
|
|
|
106
105
|
existingFingerprints: ctx._submittedPatterns || new Set(),
|
|
107
106
|
});
|
|
108
107
|
const validResult = validator.validate(params, {
|
|
109
|
-
mode: 'strict',
|
|
110
108
|
systemInjectedFields: getSystemInjectedFields(),
|
|
111
109
|
});
|
|
112
110
|
if (!validResult.pass) {
|
|
@@ -184,78 +182,7 @@ export const submitCandidate = {
|
|
|
184
182
|
};
|
|
185
183
|
// ────────────────────────────────────────────────────────────
|
|
186
184
|
// 16b. save_document — 保存开发文档到知识库
|
|
187
|
-
//
|
|
188
|
-
export const saveDocument = {
|
|
189
|
-
name: 'save_document',
|
|
190
|
-
description: '保存开发文档到知识库(架构设计、排查报告、决策记录、调研笔记等)。仅需 title + markdown,无需 Cursor Delivery 字段。文档自动发布,可通过 autosnippet_search 检索。',
|
|
191
|
-
parameters: {
|
|
192
|
-
type: 'object',
|
|
193
|
-
properties: {
|
|
194
|
-
title: { type: 'string', description: '文档标题' },
|
|
195
|
-
markdown: { type: 'string', description: '文档 Markdown 全文' },
|
|
196
|
-
description: { type: 'string', description: '一句话摘要(可选)' },
|
|
197
|
-
tags: {
|
|
198
|
-
type: 'array',
|
|
199
|
-
items: { type: 'string' },
|
|
200
|
-
description: '标签: adr, debug-report, design-doc, research, performance 等',
|
|
201
|
-
},
|
|
202
|
-
scope: {
|
|
203
|
-
type: 'string',
|
|
204
|
-
enum: ['universal', 'project-specific'],
|
|
205
|
-
description: '适用范围(默认 project-specific)',
|
|
206
|
-
},
|
|
207
|
-
},
|
|
208
|
-
required: ['title', 'markdown'],
|
|
209
|
-
},
|
|
210
|
-
handler: async (params, ctx) => {
|
|
211
|
-
const knowledgeService = ctx.container.get('knowledgeService');
|
|
212
|
-
const data = {
|
|
213
|
-
title: params.title.trim(),
|
|
214
|
-
description: params.description || '',
|
|
215
|
-
knowledgeType: 'dev-document',
|
|
216
|
-
kind: 'fact',
|
|
217
|
-
source: 'agent',
|
|
218
|
-
scope: params.scope || 'project-specific',
|
|
219
|
-
tags: params.tags || [],
|
|
220
|
-
content: {
|
|
221
|
-
markdown: params.markdown,
|
|
222
|
-
pattern: '',
|
|
223
|
-
},
|
|
224
|
-
trigger: '',
|
|
225
|
-
doClause: '',
|
|
226
|
-
dontClause: '',
|
|
227
|
-
whenClause: '',
|
|
228
|
-
topicHint: '',
|
|
229
|
-
coreCode: '',
|
|
230
|
-
reasoning: {
|
|
231
|
-
whyStandard: 'Agent development document',
|
|
232
|
-
sources: ['agent'],
|
|
233
|
-
confidence: 0.8,
|
|
234
|
-
},
|
|
235
|
-
};
|
|
236
|
-
// ── UnifiedValidator 校验(自动检测 document 模式)──
|
|
237
|
-
const validator = new UnifiedValidator();
|
|
238
|
-
const vr = validator.validate(data, { skipUniqueness: true });
|
|
239
|
-
if (!vr.pass) {
|
|
240
|
-
return { error: true, message: `文档校验失败: ${vr.errors.join('; ')}` };
|
|
241
|
-
}
|
|
242
|
-
const saved = await knowledgeService.create(data, { userId: 'agent' });
|
|
243
|
-
// 自动发布(文档不需要人工审核)
|
|
244
|
-
try {
|
|
245
|
-
await knowledgeService.publish(saved.id, { userId: 'agent' });
|
|
246
|
-
}
|
|
247
|
-
catch {
|
|
248
|
-
/* best effort */
|
|
249
|
-
}
|
|
250
|
-
return {
|
|
251
|
-
id: saved.id,
|
|
252
|
-
title: saved.title,
|
|
253
|
-
lifecycle: 'active',
|
|
254
|
-
knowledgeType: 'dev-document',
|
|
255
|
-
message: `文档「${saved.title}」已保存到知识库`,
|
|
256
|
-
};
|
|
257
|
-
},
|
|
258
|
-
};
|
|
185
|
+
// ── (已删除: save_document — 已合并到 submit_knowledge 统一管线) ──
|
|
259
186
|
// ────────────────────────────────────────────────────────────
|
|
260
187
|
// 17. approve_candidate
|
|
261
188
|
// ────────────────────────────────────────────────────────────
|
|
@@ -14,12 +14,38 @@
|
|
|
14
14
|
* - 内部: SetupService.stepDatabase() 委托调用(skipViolations = true)
|
|
15
15
|
*/
|
|
16
16
|
import Logger from '../infrastructure/logging/Logger.js';
|
|
17
|
+
import type { ApplyReport, ReconcileReport, RepairReport } from '../service/knowledge/SourceRefReconciler.js';
|
|
18
|
+
export interface SyncAllReport {
|
|
19
|
+
synced: number;
|
|
20
|
+
created: number;
|
|
21
|
+
updated: number;
|
|
22
|
+
violations: string[];
|
|
23
|
+
orphaned: string[];
|
|
24
|
+
skipped: number;
|
|
25
|
+
reconcileReport?: ReconcileReport;
|
|
26
|
+
repairReport?: RepairReport;
|
|
27
|
+
applyReport?: ApplyReport;
|
|
28
|
+
}
|
|
17
29
|
export declare class KnowledgeSyncService {
|
|
18
30
|
candidatesDir: string;
|
|
19
31
|
logger: ReturnType<typeof Logger.getInstance>;
|
|
20
32
|
projectRoot: string;
|
|
21
33
|
recipesDir: string;
|
|
22
34
|
constructor(projectRoot: string);
|
|
35
|
+
/**
|
|
36
|
+
* 完整同步入口 — sync + reconcile + repair
|
|
37
|
+
*
|
|
38
|
+
* asd sync CLI 和 asd ui 启动都调用此方法。
|
|
39
|
+
*
|
|
40
|
+
* @param db better-sqlite3 原始句柄
|
|
41
|
+
* @param opts 同步选项
|
|
42
|
+
* @returns 包含 sync + reconcile + repair 报告的综合结果
|
|
43
|
+
*/
|
|
44
|
+
syncAll(db: Parameters<KnowledgeSyncService['sync']>[0], opts?: {
|
|
45
|
+
dryRun?: boolean;
|
|
46
|
+
force?: boolean;
|
|
47
|
+
skipViolations?: boolean;
|
|
48
|
+
}): Promise<SyncAllReport>;
|
|
23
49
|
/**
|
|
24
50
|
* 执行增量同步:.md → DB(knowledge_entries 表)
|
|
25
51
|
*
|
|
@@ -19,6 +19,7 @@ import path from 'node:path';
|
|
|
19
19
|
import { CANDIDATES_DIR, RECIPES_DIR } from '../infrastructure/config/Defaults.js';
|
|
20
20
|
import Logger from '../infrastructure/logging/Logger.js';
|
|
21
21
|
import { computeKnowledgeHash, parseKnowledgeMarkdown, } from '../service/knowledge/KnowledgeFileWriter.js';
|
|
22
|
+
import { SourceRefReconciler } from '../service/knowledge/SourceRefReconciler.js';
|
|
22
23
|
export class KnowledgeSyncService {
|
|
23
24
|
candidatesDir;
|
|
24
25
|
logger;
|
|
@@ -30,6 +31,37 @@ export class KnowledgeSyncService {
|
|
|
30
31
|
this.candidatesDir = path.join(projectRoot, CANDIDATES_DIR);
|
|
31
32
|
this.logger = Logger.getInstance();
|
|
32
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* 完整同步入口 — sync + reconcile + repair
|
|
36
|
+
*
|
|
37
|
+
* asd sync CLI 和 asd ui 启动都调用此方法。
|
|
38
|
+
*
|
|
39
|
+
* @param db better-sqlite3 原始句柄
|
|
40
|
+
* @param opts 同步选项
|
|
41
|
+
* @returns 包含 sync + reconcile + repair 报告的综合结果
|
|
42
|
+
*/
|
|
43
|
+
async syncAll(db, opts = {}) {
|
|
44
|
+
// 1. .md → DB 同步
|
|
45
|
+
const syncReport = this.sync(db, opts);
|
|
46
|
+
const report = { ...syncReport };
|
|
47
|
+
// 2. 填充/验证 recipe_source_refs 桥接表
|
|
48
|
+
try {
|
|
49
|
+
const reconciler = new SourceRefReconciler(this.projectRoot, db);
|
|
50
|
+
report.reconcileReport = reconciler.reconcile({ force: opts.force });
|
|
51
|
+
// 3. git rename 修复
|
|
52
|
+
report.repairReport = await reconciler.repairRenames();
|
|
53
|
+
// 4. 写回修复
|
|
54
|
+
if (report.repairReport.renamed > 0) {
|
|
55
|
+
report.applyReport = reconciler.applyRepairs();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
this.logger.warn('KnowledgeSyncService: sourceRef reconcile failed (non-blocking)', {
|
|
60
|
+
error: err.message,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return report;
|
|
64
|
+
}
|
|
33
65
|
/**
|
|
34
66
|
* 执行增量同步:.md → DB(knowledge_entries 表)
|
|
35
67
|
*
|
|
@@ -89,7 +121,7 @@ export class KnowledgeSyncService {
|
|
|
89
121
|
if (!dryRun) {
|
|
90
122
|
const existed = this._entryExists(db, parsed.id);
|
|
91
123
|
const row = this._buildDbRow(parsed, relPath, content);
|
|
92
|
-
upsertStmt
|
|
124
|
+
upsertStmt?.run(...Object.values(row));
|
|
93
125
|
if (existed) {
|
|
94
126
|
report.updated++;
|
|
95
127
|
}
|
|
@@ -35,7 +35,6 @@ export declare const MANIFEST: ({
|
|
|
35
35
|
generate?: undefined;
|
|
36
36
|
src?: undefined;
|
|
37
37
|
chmod?: undefined;
|
|
38
|
-
cleanup?: undefined;
|
|
39
38
|
resolveDest?: undefined;
|
|
40
39
|
requireDir?: undefined;
|
|
41
40
|
} | {
|
|
@@ -48,7 +47,6 @@ export declare const MANIFEST: ({
|
|
|
48
47
|
jsonKey?: undefined;
|
|
49
48
|
src?: undefined;
|
|
50
49
|
chmod?: undefined;
|
|
51
|
-
cleanup?: undefined;
|
|
52
50
|
resolveDest?: undefined;
|
|
53
51
|
requireDir?: undefined;
|
|
54
52
|
} | {
|
|
@@ -61,7 +59,6 @@ export declare const MANIFEST: ({
|
|
|
61
59
|
jsonKey?: undefined;
|
|
62
60
|
generate?: undefined;
|
|
63
61
|
chmod?: undefined;
|
|
64
|
-
cleanup?: undefined;
|
|
65
62
|
resolveDest?: undefined;
|
|
66
63
|
requireDir?: undefined;
|
|
67
64
|
} | {
|
|
@@ -74,20 +71,6 @@ export declare const MANIFEST: ({
|
|
|
74
71
|
chmod: boolean;
|
|
75
72
|
jsonKey?: undefined;
|
|
76
73
|
generate?: undefined;
|
|
77
|
-
cleanup?: undefined;
|
|
78
|
-
resolveDest?: undefined;
|
|
79
|
-
requireDir?: undefined;
|
|
80
|
-
} | {
|
|
81
|
-
id: string;
|
|
82
|
-
src: string;
|
|
83
|
-
dest: string;
|
|
84
|
-
strategy: string;
|
|
85
|
-
on: string;
|
|
86
|
-
category: string;
|
|
87
|
-
chmod: boolean;
|
|
88
|
-
cleanup: string[];
|
|
89
|
-
jsonKey?: undefined;
|
|
90
|
-
generate?: undefined;
|
|
91
74
|
resolveDest?: undefined;
|
|
92
75
|
requireDir?: undefined;
|
|
93
76
|
} | {
|
|
@@ -101,7 +84,6 @@ export declare const MANIFEST: ({
|
|
|
101
84
|
resolveDest: string;
|
|
102
85
|
jsonKey?: undefined;
|
|
103
86
|
generate?: undefined;
|
|
104
|
-
cleanup?: undefined;
|
|
105
87
|
requireDir?: undefined;
|
|
106
88
|
} | {
|
|
107
89
|
id: string;
|
|
@@ -114,7 +96,6 @@ export declare const MANIFEST: ({
|
|
|
114
96
|
jsonKey?: undefined;
|
|
115
97
|
generate?: undefined;
|
|
116
98
|
chmod?: undefined;
|
|
117
|
-
cleanup?: undefined;
|
|
118
99
|
resolveDest?: undefined;
|
|
119
100
|
} | {
|
|
120
101
|
id: string;
|
|
@@ -126,7 +107,6 @@ export declare const MANIFEST: ({
|
|
|
126
107
|
generate?: undefined;
|
|
127
108
|
src?: undefined;
|
|
128
109
|
chmod?: undefined;
|
|
129
|
-
cleanup?: undefined;
|
|
130
110
|
resolveDest?: undefined;
|
|
131
111
|
requireDir?: undefined;
|
|
132
112
|
} | {
|
|
@@ -139,7 +119,6 @@ export declare const MANIFEST: ({
|
|
|
139
119
|
jsonKey?: undefined;
|
|
140
120
|
src?: undefined;
|
|
141
121
|
chmod?: undefined;
|
|
142
|
-
cleanup?: undefined;
|
|
143
122
|
resolveDest?: undefined;
|
|
144
123
|
requireDir?: undefined;
|
|
145
124
|
})[];
|
|
@@ -88,17 +88,6 @@ export const MANIFEST = [
|
|
|
88
88
|
on: 'both',
|
|
89
89
|
category: 'cursor-commands',
|
|
90
90
|
},
|
|
91
|
-
// ═══ Claude Code ══════════════════════════════════════
|
|
92
|
-
{
|
|
93
|
-
id: 'claude-code',
|
|
94
|
-
src: 'claude-code/',
|
|
95
|
-
dest: '.claude/',
|
|
96
|
-
strategy: 'overwrite-dir',
|
|
97
|
-
on: 'both',
|
|
98
|
-
category: 'claude-hooks',
|
|
99
|
-
chmod: true,
|
|
100
|
-
cleanup: ['.claude/hooks.yaml'], // 清理旧格式文件
|
|
101
|
-
},
|
|
102
91
|
// ═══ Agent Instructions(全部从模板生成)═══════════════
|
|
103
92
|
{
|
|
104
93
|
id: 'copilot-instructions',
|
|
@@ -11,6 +11,7 @@ export interface KnowledgeEntryProps {
|
|
|
11
11
|
at: number;
|
|
12
12
|
}>;
|
|
13
13
|
autoApprovable?: boolean;
|
|
14
|
+
stagingDeadline?: number | null;
|
|
14
15
|
language?: string;
|
|
15
16
|
category?: string;
|
|
16
17
|
knowledgeType?: string;
|
|
@@ -62,6 +63,7 @@ export declare class KnowledgeEntry {
|
|
|
62
63
|
at: number;
|
|
63
64
|
}>;
|
|
64
65
|
autoApprovable: boolean;
|
|
66
|
+
stagingDeadline: number | null;
|
|
65
67
|
language: string;
|
|
66
68
|
category: string;
|
|
67
69
|
knowledgeType: string;
|
|
@@ -240,6 +242,14 @@ export declare class KnowledgeEntry {
|
|
|
240
242
|
guardHits: number;
|
|
241
243
|
searchHits: number;
|
|
242
244
|
authority: number;
|
|
245
|
+
lastHitAt: number | null;
|
|
246
|
+
lastSearchedAt: number | null;
|
|
247
|
+
lastGuardHitAt: number | null;
|
|
248
|
+
hitsLast30d: number;
|
|
249
|
+
hitsLast90d: number;
|
|
250
|
+
searchHitsLast30d: number;
|
|
251
|
+
version: number;
|
|
252
|
+
ruleFalsePositiveRate: number | null;
|
|
243
253
|
};
|
|
244
254
|
headers: string[];
|
|
245
255
|
headerPaths: string[];
|
|
@@ -10,6 +10,7 @@ export class KnowledgeEntry {
|
|
|
10
10
|
lifecycle;
|
|
11
11
|
lifecycleHistory;
|
|
12
12
|
autoApprovable;
|
|
13
|
+
stagingDeadline;
|
|
13
14
|
// Language & Classification
|
|
14
15
|
language;
|
|
15
16
|
category;
|
|
@@ -65,6 +66,7 @@ export class KnowledgeEntry {
|
|
|
65
66
|
this.lifecycle = normalizeLifecycle(props.lifecycle || Lifecycle.PENDING);
|
|
66
67
|
this.lifecycleHistory = props.lifecycleHistory || [];
|
|
67
68
|
this.autoApprovable = props.autoApprovable ?? false;
|
|
69
|
+
this.stagingDeadline = props.stagingDeadline ?? null;
|
|
68
70
|
// ── 语言与分类 ──
|
|
69
71
|
this.language = props.language || '';
|
|
70
72
|
this.category = props.category || '';
|
|
@@ -1,28 +1,45 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Lifecycle —
|
|
2
|
+
* Lifecycle — 知识实体生命周期状态机(六态版)
|
|
3
3
|
*
|
|
4
4
|
* pending — 待审核(所有新条目初始状态)
|
|
5
|
+
* staging — 暂存期(高置信度,Grace Period 后自动 active)
|
|
5
6
|
* active — 已发布(可被搜索/Guard/Export 消费)
|
|
7
|
+
* evolving — 进化中(有 EvolutionProposal 附着,内容待更新)
|
|
8
|
+
* decaying — 衰退观察(30d Grace + 3x 确认后 deprecated)
|
|
6
9
|
* deprecated — 已废弃
|
|
7
10
|
*/
|
|
8
11
|
export declare const Lifecycle: {
|
|
9
12
|
/** 待审核 */
|
|
10
13
|
PENDING: string;
|
|
14
|
+
/** 暂存期(高置信度,Grace Period 后自动 active) */
|
|
15
|
+
STAGING: string;
|
|
11
16
|
/** 已发布(可被搜索/Guard/Export 消费) */
|
|
12
17
|
ACTIVE: string;
|
|
18
|
+
/** 进化中(有 EvolutionProposal 附着) */
|
|
19
|
+
EVOLVING: string;
|
|
20
|
+
/** 衰退观察期 */
|
|
21
|
+
DECAYING: string;
|
|
13
22
|
/** 已弃用 */
|
|
14
23
|
DEPRECATED: string;
|
|
15
24
|
};
|
|
16
25
|
/** 候选阶段的所有状态 */
|
|
17
26
|
export declare const CANDIDATE_STATES: string[];
|
|
27
|
+
/** 可消费状态(Guard/Search/Delivery 可使用的状态) */
|
|
28
|
+
export declare const CONSUMABLE_STATES: string[];
|
|
29
|
+
/** 降级消费状态(Guard violation 降为 warning,Search 降权) */
|
|
30
|
+
export declare const DEGRADED_STATES: string[];
|
|
18
31
|
/** 规范化生命周期值 */
|
|
19
32
|
export declare function normalizeLifecycle(lifecycle: string): string;
|
|
20
33
|
/** 检查状态转移是否合法 */
|
|
21
34
|
export declare function isValidTransition(from: string, to: string): boolean;
|
|
22
35
|
/** 是否为合法的生命周期值 */
|
|
23
36
|
export declare function isValidLifecycle(lifecycle: string): boolean;
|
|
24
|
-
/**
|
|
37
|
+
/** 是否处于候选阶段(待审核或暂存) */
|
|
25
38
|
export declare function isCandidate(lifecycle: string): boolean;
|
|
39
|
+
/** 是否为可消费状态(Guard/Search/Delivery 可使用) */
|
|
40
|
+
export declare function isConsumable(lifecycle: string): boolean;
|
|
41
|
+
/** 是否为降级消费状态 */
|
|
42
|
+
export declare function isDegraded(lifecycle: string): boolean;
|
|
26
43
|
/** 从 knowledgeType 推导 kind */
|
|
27
44
|
export declare function inferKind(knowledgeType: string): 'rule' | 'pattern' | 'fact';
|
|
28
45
|
export default Lifecycle;
|
|
@@ -1,24 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Lifecycle —
|
|
2
|
+
* Lifecycle — 知识实体生命周期状态机(六态版)
|
|
3
3
|
*
|
|
4
4
|
* pending — 待审核(所有新条目初始状态)
|
|
5
|
+
* staging — 暂存期(高置信度,Grace Period 后自动 active)
|
|
5
6
|
* active — 已发布(可被搜索/Guard/Export 消费)
|
|
7
|
+
* evolving — 进化中(有 EvolutionProposal 附着,内容待更新)
|
|
8
|
+
* decaying — 衰退观察(30d Grace + 3x 确认后 deprecated)
|
|
6
9
|
* deprecated — 已废弃
|
|
7
10
|
*/
|
|
8
11
|
export const Lifecycle = {
|
|
9
12
|
/** 待审核 */
|
|
10
13
|
PENDING: 'pending',
|
|
14
|
+
/** 暂存期(高置信度,Grace Period 后自动 active) */
|
|
15
|
+
STAGING: 'staging',
|
|
11
16
|
/** 已发布(可被搜索/Guard/Export 消费) */
|
|
12
17
|
ACTIVE: 'active',
|
|
18
|
+
/** 进化中(有 EvolutionProposal 附着) */
|
|
19
|
+
EVOLVING: 'evolving',
|
|
20
|
+
/** 衰退观察期 */
|
|
21
|
+
DECAYING: 'decaying',
|
|
13
22
|
/** 已弃用 */
|
|
14
23
|
DEPRECATED: 'deprecated',
|
|
15
24
|
};
|
|
16
25
|
/** 候选阶段的所有状态 */
|
|
17
|
-
export const CANDIDATE_STATES = [Lifecycle.PENDING];
|
|
26
|
+
export const CANDIDATE_STATES = [Lifecycle.PENDING, Lifecycle.STAGING];
|
|
27
|
+
/** 可消费状态(Guard/Search/Delivery 可使用的状态) */
|
|
28
|
+
export const CONSUMABLE_STATES = [Lifecycle.STAGING, Lifecycle.ACTIVE, Lifecycle.EVOLVING];
|
|
29
|
+
/** 降级消费状态(Guard violation 降为 warning,Search 降权) */
|
|
30
|
+
export const DEGRADED_STATES = [Lifecycle.DECAYING];
|
|
18
31
|
/** 合法状态转移表 */
|
|
19
32
|
const VALID_TRANSITIONS = {
|
|
20
|
-
[Lifecycle.PENDING]: [Lifecycle.ACTIVE, Lifecycle.DEPRECATED],
|
|
21
|
-
[Lifecycle.
|
|
33
|
+
[Lifecycle.PENDING]: [Lifecycle.STAGING, Lifecycle.ACTIVE, Lifecycle.DEPRECATED],
|
|
34
|
+
[Lifecycle.STAGING]: [Lifecycle.ACTIVE, Lifecycle.PENDING],
|
|
35
|
+
[Lifecycle.ACTIVE]: [Lifecycle.EVOLVING, Lifecycle.DECAYING, Lifecycle.DEPRECATED],
|
|
36
|
+
[Lifecycle.EVOLVING]: [Lifecycle.ACTIVE, Lifecycle.DECAYING],
|
|
37
|
+
[Lifecycle.DECAYING]: [Lifecycle.ACTIVE, Lifecycle.DEPRECATED],
|
|
22
38
|
[Lifecycle.DEPRECATED]: [Lifecycle.PENDING],
|
|
23
39
|
};
|
|
24
40
|
/** 规范化生命周期值 */
|
|
@@ -39,10 +55,20 @@ export function isValidTransition(from, to) {
|
|
|
39
55
|
export function isValidLifecycle(lifecycle) {
|
|
40
56
|
return Object.values(Lifecycle).includes(lifecycle);
|
|
41
57
|
}
|
|
42
|
-
/**
|
|
58
|
+
/** 是否处于候选阶段(待审核或暂存) */
|
|
43
59
|
export function isCandidate(lifecycle) {
|
|
44
60
|
const normalized = normalizeLifecycle(lifecycle);
|
|
45
|
-
return normalized === Lifecycle.PENDING;
|
|
61
|
+
return normalized === Lifecycle.PENDING || normalized === Lifecycle.STAGING;
|
|
62
|
+
}
|
|
63
|
+
/** 是否为可消费状态(Guard/Search/Delivery 可使用) */
|
|
64
|
+
export function isConsumable(lifecycle) {
|
|
65
|
+
const normalized = normalizeLifecycle(lifecycle);
|
|
66
|
+
return CONSUMABLE_STATES.includes(normalized);
|
|
67
|
+
}
|
|
68
|
+
/** 是否为降级消费状态 */
|
|
69
|
+
export function isDegraded(lifecycle) {
|
|
70
|
+
const normalized = normalizeLifecycle(lifecycle);
|
|
71
|
+
return DEGRADED_STATES.includes(normalized);
|
|
46
72
|
}
|
|
47
73
|
/* ── knowledgeType → kind 映射 ── */
|
|
48
74
|
const KIND_MAP = {
|
|
@@ -4,10 +4,7 @@
|
|
|
4
4
|
* 替代 CandidateGuardrail + RecipeReadinessChecker 的分裂验证,
|
|
5
5
|
* 提供单一入口的三层验证 (字段完整性 + 内容质量 + 去重)。
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* strict — 默认:完整 REQUIRED 字段检查(标准知识条目)
|
|
9
|
-
* document — knowledgeType='dev-document' 时自动切换:跳过 Cursor 交付字段
|
|
10
|
-
* fallback — source 含 'fallback' 时:REQUIRED 降级为 WARNING
|
|
7
|
+
* 统一严格模式:完整 REQUIRED 字段检查,无宽松降级。
|
|
11
8
|
*
|
|
12
9
|
* @module shared/UnifiedValidator
|
|
13
10
|
*/
|
|
@@ -31,7 +28,6 @@ export declare class UnifiedValidator {
|
|
|
31
28
|
* @returns }
|
|
32
29
|
*/
|
|
33
30
|
validate(candidate: Record<string, unknown>, options?: {
|
|
34
|
-
mode?: 'strict' | 'document' | 'fallback';
|
|
35
31
|
systemInjectedFields?: string[];
|
|
36
32
|
skipUniqueness?: boolean;
|
|
37
33
|
}): {
|
|
@@ -4,25 +4,12 @@
|
|
|
4
4
|
* 替代 CandidateGuardrail + RecipeReadinessChecker 的分裂验证,
|
|
5
5
|
* 提供单一入口的三层验证 (字段完整性 + 内容质量 + 去重)。
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* strict — 默认:完整 REQUIRED 字段检查(标准知识条目)
|
|
9
|
-
* document — knowledgeType='dev-document' 时自动切换:跳过 Cursor 交付字段
|
|
10
|
-
* fallback — source 含 'fallback' 时:REQUIRED 降级为 WARNING
|
|
7
|
+
* 统一严格模式:完整 REQUIRED 字段检查,无宽松降级。
|
|
11
8
|
*
|
|
12
9
|
* @module shared/UnifiedValidator
|
|
13
10
|
*/
|
|
14
11
|
import { LanguageService } from '#shared/LanguageService.js';
|
|
15
12
|
import { FieldLevel, STANDARD_CATEGORIES, V3_FIELD_SPEC, VALID_KINDS, WHITELISTED_CATEGORIES, } from './FieldSpec.js';
|
|
16
|
-
// ── Cursor 交付字段集合(document 模式跳过这些) ────────────
|
|
17
|
-
const CURSOR_DELIVERY_FIELDS = new Set([
|
|
18
|
-
'trigger',
|
|
19
|
-
'kind',
|
|
20
|
-
'doClause',
|
|
21
|
-
'dontClause',
|
|
22
|
-
'whenClause',
|
|
23
|
-
'coreCode',
|
|
24
|
-
'topicHint',
|
|
25
|
-
]);
|
|
26
13
|
// ── 代码指纹工具函数 ───────────────────────────────────────
|
|
27
14
|
/** 生成代码模式指纹 — 去除空白/注释后取前 200 字符的小写形式 */
|
|
28
15
|
function codeFingerprint(code) {
|
|
@@ -33,17 +20,6 @@ function codeFingerprint(code) {
|
|
|
33
20
|
.toLowerCase()
|
|
34
21
|
.slice(0, 200);
|
|
35
22
|
}
|
|
36
|
-
// ── 模式自动检测 ────────────────────────────────────────────
|
|
37
|
-
/** 自动检测适合的验证模式 */
|
|
38
|
-
function detectMode(candidate) {
|
|
39
|
-
if (candidate.knowledgeType === 'dev-document') {
|
|
40
|
-
return 'document';
|
|
41
|
-
}
|
|
42
|
-
if (typeof candidate.source === 'string' && candidate.source.includes('fallback')) {
|
|
43
|
-
return 'fallback';
|
|
44
|
-
}
|
|
45
|
-
return 'strict';
|
|
46
|
-
}
|
|
47
23
|
// ── UnifiedValidator ────────────────────────────────────────
|
|
48
24
|
export class UnifiedValidator {
|
|
49
25
|
/** 已提交标题 (小写) */
|
|
@@ -70,14 +46,11 @@ export class UnifiedValidator {
|
|
|
70
46
|
validate(candidate, options = {}) {
|
|
71
47
|
const errors = [];
|
|
72
48
|
const warnings = [];
|
|
73
|
-
const mode = options.mode || detectMode(candidate);
|
|
74
49
|
const systemInjected = new Set(options.systemInjectedFields || []);
|
|
75
50
|
// ── Layer 1: 字段完整性 (基于 V3_FIELD_SPEC) ──
|
|
76
|
-
this.#checkFields(candidate,
|
|
51
|
+
this.#checkFields(candidate, systemInjected, errors, warnings);
|
|
77
52
|
// ── Layer 2: 内容质量 (来自 CandidateGuardrail.validateQuality) ──
|
|
78
|
-
|
|
79
|
-
this.#checkContentQuality(candidate, mode, errors, warnings);
|
|
80
|
-
}
|
|
53
|
+
this.#checkContentQuality(candidate, errors, warnings);
|
|
81
54
|
// ── Layer 3: 唯一性 (来自 CandidateGuardrail.validateUniqueness) ──
|
|
82
55
|
if (!options.skipUniqueness) {
|
|
83
56
|
this.#checkUniqueness(candidate, errors);
|
|
@@ -89,13 +62,9 @@ export class UnifiedValidator {
|
|
|
89
62
|
};
|
|
90
63
|
}
|
|
91
64
|
// ── Layer 1: 基于 FieldSpec 检查 ─────────────────────────
|
|
92
|
-
#checkFields(candidate,
|
|
65
|
+
#checkFields(candidate, systemInjected, errors, warnings) {
|
|
93
66
|
for (const field of V3_FIELD_SPEC) {
|
|
94
67
|
const { name, level, rule } = field;
|
|
95
|
-
// document 模式:跳过 Cursor 交付字段
|
|
96
|
-
if (mode === 'document' && CURSOR_DELIVERY_FIELDS.has(name.split('.')[0])) {
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
68
|
// 系统注入字段:跳过
|
|
100
69
|
if (systemInjected.has(name)) {
|
|
101
70
|
continue;
|
|
@@ -106,13 +75,7 @@ export class UnifiedValidator {
|
|
|
106
75
|
continue;
|
|
107
76
|
}
|
|
108
77
|
if (level === FieldLevel.REQUIRED) {
|
|
109
|
-
|
|
110
|
-
// fallback 模式:REQUIRED 降级为 warning
|
|
111
|
-
warnings.push(`${name}: ${rule}`);
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
errors.push(`缺少必填字段: ${name} — ${rule}`);
|
|
115
|
-
}
|
|
78
|
+
errors.push(`缺少必填字段: ${name} — ${rule}`);
|
|
116
79
|
}
|
|
117
80
|
else if (level === FieldLevel.EXPECTED) {
|
|
118
81
|
warnings.push(`建议填写: ${name} — ${rule}`);
|
|
@@ -149,7 +112,7 @@ export class UnifiedValidator {
|
|
|
149
112
|
}
|
|
150
113
|
}
|
|
151
114
|
// ── Layer 2: 内容质量启发式 ──────────────────────────────
|
|
152
|
-
#checkContentQuality(candidate,
|
|
115
|
+
#checkContentQuality(candidate, errors, warnings) {
|
|
153
116
|
const markdown = candidate.content?.markdown || '';
|
|
154
117
|
// markdown ≥ 200 字符
|
|
155
118
|
if (markdown && markdown.length > 0 && markdown.length < 200) {
|
|
@@ -171,7 +134,7 @@ export class UnifiedValidator {
|
|
|
171
134
|
}
|
|
172
135
|
}
|
|
173
136
|
// coreCode 语法完整性
|
|
174
|
-
|
|
137
|
+
{
|
|
175
138
|
const coreCode = (candidate.coreCode || '').trim();
|
|
176
139
|
if (coreCode) {
|
|
177
140
|
const firstChar = coreCode[0];
|