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
@@ -1,171 +0,0 @@
1
- import type { Database, Statement } from 'better-sqlite3';
2
- import type { Logger as WinstonLogger } from 'winston';
3
- import { Task } from '../../domain/task/Task.js';
4
- import type { DrizzleDB } from '../../infrastructure/database/drizzle/index.js';
5
- /** Row shape returned by task_dependencies queries (camelCase — matches Drizzle schema) */
6
- interface TaskDependencyRow {
7
- id: number;
8
- taskId: string;
9
- dependsOnId: string;
10
- depType: string;
11
- metadata: string | null;
12
- createdAt: number;
13
- createdBy: string | null;
14
- }
15
- /** Filters accepted by findAll */
16
- interface TaskFilters {
17
- status?: string;
18
- taskType?: string;
19
- assignee?: string;
20
- parentId?: string;
21
- }
22
- /** Options accepted by findAll */
23
- interface TaskFindOptions {
24
- limit?: number;
25
- offset?: number;
26
- orderBy?: string;
27
- }
28
- /** Column mapping for update fields */
29
- interface TaskUpdateFields {
30
- status?: string;
31
- priority?: number;
32
- assignee?: string;
33
- notes?: string;
34
- description?: string;
35
- design?: string;
36
- acceptance?: string;
37
- closeReason?: string;
38
- closedAt?: number | null;
39
- updatedAt?: number;
40
- failCount?: number;
41
- lastFailReason?: string;
42
- childSeq?: number;
43
- metadata?: Record<string, unknown>;
44
- [key: string]: unknown;
45
- }
46
- /** Database connection wrapper interface */
47
- interface DatabaseWrapper {
48
- getDb(): Database;
49
- }
50
- /**
51
- * TaskRepositoryImpl — 任务实体 SQLite 持久化 (Drizzle ORM)
52
- *
53
- * DB 列名 snake_case,实体属性 camelCase—— Task.fromRow() / _entityToRow() 负责映射。
54
- *
55
- * Drizzle 迁移策略:
56
- * - CRUD (create/findById/update/delete) → drizzle 类型安全 API
57
- * - 依赖管理 (add/remove/get) → drizzle 类型安全 API
58
- * - 事件审计 / 统计 → drizzle 类型安全 API
59
- * - 环检测 (递归 CTE) / 复杂动态查询 (findAll) → 保留 raw SQL
60
- */
61
- export declare class TaskRepositoryImpl {
62
- #private;
63
- _reachableStmt: Statement;
64
- db: Database;
65
- logger: WinstonLogger;
66
- constructor(database: DatabaseWrapper, drizzle?: DrizzleDB);
67
- /** 预编译复杂查询(仅保留 drizzle 无法表达的递归 CTE) */
68
- private _prepareStatements;
69
- /**
70
- * 创建任务
71
- * ★ Drizzle 类型安全 INSERT
72
- */
73
- create(task: Task): Task | null;
74
- /**
75
- * 按 ID 查询
76
- * ★ Drizzle 类型安全 SELECT
77
- */
78
- findById(id: string): Task | null;
79
- /**
80
- * 按内容哈希查询(去重用)
81
- * ★ Drizzle 类型安全 SELECT
82
- */
83
- findByContentHash(hash: string | null): Task | null;
84
- /**
85
- * 更新任务字段
86
- * ★ Drizzle 类型安全 UPDATE
87
- */
88
- update(id: string, fields: TaskUpdateFields): Task | null;
89
- /**
90
- * 删除任务
91
- * ★ Drizzle 类型安全 DELETE
92
- */
93
- delete(id: string): boolean;
94
- /**
95
- * 列表查询
96
- * @param filters { status, taskType, assignee, parentId }
97
- * @param options { limit, offset, orderBy }
98
- */
99
- findAll(filters?: TaskFilters, options?: TaskFindOptions): (Task | null)[];
100
- /**
101
- * 添加依赖
102
- * ★ Drizzle 类型安全 INSERT OR IGNORE
103
- */
104
- addDependency(taskId: string, dependsOnId: string, depType: string): void;
105
- /**
106
- * 删除依赖
107
- * ★ Drizzle 类型安全 DELETE
108
- */
109
- removeDependency(taskId: string, dependsOnId: string, depType: string): void;
110
- /**
111
- * 获取任务的所有依赖
112
- * ★ Drizzle 类型安全 SELECT
113
- */
114
- getDependencies(taskId: string): TaskDependencyRow[];
115
- /**
116
- * 获取依赖此任务的所有任务
117
- * ★ Drizzle 类型安全 SELECT
118
- */
119
- getDependents(dependsOnId: string): TaskDependencyRow[];
120
- /**
121
- * 获取阻塞某任务的所有任务(含任务详情)
122
- * 保留 raw SQL — JOIN 查询
123
- */
124
- getBlockers(taskId: string): (Task | null)[];
125
- /** 环检测:检查 fromId → toId 是否已有可达路径 */
126
- hasReachablePath(fromId: string, toId: string): boolean;
127
- /** 在事务中执行操作 */
128
- inTransaction<T>(fn: () => T): T;
129
- /**
130
- * 获取任务统计
131
- * 保留 raw SQL — SUM(CASE WHEN) 聚合在 drizzle 中不如直写清晰
132
- */
133
- getStatistics(): {
134
- total: number;
135
- open: number;
136
- in_progress: number;
137
- closed: number;
138
- deferred: number;
139
- pinned: number;
140
- };
141
- /**
142
- * 记录任务事件
143
- * ★ Drizzle 类型安全 INSERT
144
- */
145
- logEvent(taskId: string, eventType: string, oldValue?: string | null, newValue?: string | null, comment?: string | null, actor?: string): void;
146
- /** 实体 → DB 行 (camelCase → snake_case) */
147
- _entityToRow(task: Task): {
148
- id: string;
149
- parentId: string | null;
150
- childSeq: number;
151
- title: string;
152
- description: string;
153
- design: string;
154
- acceptance: string;
155
- notes: string;
156
- status: string;
157
- priority: number;
158
- taskType: string;
159
- closeReason: string;
160
- contentHash: string;
161
- failCount: number;
162
- lastFailReason: string;
163
- assignee: string;
164
- createdBy: string;
165
- createdAt: number;
166
- updatedAt: number;
167
- closedAt: number | null;
168
- metadata: string;
169
- };
170
- }
171
- export default TaskRepositoryImpl;
@@ -1,347 +0,0 @@
1
- import { and, asc, eq, sql } from 'drizzle-orm';
2
- import { Task } from '../../domain/task/Task.js';
3
- import { getDrizzle } from '../../infrastructure/database/drizzle/index.js';
4
- import { taskDependencies, taskEvents, tasks, } from '../../infrastructure/database/drizzle/schema.js';
5
- import Logger from '../../infrastructure/logging/Logger.js';
6
- /**
7
- * TaskRepositoryImpl — 任务实体 SQLite 持久化 (Drizzle ORM)
8
- *
9
- * DB 列名 snake_case,实体属性 camelCase—— Task.fromRow() / _entityToRow() 负责映射。
10
- *
11
- * Drizzle 迁移策略:
12
- * - CRUD (create/findById/update/delete) → drizzle 类型安全 API
13
- * - 依赖管理 (add/remove/get) → drizzle 类型安全 API
14
- * - 事件审计 / 统计 → drizzle 类型安全 API
15
- * - 环检测 (递归 CTE) / 复杂动态查询 (findAll) → 保留 raw SQL
16
- */
17
- export class TaskRepositoryImpl {
18
- _reachableStmt;
19
- #drizzle;
20
- db;
21
- logger;
22
- constructor(database, drizzle) {
23
- this.db = database.getDb();
24
- this.logger = Logger.getInstance();
25
- this.#drizzle = drizzle ?? getDrizzle();
26
- this._prepareStatements();
27
- }
28
- /** 预编译复杂查询(仅保留 drizzle 无法表达的递归 CTE) */
29
- _prepareStatements() {
30
- // ── 环检测 (递归 CTE) — drizzle 不支持递归 CTE ──
31
- this._reachableStmt = this.db.prepare(`
32
- WITH RECURSIVE reachable(id, depth) AS (
33
- SELECT depends_on_id, 1
34
- FROM task_dependencies
35
- WHERE task_id = ?
36
- AND dep_type IN ('blocks', 'waits-for')
37
-
38
- UNION ALL
39
-
40
- SELECT td.depends_on_id, r.depth + 1
41
- FROM task_dependencies td
42
- JOIN reachable r ON td.task_id = r.id
43
- WHERE td.dep_type IN ('blocks', 'waits-for')
44
- AND r.depth < 50
45
- )
46
- SELECT 1 FROM reachable WHERE id = ? LIMIT 1
47
- `);
48
- }
49
- // ═══ CRUD ═══════════════════════════════════════════
50
- /**
51
- * 创建任务
52
- * ★ Drizzle 类型安全 INSERT
53
- */
54
- create(task) {
55
- const row = this._entityToRow(task);
56
- this.#drizzle.insert(tasks).values(row).run();
57
- return this.findById(task.id);
58
- }
59
- /**
60
- * 按 ID 查询
61
- * ★ Drizzle 类型安全 SELECT
62
- */
63
- findById(id) {
64
- const row = this.#drizzle.select().from(tasks).where(eq(tasks.id, id)).get();
65
- return row ? Task.fromRow(row) : null;
66
- }
67
- /**
68
- * 按内容哈希查询(去重用)
69
- * ★ Drizzle 类型安全 SELECT
70
- */
71
- findByContentHash(hash) {
72
- if (!hash) {
73
- return null;
74
- }
75
- const row = this.#drizzle
76
- .select()
77
- .from(tasks)
78
- .where(and(eq(tasks.contentHash, hash), sql `${tasks.status} != 'closed'`))
79
- .get();
80
- return row ? Task.fromRow(row) : null;
81
- }
82
- /**
83
- * 更新任务字段
84
- * ★ Drizzle 类型安全 UPDATE
85
- */
86
- update(id, fields) {
87
- const setObj = {};
88
- const columnMap = {
89
- status: 'status',
90
- priority: 'priority',
91
- assignee: 'assignee',
92
- notes: 'notes',
93
- description: 'description',
94
- design: 'design',
95
- acceptance: 'acceptance',
96
- closeReason: 'closeReason',
97
- closedAt: 'closedAt',
98
- updatedAt: 'updatedAt',
99
- failCount: 'failCount',
100
- lastFailReason: 'lastFailReason',
101
- childSeq: 'childSeq',
102
- metadata: 'metadata',
103
- };
104
- for (const [key, value] of Object.entries(fields)) {
105
- const schemaKey = columnMap[key];
106
- if (!schemaKey) {
107
- continue;
108
- }
109
- setObj[schemaKey] = key === 'metadata' ? JSON.stringify(value) : value;
110
- }
111
- if (Object.keys(setObj).length === 0) {
112
- return this.findById(id);
113
- }
114
- // 始终更新 updatedAt
115
- if (!fields.updatedAt) {
116
- setObj.updatedAt = Math.floor(Date.now() / 1000);
117
- }
118
- this.#drizzle.update(tasks).set(setObj).where(eq(tasks.id, id)).run();
119
- return this.findById(id);
120
- }
121
- /**
122
- * 删除任务
123
- * ★ Drizzle 类型安全 DELETE
124
- */
125
- delete(id) {
126
- const result = this.#drizzle.delete(tasks).where(eq(tasks.id, id)).run();
127
- return result.changes > 0;
128
- }
129
- /**
130
- * 列表查询
131
- * @param filters { status, taskType, assignee, parentId }
132
- * @param options { limit, offset, orderBy }
133
- */
134
- findAll(filters = {}, options = {}) {
135
- const conditions = [];
136
- const params = [];
137
- if (filters.status) {
138
- conditions.push('status = ?');
139
- params.push(filters.status);
140
- }
141
- if (filters.taskType) {
142
- conditions.push('task_type = ?');
143
- params.push(filters.taskType);
144
- }
145
- if (filters.assignee) {
146
- conditions.push('assignee = ?');
147
- params.push(filters.assignee);
148
- }
149
- if (filters.parentId) {
150
- conditions.push('parent_id = ?');
151
- params.push(filters.parentId);
152
- }
153
- const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
154
- const limit = Math.max(1, Math.min(options.limit || 50, 500));
155
- const offset = Math.max(0, options.offset || 0);
156
- const orderBy = _sanitizeOrderBy(options.orderBy);
157
- const sql = `SELECT * FROM tasks ${where} ORDER BY ${orderBy} LIMIT ? OFFSET ?`;
158
- params.push(limit, offset);
159
- const rows = this.db.prepare(sql).all(...params);
160
- return rows.map((r) => Task.fromRow(r));
161
- }
162
- // ═══ 依赖管理 ═══════════════════════════════════════
163
- /**
164
- * 添加依赖
165
- * ★ Drizzle 类型安全 INSERT OR IGNORE
166
- */
167
- addDependency(taskId, dependsOnId, depType) {
168
- this.#drizzle
169
- .insert(taskDependencies)
170
- .values({
171
- taskId,
172
- dependsOnId,
173
- depType,
174
- createdAt: Math.floor(Date.now() / 1000),
175
- createdBy: 'agent',
176
- })
177
- .onConflictDoNothing()
178
- .run();
179
- }
180
- /**
181
- * 删除依赖
182
- * ★ Drizzle 类型安全 DELETE
183
- */
184
- removeDependency(taskId, dependsOnId, depType) {
185
- this.#drizzle
186
- .delete(taskDependencies)
187
- .where(and(eq(taskDependencies.taskId, taskId), eq(taskDependencies.dependsOnId, dependsOnId), eq(taskDependencies.depType, depType)))
188
- .run();
189
- }
190
- /**
191
- * 获取任务的所有依赖
192
- * ★ Drizzle 类型安全 SELECT
193
- */
194
- getDependencies(taskId) {
195
- return this.#drizzle
196
- .select()
197
- .from(taskDependencies)
198
- .where(eq(taskDependencies.taskId, taskId))
199
- .orderBy(asc(taskDependencies.createdAt))
200
- .all();
201
- }
202
- /**
203
- * 获取依赖此任务的所有任务
204
- * ★ Drizzle 类型安全 SELECT
205
- */
206
- getDependents(dependsOnId) {
207
- return this.#drizzle
208
- .select()
209
- .from(taskDependencies)
210
- .where(eq(taskDependencies.dependsOnId, dependsOnId))
211
- .all();
212
- }
213
- /**
214
- * 获取阻塞某任务的所有任务(含任务详情)
215
- * 保留 raw SQL — JOIN 查询
216
- */
217
- getBlockers(taskId) {
218
- const rows = this.db
219
- .prepare(`
220
- SELECT t.*
221
- FROM task_dependencies td
222
- JOIN tasks t ON td.depends_on_id = t.id
223
- WHERE td.task_id = ?
224
- AND td.dep_type IN ('blocks', 'waits-for')
225
- AND t.status != 'closed'
226
- `)
227
- .all(taskId);
228
- return rows.map((r) => Task.fromRow(r));
229
- }
230
- /** 环检测:检查 fromId → toId 是否已有可达路径 */
231
- hasReachablePath(fromId, toId) {
232
- const row = this._reachableStmt.get(fromId, toId);
233
- return !!row;
234
- }
235
- // ═══ 事务支持 ═══════════════════════════════════════
236
- /** 在事务中执行操作 */
237
- inTransaction(fn) {
238
- const txn = this.db.transaction(fn);
239
- return txn();
240
- }
241
- // ═══ 统计 ═══════════════════════════════════════════
242
- /**
243
- * 获取任务统计
244
- * 保留 raw SQL — SUM(CASE WHEN) 聚合在 drizzle 中不如直写清晰
245
- */
246
- getStatistics() {
247
- const row = this.db
248
- .prepare(`
249
- SELECT
250
- COUNT(*) as total,
251
- SUM(CASE WHEN status = 'open' THEN 1 ELSE 0 END) as open,
252
- SUM(CASE WHEN status = 'in_progress' THEN 1 ELSE 0 END) as in_progress,
253
- SUM(CASE WHEN status = 'closed' THEN 1 ELSE 0 END) as closed,
254
- SUM(CASE WHEN status = 'deferred' THEN 1 ELSE 0 END) as deferred,
255
- SUM(CASE WHEN status = 'pinned' THEN 1 ELSE 0 END) as pinned
256
- FROM tasks
257
- `)
258
- .get();
259
- return {
260
- total: row.total || 0,
261
- open: row.open || 0,
262
- in_progress: row.in_progress || 0,
263
- closed: row.closed || 0,
264
- deferred: row.deferred || 0,
265
- pinned: row.pinned || 0,
266
- };
267
- }
268
- // ═══ 事件审计 ═══════════════════════════════════════
269
- /**
270
- * 记录任务事件
271
- * ★ Drizzle 类型安全 INSERT
272
- */
273
- logEvent(taskId, eventType, oldValue = null, newValue = null, comment = null, actor = 'agent') {
274
- this.#drizzle
275
- .insert(taskEvents)
276
- .values({
277
- taskId,
278
- eventType,
279
- actor,
280
- oldValue,
281
- newValue,
282
- comment,
283
- createdAt: Math.floor(Date.now() / 1000),
284
- })
285
- .run();
286
- }
287
- // ═══ 私有方法 ═══════════════════════════════════════
288
- /** 实体 → DB 行 (camelCase → snake_case) */
289
- _entityToRow(task) {
290
- return {
291
- id: task.id,
292
- parentId: task.parentId || null,
293
- childSeq: task.childSeq || 0,
294
- title: task.title,
295
- description: task.description || '',
296
- design: task.design || '',
297
- acceptance: task.acceptance || '',
298
- notes: task.notes || '',
299
- status: task.status,
300
- priority: task.priority ?? 2,
301
- taskType: task.taskType || 'task',
302
- closeReason: task.closeReason || '',
303
- contentHash: task.contentHash || '',
304
- failCount: task.failCount || 0,
305
- lastFailReason: task.lastFailReason || '',
306
- assignee: task.assignee || '',
307
- createdBy: task.createdBy || 'agent',
308
- createdAt: task.createdAt,
309
- updatedAt: task.updatedAt,
310
- closedAt: task.closedAt || null,
311
- metadata: JSON.stringify(task.metadata || {}),
312
- };
313
- }
314
- }
315
- // ═══ 内部工具 ═══════════════════════════════════════
316
- const ALLOWED_ORDER_FIELDS = new Set([
317
- 'priority',
318
- 'created_at',
319
- 'updated_at',
320
- 'status',
321
- 'title',
322
- 'task_type',
323
- 'closed_at',
324
- ]);
325
- const ALLOWED_DIRECTIONS = new Set(['ASC', 'DESC']);
326
- /** orderBy 白名单校验,防止 SQL 注入 */
327
- function _sanitizeOrderBy(orderBy) {
328
- if (!orderBy) {
329
- return 'priority ASC, created_at ASC';
330
- }
331
- return (orderBy
332
- .split(',')
333
- .map((clause) => {
334
- const parts = clause.trim().split(/\s+/);
335
- const field = parts[0];
336
- if (!ALLOWED_ORDER_FIELDS.has(field)) {
337
- return null;
338
- }
339
- const dir = ALLOWED_DIRECTIONS.has(parts[1]?.toUpperCase())
340
- ? parts[1].toUpperCase()
341
- : 'ASC';
342
- return `${field} ${dir}`;
343
- })
344
- .filter(Boolean)
345
- .join(', ') || 'priority ASC, created_at ASC');
346
- }
347
- export default TaskRepositoryImpl;