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.
Files changed (245) hide show
  1. package/dashboard/dist/assets/icons-BJ2mUBi8.js +1 -0
  2. package/dashboard/dist/assets/index-B659K9t5.js +128 -0
  3. package/dashboard/dist/assets/index-NCm40PMD.css +1 -0
  4. package/dashboard/dist/index.html +3 -3
  5. package/dist/bin/cli.d.ts +1 -0
  6. package/dist/bin/cli.js +284 -142
  7. package/dist/lib/agent/context/ExplorationTracker.d.ts +2 -0
  8. package/dist/lib/agent/context/ExplorationTracker.js +21 -3
  9. package/dist/lib/agent/core/ToolExecutionPipeline.d.ts +3 -1
  10. package/dist/lib/agent/core/ToolExecutionPipeline.js +8 -1
  11. package/dist/lib/agent/forge/DynamicComposer.d.ts +58 -0
  12. package/dist/lib/agent/forge/DynamicComposer.js +99 -0
  13. package/dist/lib/agent/forge/SandboxRunner.d.ts +60 -0
  14. package/dist/lib/agent/forge/SandboxRunner.js +251 -0
  15. package/dist/lib/agent/forge/TemporaryToolRegistry.d.ts +76 -0
  16. package/dist/lib/agent/forge/TemporaryToolRegistry.js +154 -0
  17. package/dist/lib/agent/forge/ToolForge.d.ts +92 -0
  18. package/dist/lib/agent/forge/ToolForge.js +239 -0
  19. package/dist/lib/agent/forge/ToolRequirementAnalyzer.d.ts +44 -0
  20. package/dist/lib/agent/forge/ToolRequirementAnalyzer.js +119 -0
  21. package/dist/lib/agent/tools/ToolRegistry.d.ts +2 -0
  22. package/dist/lib/agent/tools/ToolRegistry.js +4 -0
  23. package/dist/lib/agent/tools/composite.js +0 -1
  24. package/dist/lib/agent/tools/index.d.ts +2 -50
  25. package/dist/lib/agent/tools/index.js +2 -3
  26. package/dist/lib/agent/tools/lifecycle.d.ts +1 -58
  27. package/dist/lib/agent/tools/lifecycle.js +2 -75
  28. package/dist/lib/cli/KnowledgeSyncService.d.ts +26 -0
  29. package/dist/lib/cli/KnowledgeSyncService.js +33 -1
  30. package/dist/lib/cli/deploy/FileManifest.d.ts +0 -21
  31. package/dist/lib/cli/deploy/FileManifest.js +0 -11
  32. package/dist/lib/domain/knowledge/KnowledgeEntry.d.ts +10 -0
  33. package/dist/lib/domain/knowledge/KnowledgeEntry.js +2 -0
  34. package/dist/lib/domain/knowledge/Lifecycle.d.ts +19 -2
  35. package/dist/lib/domain/knowledge/Lifecycle.js +32 -6
  36. package/dist/lib/domain/knowledge/UnifiedValidator.d.ts +1 -5
  37. package/dist/lib/domain/knowledge/UnifiedValidator.js +7 -44
  38. package/dist/lib/domain/knowledge/values/Stats.d.ts +29 -0
  39. package/dist/lib/domain/knowledge/values/Stats.js +41 -0
  40. package/dist/lib/external/mcp/McpServer.d.ts +19 -38
  41. package/dist/lib/external/mcp/McpServer.js +145 -117
  42. package/dist/lib/external/mcp/autoApproveInjector.js +0 -2
  43. package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.d.ts +26 -1
  44. package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.js +41 -0
  45. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +49 -0
  46. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +3 -0
  47. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +27 -0
  48. package/dist/lib/external/mcp/handlers/bootstrap/skills.js +1 -1
  49. package/dist/lib/external/mcp/handlers/bootstrap-external.js +1 -0
  50. package/dist/lib/external/mcp/handlers/bootstrap-internal.js +2 -0
  51. package/dist/lib/external/mcp/handlers/browse.d.ts +1 -0
  52. package/dist/lib/external/mcp/handlers/browse.js +2 -1
  53. package/dist/lib/external/mcp/handlers/consolidated.d.ts +117 -6
  54. package/dist/lib/external/mcp/handlers/consolidated.js +251 -71
  55. package/dist/lib/external/mcp/handlers/guard.d.ts +150 -0
  56. package/dist/lib/external/mcp/handlers/guard.js +239 -5
  57. package/dist/lib/external/mcp/handlers/knowledge.d.ts +0 -29
  58. package/dist/lib/external/mcp/handlers/knowledge.js +1 -76
  59. package/dist/lib/external/mcp/handlers/panorama.d.ts +36 -0
  60. package/dist/lib/external/mcp/handlers/panorama.js +156 -0
  61. package/dist/lib/external/mcp/handlers/system.d.ts +2 -54
  62. package/dist/lib/external/mcp/handlers/system.js +3 -113
  63. package/dist/lib/external/mcp/handlers/task.d.ts +13 -24
  64. package/dist/lib/external/mcp/handlers/task.js +218 -557
  65. package/dist/lib/external/mcp/handlers/types.d.ts +91 -8
  66. package/dist/lib/external/mcp/handlers/types.js +18 -1
  67. package/dist/lib/external/mcp/handlers/wiki-external.d.ts +18 -1
  68. package/dist/lib/external/mcp/handlers/wiki-external.js +16 -1
  69. package/dist/lib/external/mcp/tools.d.ts +18 -24
  70. package/dist/lib/external/mcp/tools.js +132 -159
  71. package/dist/lib/http/HttpServer.js +52 -0
  72. package/dist/lib/http/middleware/validate.js +7 -3
  73. package/dist/lib/http/routes/audit.d.ts +8 -0
  74. package/dist/lib/http/routes/audit.js +51 -0
  75. package/dist/lib/http/routes/guardReport.d.ts +10 -0
  76. package/dist/lib/http/routes/guardReport.js +143 -0
  77. package/dist/lib/http/routes/knowledge.js +32 -1
  78. package/dist/lib/http/routes/panorama.d.ts +11 -0
  79. package/dist/lib/http/routes/panorama.js +322 -0
  80. package/dist/lib/http/routes/signals.d.ts +10 -0
  81. package/dist/lib/http/routes/signals.js +104 -0
  82. package/dist/lib/http/routes/task.d.ts +2 -3
  83. package/dist/lib/http/routes/task.js +17 -347
  84. package/dist/lib/http/routes/violations.js +1 -1
  85. package/dist/lib/infrastructure/audit/AuditLogger.d.ts +6 -1
  86. package/dist/lib/infrastructure/audit/AuditLogger.js +14 -1
  87. package/dist/lib/infrastructure/database/drizzle/schema.d.ts +202 -504
  88. package/dist/lib/infrastructure/database/drizzle/schema.js +38 -69
  89. package/dist/lib/infrastructure/database/migrations/004_evolution_proposals.d.ts +8 -0
  90. package/dist/lib/infrastructure/database/migrations/004_evolution_proposals.js +43 -0
  91. package/dist/lib/infrastructure/database/migrations/005_recipe_source_refs.d.ts +9 -0
  92. package/dist/lib/infrastructure/database/migrations/005_recipe_source_refs.js +24 -0
  93. package/dist/lib/infrastructure/logging/Logger.d.ts +2 -0
  94. package/dist/lib/infrastructure/logging/Logger.js +34 -7
  95. package/dist/lib/infrastructure/monitoring/ErrorTracker.js +3 -1
  96. package/dist/lib/infrastructure/monitoring/PerformanceMonitor.d.ts +2 -2
  97. package/dist/lib/infrastructure/monitoring/PerformanceMonitor.js +12 -10
  98. package/dist/lib/infrastructure/notification/LarkNotifier.d.ts +24 -0
  99. package/dist/lib/infrastructure/notification/LarkNotifier.js +97 -0
  100. package/dist/lib/infrastructure/report/ReportStore.d.ts +45 -0
  101. package/dist/lib/infrastructure/report/ReportStore.js +133 -0
  102. package/dist/lib/infrastructure/signal/SignalAggregator.d.ts +18 -0
  103. package/dist/lib/infrastructure/signal/SignalAggregator.js +84 -0
  104. package/dist/lib/infrastructure/signal/SignalBridge.d.ts +13 -0
  105. package/dist/lib/infrastructure/signal/SignalBridge.js +20 -0
  106. package/dist/lib/infrastructure/signal/SignalBus.d.ts +63 -0
  107. package/dist/lib/infrastructure/signal/SignalBus.js +106 -0
  108. package/dist/lib/infrastructure/signal/SignalTraceWriter.d.ts +36 -0
  109. package/dist/lib/infrastructure/signal/SignalTraceWriter.js +130 -0
  110. package/dist/lib/infrastructure/vector/HnswVectorAdapter.js +18 -2
  111. package/dist/lib/injection/ServiceContainer.js +8 -0
  112. package/dist/lib/injection/ServiceMap.d.ts +16 -10
  113. package/dist/lib/injection/modules/AgentModule.d.ts +1 -1
  114. package/dist/lib/injection/modules/AgentModule.js +7 -1
  115. package/dist/lib/injection/modules/AppModule.d.ts +1 -1
  116. package/dist/lib/injection/modules/AppModule.js +4 -13
  117. package/dist/lib/injection/modules/GuardModule.js +27 -2
  118. package/dist/lib/injection/modules/InfraModule.d.ts +0 -1
  119. package/dist/lib/injection/modules/InfraModule.js +9 -7
  120. package/dist/lib/injection/modules/KnowledgeModule.d.ts +5 -0
  121. package/dist/lib/injection/modules/KnowledgeModule.js +131 -0
  122. package/dist/lib/injection/modules/PanoramaModule.d.ts +18 -0
  123. package/dist/lib/injection/modules/PanoramaModule.js +76 -0
  124. package/dist/lib/injection/modules/SignalModule.d.ts +10 -0
  125. package/dist/lib/injection/modules/SignalModule.js +84 -0
  126. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +1 -0
  127. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +6 -0
  128. package/dist/lib/service/bootstrap/BootstrapTaskManager.d.ts +3 -1
  129. package/dist/lib/service/bootstrap/BootstrapTaskManager.js +20 -1
  130. package/dist/lib/service/bootstrap/UiStartupTasks.d.ts +45 -0
  131. package/dist/lib/service/bootstrap/UiStartupTasks.js +101 -0
  132. package/dist/lib/service/delivery/AgentInstructionsGenerator.js +4 -5
  133. package/dist/lib/service/delivery/CursorDeliveryPipeline.d.ts +3 -1
  134. package/dist/lib/service/delivery/CursorDeliveryPipeline.js +13 -10
  135. package/dist/lib/service/delivery/RulesGenerator.js +3 -2
  136. package/dist/lib/service/evolution/ConsolidationAdvisor.d.ts +114 -0
  137. package/dist/lib/service/evolution/ConsolidationAdvisor.js +542 -0
  138. package/dist/lib/service/evolution/ContradictionDetector.d.ts +54 -0
  139. package/dist/lib/service/evolution/ContradictionDetector.js +253 -0
  140. package/dist/lib/service/evolution/DecayDetector.d.ts +71 -0
  141. package/dist/lib/service/evolution/DecayDetector.js +244 -0
  142. package/dist/lib/service/evolution/EnhancementSuggester.d.ts +38 -0
  143. package/dist/lib/service/evolution/EnhancementSuggester.js +220 -0
  144. package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +82 -0
  145. package/dist/lib/service/evolution/KnowledgeMetabolism.js +167 -0
  146. package/dist/lib/service/evolution/RedundancyAnalyzer.d.ts +53 -0
  147. package/dist/lib/service/evolution/RedundancyAnalyzer.js +210 -0
  148. package/dist/lib/service/evolution/StagingManager.d.ts +57 -0
  149. package/dist/lib/service/evolution/StagingManager.js +201 -0
  150. package/dist/lib/service/guard/ComplianceReporter.d.ts +42 -2
  151. package/dist/lib/service/guard/ComplianceReporter.js +43 -5
  152. package/dist/lib/service/guard/CoverageAnalyzer.d.ts +54 -0
  153. package/dist/lib/service/guard/CoverageAnalyzer.js +149 -0
  154. package/dist/lib/service/guard/GuardCheckEngine.d.ts +42 -0
  155. package/dist/lib/service/guard/GuardCheckEngine.js +465 -14
  156. package/dist/lib/service/guard/GuardFeedbackLoop.d.ts +3 -0
  157. package/dist/lib/service/guard/GuardFeedbackLoop.js +9 -0
  158. package/dist/lib/service/guard/ReverseGuard.d.ts +73 -0
  159. package/dist/lib/service/guard/ReverseGuard.js +256 -0
  160. package/dist/lib/service/guard/RuleLearner.d.ts +12 -0
  161. package/dist/lib/service/guard/RuleLearner.js +38 -0
  162. package/dist/lib/service/guard/UncertaintyCollector.d.ts +83 -0
  163. package/dist/lib/service/guard/UncertaintyCollector.js +149 -0
  164. package/dist/lib/service/guard/ViolationsStore.d.ts +1 -0
  165. package/dist/lib/service/guard/ViolationsStore.js +33 -3
  166. package/dist/lib/service/knowledge/ConfidenceRouter.d.ts +13 -0
  167. package/dist/lib/service/knowledge/ConfidenceRouter.js +14 -0
  168. package/dist/lib/service/knowledge/KnowledgeService.js +22 -4
  169. package/dist/lib/service/knowledge/SourceRefReconciler.d.ts +68 -0
  170. package/dist/lib/service/knowledge/SourceRefReconciler.js +309 -0
  171. package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +27 -0
  172. package/dist/lib/service/panorama/CouplingAnalyzer.js +192 -0
  173. package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +28 -0
  174. package/dist/lib/service/panorama/DimensionAnalyzer.js +320 -0
  175. package/dist/lib/service/panorama/LayerInferrer.d.ts +19 -0
  176. package/dist/lib/service/panorama/LayerInferrer.js +182 -0
  177. package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +24 -0
  178. package/dist/lib/service/panorama/ModuleDiscoverer.js +185 -0
  179. package/dist/lib/service/panorama/PanoramaAggregator.d.ts +29 -0
  180. package/dist/lib/service/panorama/PanoramaAggregator.js +228 -0
  181. package/dist/lib/service/panorama/PanoramaScanner.d.ts +52 -0
  182. package/dist/lib/service/panorama/PanoramaScanner.js +188 -0
  183. package/dist/lib/service/panorama/PanoramaService.d.ts +125 -0
  184. package/dist/lib/service/panorama/PanoramaService.js +363 -0
  185. package/dist/lib/service/panorama/PanoramaTypes.d.ts +134 -0
  186. package/dist/lib/service/panorama/PanoramaTypes.js +6 -0
  187. package/dist/lib/service/panorama/RoleRefiner.d.ts +48 -0
  188. package/dist/lib/service/panorama/RoleRefiner.js +535 -0
  189. package/dist/lib/service/search/BM25Scorer.d.ts +2 -2
  190. package/dist/lib/service/search/CoarseRanker.d.ts +7 -6
  191. package/dist/lib/service/search/CoarseRanker.js +11 -10
  192. package/dist/lib/service/search/FieldWeightedScorer.d.ts +81 -0
  193. package/dist/lib/service/search/FieldWeightedScorer.js +318 -0
  194. package/dist/lib/service/search/MultiSignalRanker.d.ts +3 -2
  195. package/dist/lib/service/search/MultiSignalRanker.js +17 -1
  196. package/dist/lib/service/search/SearchEngine.d.ts +9 -7
  197. package/dist/lib/service/search/SearchEngine.js +67 -10
  198. package/dist/lib/service/search/SearchTypes.d.ts +25 -3
  199. package/dist/lib/service/search/SearchTypes.js +6 -1
  200. package/dist/lib/service/signal/HitRecorder.d.ts +68 -0
  201. package/dist/lib/service/signal/HitRecorder.js +173 -0
  202. package/dist/lib/service/skills/SignalCollector.d.ts +3 -1
  203. package/dist/lib/service/skills/SignalCollector.js +31 -1
  204. package/dist/lib/service/task/IntentExtractor.d.ts +66 -0
  205. package/dist/lib/service/task/IntentExtractor.js +256 -0
  206. package/dist/lib/service/task/PrimeSearchPipeline.d.ts +54 -0
  207. package/dist/lib/service/task/PrimeSearchPipeline.js +113 -0
  208. package/dist/lib/service/vector/VectorService.d.ts +3 -0
  209. package/dist/lib/service/vector/VectorService.js +38 -4
  210. package/dist/lib/shared/schemas/mcp-tools.d.ts +41 -96
  211. package/dist/lib/shared/schemas/mcp-tools.js +59 -119
  212. package/dist/scripts/analyze-signals.d.ts +20 -0
  213. package/dist/scripts/analyze-signals.js +155 -0
  214. package/dist/scripts/diagnose-mcp.js +1 -1
  215. package/package.json +1 -1
  216. package/skills/autosnippet-create/SKILL.md +98 -89
  217. package/skills/autosnippet-devdocs/SKILL.md +55 -57
  218. package/templates/claude-code/hooks/autosnippet-session.sh +10 -15
  219. package/templates/cursor-hooks/hooks/session-start.sh +1 -1
  220. package/templates/guard-ci.yml +2 -2
  221. package/templates/instructions/agent-static.md +2 -1
  222. package/templates/instructions/conventions.md +5 -6
  223. package/templates/recipes-setup/README.md +1 -2
  224. package/templates/recipes-setup/_template.md +39 -39
  225. package/dashboard/dist/assets/icons-BofcEZ3f.js +0 -1
  226. package/dashboard/dist/assets/index-D0whuycy.css +0 -1
  227. package/dashboard/dist/assets/index-SiN1GChm.js +0 -128
  228. package/dist/lib/domain/task/Task.d.ts +0 -140
  229. package/dist/lib/domain/task/Task.js +0 -254
  230. package/dist/lib/domain/task/TaskDependency.d.ts +0 -23
  231. package/dist/lib/domain/task/TaskDependency.js +0 -34
  232. package/dist/lib/domain/task/TaskIdGenerator.d.ts +0 -40
  233. package/dist/lib/domain/task/TaskIdGenerator.js +0 -75
  234. package/dist/lib/domain/task/index.d.ts +0 -4
  235. package/dist/lib/domain/task/index.js +0 -4
  236. package/dist/lib/infrastructure/database/migrations/002_add_tasks.d.ts +0 -11
  237. package/dist/lib/infrastructure/database/migrations/002_add_tasks.js +0 -86
  238. package/dist/lib/repository/task/TaskRepository.impl.d.ts +0 -171
  239. package/dist/lib/repository/task/TaskRepository.impl.js +0 -347
  240. package/dist/lib/service/task/TaskGraphService.d.ts +0 -222
  241. package/dist/lib/service/task/TaskGraphService.js +0 -597
  242. package/dist/lib/service/task/TaskKnowledgeBridge.d.ts +0 -95
  243. package/dist/lib/service/task/TaskKnowledgeBridge.js +0 -298
  244. package/dist/lib/service/task/TaskReadyEngine.d.ts +0 -84
  245. package/dist/lib/service/task/TaskReadyEngine.js +0 -115
@@ -18,20 +18,41 @@ export class ViolationsStore {
18
18
  // ─── 写入 ─────────────────────────────────────────────
19
19
  /**
20
20
  * 追加一次 Guard 运行记录
21
+ * ★ 去重:同一文件、同一违规集合不重复入库,仅更新时间戳
21
22
  * ★ Drizzle 类型安全 INSERT + raw SQL 截断
22
23
  */
23
24
  appendRun(run) {
25
+ const filePath = run.filePath || '';
26
+ const violations = run.violations || [];
27
+ const violationsJson = JSON.stringify(violations);
28
+ // ── 去重:查最近一条同文件记录,比较违规指纹 ──
29
+ const fingerprint = this.#violationFingerprint(violations);
30
+ if (filePath) {
31
+ const lastRow = this.#db
32
+ .prepare(`SELECT id, violations_json FROM guard_violations WHERE file_path = ? ORDER BY created_at DESC LIMIT 1`)
33
+ .get(filePath);
34
+ if (lastRow) {
35
+ const lastFingerprint = this.#violationFingerprint(JSON.parse(lastRow.violations_json || '[]'));
36
+ if (fingerprint === lastFingerprint) {
37
+ // 违规未变化:仅刷新时间戳,不新增行
38
+ this.#db
39
+ .prepare(`UPDATE guard_violations SET triggered_at = ?, created_at = ? WHERE id = ?`)
40
+ .run(new Date().toISOString(), Math.floor(Date.now() / 1000), lastRow.id);
41
+ return lastRow.id;
42
+ }
43
+ }
44
+ }
24
45
  const id = `run_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
25
46
  const now = Math.floor(Date.now() / 1000);
26
47
  this.#drizzle
27
48
  .insert(guardViolations)
28
49
  .values({
29
50
  id,
30
- filePath: run.filePath || '',
51
+ filePath,
31
52
  triggeredAt: new Date().toISOString(),
32
- violationCount: (run.violations || []).length,
53
+ violationCount: violations.length,
33
54
  summary: run.summary || '',
34
- violationsJson: JSON.stringify(run.violations || []),
55
+ violationsJson,
35
56
  createdAt: now,
36
57
  })
37
58
  .run();
@@ -45,6 +66,15 @@ export class ViolationsStore {
45
66
  .run(MAX_RUNS);
46
67
  return id;
47
68
  }
69
+ /**
70
+ * 违规指纹:按 ruleId+severity+line 排序后拼接,用于去重比较
71
+ */
72
+ #violationFingerprint(violations) {
73
+ return violations
74
+ .map((v) => `${v.ruleId || ''}|${v.severity || ''}|${v.line ?? ''}`)
75
+ .sort()
76
+ .join('\n');
77
+ }
48
78
  // ─── 查询 ─────────────────────────────────────────────
49
79
  /**
50
80
  * 获取所有运行记录(最新在后)
@@ -8,11 +8,18 @@ interface ConfidenceRouterConfig {
8
8
  requireReasoning?: boolean;
9
9
  trustedSources?: string[];
10
10
  trustedAutoApproveThreshold?: number;
11
+ highConfidenceThreshold?: number;
12
+ standardGracePeriod?: number;
13
+ highConfidenceGracePeriod?: number;
11
14
  }
12
15
  interface RouteResult {
13
16
  action: 'auto_approve' | 'pending' | 'reject';
14
17
  reason: string;
15
18
  confidence?: number;
19
+ /** 目标生命周期状态(六态状态机) */
20
+ targetState?: 'staging' | 'pending' | 'deprecated';
21
+ /** Grace Period(毫秒)— staging → active 自动转换等待时间 */
22
+ gracePeriod?: number;
16
23
  }
17
24
  /**
18
25
  * ConfidenceRouter — 知识条目自动审核路由器
@@ -38,6 +45,12 @@ declare const DEFAULT_CONFIG: {
38
45
  trustedSources: string[];
39
46
  /** 可信来源的自动通过阈值 */
40
47
  trustedAutoApproveThreshold: number;
48
+ /** 极高置信度阈值 (≥0.90 → 24h Grace) */
49
+ highConfidenceThreshold: number;
50
+ /** 标准 Grace Period(72h)— staging → active */
51
+ standardGracePeriod: number;
52
+ /** 高置信度 Grace Period(24h) */
53
+ highConfidenceGracePeriod: number;
41
54
  };
42
55
  export declare class ConfidenceRouter {
43
56
  _config: Required<typeof DEFAULT_CONFIG>;
@@ -23,6 +23,12 @@ const DEFAULT_CONFIG = {
23
23
  trustedSources: ['bootstrap', 'cursor-scan'],
24
24
  /** 可信来源的自动通过阈值 */
25
25
  trustedAutoApproveThreshold: 0.7,
26
+ /** 极高置信度阈值 (≥0.90 → 24h Grace) */
27
+ highConfidenceThreshold: 0.9,
28
+ /** 标准 Grace Period(72h)— staging → active */
29
+ standardGracePeriod: 72 * 60 * 60 * 1000,
30
+ /** 高置信度 Grace Period(24h) */
31
+ highConfidenceGracePeriod: 24 * 60 * 60 * 1000,
26
32
  };
27
33
  export class ConfidenceRouter {
28
34
  _config;
@@ -56,6 +62,7 @@ export class ConfidenceRouter {
56
62
  action: 'reject',
57
63
  reason: `Confidence too low: ${confidence.toFixed(2)} < ${this._config.rejectThreshold}`,
58
64
  confidence,
65
+ targetState: 'deprecated',
59
66
  };
60
67
  }
61
68
  // ── 阶段 3: 内容最短长度检查 ──
@@ -115,12 +122,19 @@ export class ConfidenceRouter {
115
122
  action: 'pending',
116
123
  reason: `Confidence OK (${confidence.toFixed(2)}) but quality low (${qualityScore.toFixed(2)})`,
117
124
  confidence,
125
+ targetState: 'pending',
118
126
  };
119
127
  }
128
+ // 分级 Grace Period: ≥0.90 → 24h, 0.85-0.89 → 72h
129
+ const gracePeriod = confidence >= this._config.highConfidenceThreshold
130
+ ? this._config.highConfidenceGracePeriod
131
+ : this._config.standardGracePeriod;
120
132
  return {
121
133
  action: 'auto_approve',
122
134
  reason: `Confidence ${confidence.toFixed(2)} >= threshold ${threshold} (source: ${source})`,
123
135
  confidence,
136
+ targetState: 'staging',
137
+ gracePeriod,
124
138
  };
125
139
  }
126
140
  // ── 默认: 需要人工审核 ──
@@ -67,17 +67,25 @@ export class KnowledgeService {
67
67
  throw new ValidationError(`SkillHook blocked: ${hookResult.reason || 'unknown'}`);
68
68
  }
69
69
  }
70
- // ── ConfidenceRouter — 标记 auto_approvable ──
70
+ // ── ConfidenceRouter — staging 路由 ──
71
71
  if (this._confidenceRouter) {
72
72
  const route = await this._confidenceRouter.route(entry);
73
73
  if (route.action === 'auto_approve') {
74
74
  entry.autoApprovable = true;
75
+ // 六态状态机:高置信度条目进入 staging
76
+ if (route.targetState === 'staging' && route.gracePeriod) {
77
+ entry.lifecycle = Lifecycle.STAGING;
78
+ entry.stagingDeadline = Date.now() + route.gracePeriod;
79
+ }
80
+ }
81
+ else if (route.action === 'reject' && route.targetState === 'deprecated') {
82
+ entry.lifecycle = Lifecycle.DEPRECATED;
75
83
  }
76
- // reject / pending 都保持 pending 状态,等待人工审核
84
+ // pending 保持不变
77
85
  }
78
- // 注意: Bootstrap 候选保持 pending 状态,由 Dashboard 审核后发布。
86
+ // 注意: staging 条目由 StagingManager.checkAndPromote() 在到期后自动转为 active。
79
87
  // autoApprovable 标记保留,供前端显示「推荐批准」徽章。
80
- // CursorDelivery 已支持高置信度 pending 条目的交付。
88
+ // CursorDelivery 已支持高置信度 staging/pending 条目的交付。
81
89
  const saved = await this.repository.create(entry);
82
90
  // 同步 relations → knowledge_edges
83
91
  this._syncRelationsToGraph(saved.id, saved.relations);
@@ -583,6 +591,16 @@ export class KnowledgeService {
583
591
  to: entry.lifecycle,
584
592
  actor: context.userId,
585
593
  });
594
+ // EventBus: 通知生命周期状态转换(Dashboard 实时更新 + SignalBus)
595
+ if (this._eventBus) {
596
+ this._eventBus.emit('lifecycle:transition', {
597
+ entryId: id,
598
+ from: prevLifecycle,
599
+ to: entry.lifecycle,
600
+ method,
601
+ actor: context.userId,
602
+ });
603
+ }
586
604
  return updated;
587
605
  }
588
606
  catch (error) {
@@ -0,0 +1,68 @@
1
+ /**
2
+ * SourceRefReconciler — Recipe 来源引用健康检查 + 自动修复
3
+ *
4
+ * 从 knowledge_entries.reasoning.sources 填充 recipe_source_refs 桥接表,
5
+ * 验证路径存在性,检测 git rename,修复路径引用。
6
+ *
7
+ * 状态机:
8
+ * active — 文件存在,路径有效
9
+ * renamed — 文件已移动到 new_path,等待修复
10
+ * stale — 路径失效,无法自动修复
11
+ */
12
+ interface DatabaseLike {
13
+ prepare(sql: string): {
14
+ all(...params: unknown[]): Record<string, unknown>[];
15
+ get(...params: unknown[]): Record<string, unknown> | undefined;
16
+ run(...params: unknown[]): {
17
+ changes: number;
18
+ };
19
+ };
20
+ }
21
+ export interface ReconcileReport {
22
+ /** 新插入的 sourceRef 条目 */
23
+ inserted: number;
24
+ /** 验证为 active 的条目 */
25
+ active: number;
26
+ /** 标记为 stale 的条目 */
27
+ stale: number;
28
+ /** 跳过的条目(24h 内已验证) */
29
+ skipped: number;
30
+ /** 处理的 recipe 数 */
31
+ recipesProcessed: number;
32
+ }
33
+ export interface RepairReport {
34
+ /** 成功检测到 rename 的条目 */
35
+ renamed: number;
36
+ /** 仍然 stale 的条目 */
37
+ stillStale: number;
38
+ }
39
+ export interface ApplyReport {
40
+ /** 成功写回 .md 的条目 */
41
+ applied: number;
42
+ /** 写回失败的条目 */
43
+ failed: number;
44
+ }
45
+ export declare class SourceRefReconciler {
46
+ #private;
47
+ constructor(projectRoot: string, db: DatabaseLike, options?: {
48
+ ttlMs?: number;
49
+ });
50
+ /**
51
+ * 从 knowledge_entries.reasoning 填充 recipe_source_refs 表。
52
+ * 对已有条目验证路径存在性,更新 status。
53
+ */
54
+ reconcile(opts?: {
55
+ force?: boolean;
56
+ }): ReconcileReport;
57
+ /**
58
+ * 对 stale 条目尝试 git rename 修复。
59
+ * 使用 execFile() 安全执行 git log(防止命令注入)。
60
+ */
61
+ repairRenames(): Promise<RepairReport>;
62
+ /**
63
+ * 将 renamed 条目的 new_path 写回 Recipe .md 文件的 _reasoning.sources。
64
+ * 完成后 status → active。
65
+ */
66
+ applyRepairs(): ApplyReport;
67
+ }
68
+ export {};
@@ -0,0 +1,309 @@
1
+ /**
2
+ * SourceRefReconciler — Recipe 来源引用健康检查 + 自动修复
3
+ *
4
+ * 从 knowledge_entries.reasoning.sources 填充 recipe_source_refs 桥接表,
5
+ * 验证路径存在性,检测 git rename,修复路径引用。
6
+ *
7
+ * 状态机:
8
+ * active — 文件存在,路径有效
9
+ * renamed — 文件已移动到 new_path,等待修复
10
+ * stale — 路径失效,无法自动修复
11
+ */
12
+ import { execFile } from 'node:child_process';
13
+ import fs from 'node:fs';
14
+ import path from 'node:path';
15
+ import { promisify } from 'node:util';
16
+ import Logger from '../../infrastructure/logging/Logger.js';
17
+ const execFileAsync = promisify(execFile);
18
+ /* ────────────────────── Class ────────────────────── */
19
+ /** 默认跳过 24h 内已验证的条目 */
20
+ const DEFAULT_TTL_MS = 24 * 60 * 60 * 1000;
21
+ export class SourceRefReconciler {
22
+ #projectRoot;
23
+ #db;
24
+ #logger = Logger.getInstance();
25
+ #ttlMs;
26
+ constructor(projectRoot, db, options) {
27
+ this.#projectRoot = projectRoot;
28
+ this.#db = db;
29
+ this.#ttlMs = options?.ttlMs ?? DEFAULT_TTL_MS;
30
+ }
31
+ /**
32
+ * 从 knowledge_entries.reasoning 填充 recipe_source_refs 表。
33
+ * 对已有条目验证路径存在性,更新 status。
34
+ */
35
+ reconcile(opts) {
36
+ const force = opts?.force ?? false;
37
+ const report = {
38
+ inserted: 0,
39
+ active: 0,
40
+ stale: 0,
41
+ skipped: 0,
42
+ recipesProcessed: 0,
43
+ };
44
+ // 确保表存在(兼容未跑 migration 的场景)
45
+ this.#ensureTable();
46
+ // 获取所有有 reasoning 的知识条目
47
+ const rows = this.#db
48
+ .prepare(`SELECT id, reasoning FROM knowledge_entries WHERE reasoning IS NOT NULL AND reasoning != '{}'`)
49
+ .all();
50
+ const now = Date.now();
51
+ for (const row of rows) {
52
+ let sources = [];
53
+ try {
54
+ const reasoning = JSON.parse(row.reasoning);
55
+ sources = Array.isArray(reasoning.sources)
56
+ ? reasoning.sources.filter((s) => typeof s === 'string' && s.length > 0)
57
+ : [];
58
+ }
59
+ catch {
60
+ continue;
61
+ }
62
+ if (sources.length === 0) {
63
+ continue;
64
+ }
65
+ report.recipesProcessed++;
66
+ for (const sourcePath of sources) {
67
+ // 检查是否已有记录
68
+ const existing = this.#db
69
+ .prepare(`SELECT status, verified_at FROM recipe_source_refs WHERE recipe_id = ? AND source_path = ?`)
70
+ .get(row.id, sourcePath);
71
+ if (existing && !force) {
72
+ // TTL 检查:跳过近期已验证的条目
73
+ if (now - existing.verified_at < this.#ttlMs) {
74
+ report.skipped++;
75
+ if (existing.status === 'active') {
76
+ report.active++;
77
+ }
78
+ else if (existing.status === 'stale') {
79
+ report.stale++;
80
+ }
81
+ continue;
82
+ }
83
+ }
84
+ // 验证路径存在性
85
+ const absPath = path.resolve(this.#projectRoot, sourcePath);
86
+ const exists = fs.existsSync(absPath);
87
+ if (existing) {
88
+ // 更新已有记录
89
+ if (exists) {
90
+ this.#db
91
+ .prepare(`UPDATE recipe_source_refs SET status = 'active', new_path = NULL, verified_at = ? WHERE recipe_id = ? AND source_path = ?`)
92
+ .run(now, row.id, sourcePath);
93
+ report.active++;
94
+ }
95
+ else {
96
+ this.#db
97
+ .prepare(`UPDATE recipe_source_refs SET status = 'stale', verified_at = ? WHERE recipe_id = ? AND source_path = ?`)
98
+ .run(now, row.id, sourcePath);
99
+ report.stale++;
100
+ }
101
+ }
102
+ else {
103
+ // 新增记录
104
+ const status = exists ? 'active' : 'stale';
105
+ this.#db
106
+ .prepare(`INSERT OR REPLACE INTO recipe_source_refs (recipe_id, source_path, status, verified_at) VALUES (?, ?, ?, ?)`)
107
+ .run(row.id, sourcePath, status, now);
108
+ report.inserted++;
109
+ if (exists) {
110
+ report.active++;
111
+ }
112
+ else {
113
+ report.stale++;
114
+ }
115
+ }
116
+ }
117
+ }
118
+ this.#logger.info('SourceRefReconciler: reconcile complete', {
119
+ inserted: report.inserted,
120
+ active: report.active,
121
+ stale: report.stale,
122
+ skipped: report.skipped,
123
+ recipesProcessed: report.recipesProcessed,
124
+ });
125
+ return report;
126
+ }
127
+ /**
128
+ * 对 stale 条目尝试 git rename 修复。
129
+ * 使用 execFile() 安全执行 git log(防止命令注入)。
130
+ */
131
+ async repairRenames() {
132
+ const report = { renamed: 0, stillStale: 0 };
133
+ // 获取所有 stale 条目
134
+ const staleRows = this.#db
135
+ .prepare(`SELECT recipe_id, source_path FROM recipe_source_refs WHERE status = 'stale'`)
136
+ .all();
137
+ if (staleRows.length === 0) {
138
+ return report;
139
+ }
140
+ // 获取 git rename 映射
141
+ const renameMap = await this.#getGitRenameMap();
142
+ const now = Date.now();
143
+ for (const row of staleRows) {
144
+ const newPath = renameMap.get(row.source_path);
145
+ if (newPath) {
146
+ // 验证 newPath 存在
147
+ const absNewPath = path.resolve(this.#projectRoot, newPath);
148
+ if (fs.existsSync(absNewPath)) {
149
+ this.#db
150
+ .prepare(`UPDATE recipe_source_refs SET status = 'renamed', new_path = ?, verified_at = ? WHERE recipe_id = ? AND source_path = ?`)
151
+ .run(newPath, now, row.recipe_id, row.source_path);
152
+ report.renamed++;
153
+ continue;
154
+ }
155
+ }
156
+ report.stillStale++;
157
+ }
158
+ if (report.renamed > 0) {
159
+ this.#logger.info('SourceRefReconciler: rename repair complete', {
160
+ renamed: report.renamed,
161
+ stillStale: report.stillStale,
162
+ });
163
+ }
164
+ return report;
165
+ }
166
+ /**
167
+ * 将 renamed 条目的 new_path 写回 Recipe .md 文件的 _reasoning.sources。
168
+ * 完成后 status → active。
169
+ */
170
+ applyRepairs() {
171
+ const report = { applied: 0, failed: 0 };
172
+ const renamedRows = this.#db
173
+ .prepare(`SELECT recipe_id, source_path, new_path FROM recipe_source_refs WHERE status = 'renamed' AND new_path IS NOT NULL`)
174
+ .all();
175
+ if (renamedRows.length === 0) {
176
+ return report;
177
+ }
178
+ // 按 recipe_id 分组
179
+ const byRecipe = new Map();
180
+ for (const row of renamedRows) {
181
+ if (!byRecipe.has(row.recipe_id)) {
182
+ byRecipe.set(row.recipe_id, []);
183
+ }
184
+ byRecipe.get(row.recipe_id)?.push({ source_path: row.source_path, new_path: row.new_path });
185
+ }
186
+ // 获取 recipe 的 sourceFile 以定位 .md 文件
187
+ const now = Date.now();
188
+ for (const [recipeId, renames] of byRecipe) {
189
+ try {
190
+ const entry = this.#db
191
+ .prepare(`SELECT sourceFile, reasoning FROM knowledge_entries WHERE id = ?`)
192
+ .get(recipeId);
193
+ if (!entry?.sourceFile || !entry.reasoning) {
194
+ report.failed += renames.length;
195
+ continue;
196
+ }
197
+ const mdPath = path.resolve(this.#projectRoot, entry.sourceFile);
198
+ if (!fs.existsSync(mdPath)) {
199
+ report.failed += renames.length;
200
+ continue;
201
+ }
202
+ // 读取并修改 .md 文件中的 reasoning.sources
203
+ const _content = fs.readFileSync(mdPath, 'utf8');
204
+ let reasoning;
205
+ try {
206
+ reasoning = JSON.parse(entry.reasoning);
207
+ }
208
+ catch {
209
+ report.failed += renames.length;
210
+ continue;
211
+ }
212
+ const sources = Array.isArray(reasoning.sources) ? [...reasoning.sources] : [];
213
+ let modified = false;
214
+ for (const rename of renames) {
215
+ const idx = sources.indexOf(rename.source_path);
216
+ if (idx >= 0) {
217
+ sources[idx] = rename.new_path;
218
+ modified = true;
219
+ }
220
+ }
221
+ if (modified) {
222
+ reasoning.sources = sources;
223
+ // 更新 .md 文件中的 reasoning frontmatter
224
+ // 查找 YAML frontmatter 中的 reasoning 并替换
225
+ const updatedReasoning = JSON.stringify(reasoning);
226
+ // 更新 DB reasoning 列
227
+ this.#db
228
+ .prepare(`UPDATE knowledge_entries SET reasoning = ?, updatedAt = ? WHERE id = ?`)
229
+ .run(updatedReasoning, now, recipeId);
230
+ // 更新 recipe_source_refs 状态
231
+ for (const rename of renames) {
232
+ this.#db
233
+ .prepare(`UPDATE recipe_source_refs SET status = 'active', source_path = ?, new_path = NULL, verified_at = ? WHERE recipe_id = ? AND source_path = ?`)
234
+ .run(rename.new_path, now, recipeId, rename.source_path);
235
+ }
236
+ report.applied += renames.length;
237
+ }
238
+ else {
239
+ report.failed += renames.length;
240
+ }
241
+ }
242
+ catch (err) {
243
+ this.#logger.warn('SourceRefReconciler: applyRepairs failed for recipe', {
244
+ recipeId,
245
+ error: err.message,
246
+ });
247
+ report.failed += renames.length;
248
+ }
249
+ }
250
+ if (report.applied > 0) {
251
+ this.#logger.info('SourceRefReconciler: applyRepairs complete', report);
252
+ }
253
+ return report;
254
+ }
255
+ /* ═══ Private helpers ═══════════════════════════════ */
256
+ #ensureTable() {
257
+ try {
258
+ this.#db.prepare(`SELECT 1 FROM recipe_source_refs LIMIT 1`).get();
259
+ }
260
+ catch {
261
+ // 表不存在,创建之
262
+ this.#db.exec?.(`CREATE TABLE IF NOT EXISTS recipe_source_refs (
263
+ recipe_id TEXT NOT NULL,
264
+ source_path TEXT NOT NULL,
265
+ status TEXT NOT NULL DEFAULT 'active',
266
+ new_path TEXT,
267
+ verified_at INTEGER NOT NULL,
268
+ PRIMARY KEY (recipe_id, source_path),
269
+ FOREIGN KEY (recipe_id) REFERENCES knowledge_entries(id) ON DELETE CASCADE
270
+ );
271
+ CREATE INDEX IF NOT EXISTS idx_rsr_path ON recipe_source_refs(source_path);
272
+ CREATE INDEX IF NOT EXISTS idx_rsr_status ON recipe_source_refs(status);`);
273
+ }
274
+ }
275
+ /**
276
+ * 通过 git log 获取 rename 映射(旧路径 → 新路径)
277
+ * 使用 execFile 防止命令注入
278
+ */
279
+ async #getGitRenameMap() {
280
+ const renameMap = new Map();
281
+ try {
282
+ const { stdout } = await execFileAsync('git', ['log', '--diff-filter=R', '--name-status', '--pretty=format:', '-n', '200'], {
283
+ cwd: this.#projectRoot,
284
+ timeout: 10000,
285
+ maxBuffer: 1024 * 1024,
286
+ });
287
+ // 解析 git log 输出: R100\told_path\tnew_path
288
+ for (const line of stdout.split('\n')) {
289
+ const trimmed = line.trim();
290
+ if (!trimmed.startsWith('R')) {
291
+ continue;
292
+ }
293
+ const parts = trimmed.split('\t');
294
+ if (parts.length >= 3) {
295
+ const oldPath = parts[1];
296
+ const newPath = parts[2];
297
+ if (oldPath && newPath) {
298
+ renameMap.set(oldPath, newPath);
299
+ }
300
+ }
301
+ }
302
+ }
303
+ catch {
304
+ // git 不可用或不在 git 仓库中 — 跳过 rename 检测
305
+ this.#logger.debug('SourceRefReconciler: git rename detection unavailable');
306
+ }
307
+ return renameMap;
308
+ }
309
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * CouplingAnalyzer — 模块耦合分析
3
+ *
4
+ * 三边融合 (import + call + dataFlow) 构建加权依赖图,
5
+ * 使用 Tarjan SCC 检测循环依赖,计算 fanIn/fanOut。
6
+ *
7
+ * @module CouplingAnalyzer
8
+ */
9
+ import type { CeDbLike, CyclicDependency, Edge } from './PanoramaTypes.js';
10
+ export interface CouplingMetrics {
11
+ fanIn: number;
12
+ fanOut: number;
13
+ }
14
+ export interface CouplingResult {
15
+ cycles: CyclicDependency[];
16
+ metrics: Map<string, CouplingMetrics>;
17
+ edges: Edge[];
18
+ }
19
+ export declare class CouplingAnalyzer {
20
+ #private;
21
+ constructor(db: CeDbLike, projectRoot: string);
22
+ /**
23
+ * 分析模块间耦合关系
24
+ * @param moduleFiles - Map<moduleName, filePaths[]>
25
+ */
26
+ analyze(moduleFiles: Map<string, string[]>): CouplingResult;
27
+ }