@jamesaphoenix/tx-core 0.4.2 → 0.4.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 (330) hide show
  1. package/README.md +480 -0
  2. package/dist/db.d.ts +28 -14
  3. package/dist/db.d.ts.map +1 -1
  4. package/dist/db.js +102 -14
  5. package/dist/db.js.map +1 -1
  6. package/dist/errors.d.ts +178 -34
  7. package/dist/errors.d.ts.map +1 -1
  8. package/dist/errors.js +119 -26
  9. package/dist/errors.js.map +1 -1
  10. package/dist/id.d.ts +10 -0
  11. package/dist/id.d.ts.map +1 -1
  12. package/dist/id.js +17 -1
  13. package/dist/id.js.map +1 -1
  14. package/dist/index.d.ts +15 -7
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +62 -8
  17. package/dist/index.js.map +1 -1
  18. package/dist/layer.d.ts +23 -14
  19. package/dist/layer.d.ts.map +1 -1
  20. package/dist/layer.js +75 -76
  21. package/dist/layer.js.map +1 -1
  22. package/dist/mappers/anchor.d.ts +15 -1
  23. package/dist/mappers/anchor.d.ts.map +1 -1
  24. package/dist/mappers/anchor.js +95 -28
  25. package/dist/mappers/anchor.js.map +1 -1
  26. package/dist/mappers/attempt.d.ts +3 -1
  27. package/dist/mappers/attempt.d.ts.map +1 -1
  28. package/dist/mappers/attempt.js +23 -9
  29. package/dist/mappers/attempt.js.map +1 -1
  30. package/dist/mappers/candidate.d.ts +3 -1
  31. package/dist/mappers/candidate.d.ts.map +1 -1
  32. package/dist/mappers/candidate.js +46 -16
  33. package/dist/mappers/candidate.js.map +1 -1
  34. package/dist/mappers/claim.d.ts +1 -1
  35. package/dist/mappers/claim.d.ts.map +1 -1
  36. package/dist/mappers/claim.js +11 -4
  37. package/dist/mappers/claim.js.map +1 -1
  38. package/dist/mappers/deduplication.d.ts +13 -1
  39. package/dist/mappers/deduplication.d.ts.map +1 -1
  40. package/dist/mappers/deduplication.js +22 -3
  41. package/dist/mappers/deduplication.js.map +1 -1
  42. package/dist/mappers/doc.d.ts +24 -0
  43. package/dist/mappers/doc.d.ts.map +1 -0
  44. package/dist/mappers/doc.js +161 -0
  45. package/dist/mappers/doc.js.map +1 -0
  46. package/dist/mappers/edge.d.ts +10 -1
  47. package/dist/mappers/edge.d.ts.map +1 -1
  48. package/dist/mappers/edge.js +74 -12
  49. package/dist/mappers/edge.js.map +1 -1
  50. package/dist/mappers/file-learning.d.ts.map +1 -1
  51. package/dist/mappers/file-learning.js +2 -1
  52. package/dist/mappers/file-learning.js.map +1 -1
  53. package/dist/mappers/index.d.ts +6 -7
  54. package/dist/mappers/index.d.ts.map +1 -1
  55. package/dist/mappers/index.js +10 -12
  56. package/dist/mappers/index.js.map +1 -1
  57. package/dist/mappers/learning.d.ts +9 -1
  58. package/dist/mappers/learning.d.ts.map +1 -1
  59. package/dist/mappers/learning.js +94 -14
  60. package/dist/mappers/learning.js.map +1 -1
  61. package/dist/mappers/orchestrator-state.d.ts +1 -1
  62. package/dist/mappers/orchestrator-state.d.ts.map +1 -1
  63. package/dist/mappers/orchestrator-state.js +31 -5
  64. package/dist/mappers/orchestrator-state.js.map +1 -1
  65. package/dist/mappers/parse-date.d.ts +11 -0
  66. package/dist/mappers/parse-date.d.ts.map +1 -0
  67. package/dist/mappers/parse-date.js +18 -0
  68. package/dist/mappers/parse-date.js.map +1 -0
  69. package/dist/mappers/run.d.ts +14 -4
  70. package/dist/mappers/run.d.ts.map +1 -1
  71. package/dist/mappers/run.js +49 -18
  72. package/dist/mappers/run.js.map +1 -1
  73. package/dist/mappers/task.d.ts +5 -1
  74. package/dist/mappers/task.d.ts.map +1 -1
  75. package/dist/mappers/task.js +66 -16
  76. package/dist/mappers/task.js.map +1 -1
  77. package/dist/mappers/tracked-project.d.ts +3 -1
  78. package/dist/mappers/tracked-project.d.ts.map +1 -1
  79. package/dist/mappers/tracked-project.js +23 -9
  80. package/dist/mappers/tracked-project.js.map +1 -1
  81. package/dist/mappers/worker.d.ts +1 -1
  82. package/dist/mappers/worker.d.ts.map +1 -1
  83. package/dist/mappers/worker.js +44 -6
  84. package/dist/mappers/worker.js.map +1 -1
  85. package/dist/repo/anchor-repo.d.ts +2 -2
  86. package/dist/repo/anchor-repo.d.ts.map +1 -1
  87. package/dist/repo/anchor-repo.js +46 -5
  88. package/dist/repo/anchor-repo.js.map +1 -1
  89. package/dist/repo/attempt-repo.d.ts +2 -2
  90. package/dist/repo/attempt-repo.d.ts.map +1 -1
  91. package/dist/repo/attempt-repo.js +16 -6
  92. package/dist/repo/attempt-repo.js.map +1 -1
  93. package/dist/repo/candidate-repo.d.ts.map +1 -1
  94. package/dist/repo/candidate-repo.js +22 -1
  95. package/dist/repo/candidate-repo.js.map +1 -1
  96. package/dist/repo/claim-repo.d.ts +46 -2
  97. package/dist/repo/claim-repo.d.ts.map +1 -1
  98. package/dist/repo/claim-repo.js +113 -6
  99. package/dist/repo/claim-repo.js.map +1 -1
  100. package/dist/repo/compaction-repo.d.ts +41 -0
  101. package/dist/repo/compaction-repo.d.ts.map +1 -0
  102. package/dist/repo/compaction-repo.js +84 -0
  103. package/dist/repo/compaction-repo.js.map +1 -0
  104. package/dist/repo/deduplication-repo.d.ts +9 -1
  105. package/dist/repo/deduplication-repo.d.ts.map +1 -1
  106. package/dist/repo/deduplication-repo.js +46 -9
  107. package/dist/repo/deduplication-repo.js.map +1 -1
  108. package/dist/repo/dep-repo.d.ts +27 -3
  109. package/dist/repo/dep-repo.d.ts.map +1 -1
  110. package/dist/repo/dep-repo.js +166 -39
  111. package/dist/repo/dep-repo.js.map +1 -1
  112. package/dist/repo/doc-repo.d.ts +59 -0
  113. package/dist/repo/doc-repo.d.ts.map +1 -0
  114. package/dist/repo/doc-repo.js +276 -0
  115. package/dist/repo/doc-repo.js.map +1 -0
  116. package/dist/repo/edge-repo.d.ts +1 -1
  117. package/dist/repo/edge-repo.d.ts.map +1 -1
  118. package/dist/repo/edge-repo.js +65 -34
  119. package/dist/repo/edge-repo.js.map +1 -1
  120. package/dist/repo/file-learning-repo.d.ts +3 -3
  121. package/dist/repo/file-learning-repo.d.ts.map +1 -1
  122. package/dist/repo/file-learning-repo.js +19 -8
  123. package/dist/repo/file-learning-repo.js.map +1 -1
  124. package/dist/repo/index.d.ts +4 -6
  125. package/dist/repo/index.d.ts.map +1 -1
  126. package/dist/repo/index.js +3 -5
  127. package/dist/repo/index.js.map +1 -1
  128. package/dist/repo/learning-repo.d.ts +10 -3
  129. package/dist/repo/learning-repo.d.ts.map +1 -1
  130. package/dist/repo/learning-repo.js +68 -11
  131. package/dist/repo/learning-repo.js.map +1 -1
  132. package/dist/repo/orchestrator-state-repo.d.ts.map +1 -1
  133. package/dist/repo/orchestrator-state-repo.js +8 -1
  134. package/dist/repo/orchestrator-state-repo.js.map +1 -1
  135. package/dist/repo/run-repo.d.ts +3 -3
  136. package/dist/repo/run-repo.d.ts.map +1 -1
  137. package/dist/repo/run-repo.js +40 -19
  138. package/dist/repo/run-repo.js.map +1 -1
  139. package/dist/repo/task-repo.d.ts +14 -3
  140. package/dist/repo/task-repo.d.ts.map +1 -1
  141. package/dist/repo/task-repo.js +194 -20
  142. package/dist/repo/task-repo.js.map +1 -1
  143. package/dist/repo/tracked-project-repo.d.ts.map +1 -1
  144. package/dist/repo/tracked-project-repo.js +15 -1
  145. package/dist/repo/tracked-project-repo.js.map +1 -1
  146. package/dist/repo/worker-repo.d.ts +3 -2
  147. package/dist/repo/worker-repo.d.ts.map +1 -1
  148. package/dist/repo/worker-repo.js +54 -8
  149. package/dist/repo/worker-repo.js.map +1 -1
  150. package/dist/schemas/sync.js +2 -2
  151. package/dist/schemas/sync.js.map +1 -1
  152. package/dist/schemas/worker.d.ts +1 -0
  153. package/dist/schemas/worker.d.ts.map +1 -1
  154. package/dist/schemas/worker.js +1 -0
  155. package/dist/schemas/worker.js.map +1 -1
  156. package/dist/services/agent-service.d.ts +57 -0
  157. package/dist/services/agent-service.d.ts.map +1 -0
  158. package/dist/services/agent-service.js +81 -0
  159. package/dist/services/agent-service.js.map +1 -0
  160. package/dist/services/anchor-service.js +1 -1
  161. package/dist/services/anchor-service.js.map +1 -1
  162. package/dist/services/anchor-verification.d.ts +8 -0
  163. package/dist/services/anchor-verification.d.ts.map +1 -1
  164. package/dist/services/anchor-verification.js +237 -37
  165. package/dist/services/anchor-verification.js.map +1 -1
  166. package/dist/services/ast-grep-service.d.ts.map +1 -1
  167. package/dist/services/ast-grep-service.js +93 -22
  168. package/dist/services/ast-grep-service.js.map +1 -1
  169. package/dist/services/attempt-service.d.ts.map +1 -1
  170. package/dist/services/attempt-service.js +1 -4
  171. package/dist/services/attempt-service.js.map +1 -1
  172. package/dist/services/auto-sync-service.d.ts +1 -1
  173. package/dist/services/auto-sync-service.d.ts.map +1 -1
  174. package/dist/services/auto-sync-service.js +18 -10
  175. package/dist/services/auto-sync-service.js.map +1 -1
  176. package/dist/services/claim-service.d.ts +8 -2
  177. package/dist/services/claim-service.d.ts.map +1 -1
  178. package/dist/services/claim-service.js +37 -23
  179. package/dist/services/claim-service.js.map +1 -1
  180. package/dist/services/compaction-service.d.ts +105 -0
  181. package/dist/services/compaction-service.d.ts.map +1 -0
  182. package/dist/services/compaction-service.js +369 -0
  183. package/dist/services/compaction-service.js.map +1 -0
  184. package/dist/services/cycle-scan-service.d.ts +32 -0
  185. package/dist/services/cycle-scan-service.d.ts.map +1 -0
  186. package/dist/services/cycle-scan-service.js +542 -0
  187. package/dist/services/cycle-scan-service.js.map +1 -0
  188. package/dist/services/daemon-service.d.ts +40 -2
  189. package/dist/services/daemon-service.d.ts.map +1 -1
  190. package/dist/services/daemon-service.js +199 -52
  191. package/dist/services/daemon-service.js.map +1 -1
  192. package/dist/services/deduplication-service.d.ts +8 -4
  193. package/dist/services/deduplication-service.d.ts.map +1 -1
  194. package/dist/services/deduplication-service.js +79 -25
  195. package/dist/services/deduplication-service.js.map +1 -1
  196. package/dist/services/dep-service.d.ts +2 -2
  197. package/dist/services/dep-service.d.ts.map +1 -1
  198. package/dist/services/dep-service.js +9 -5
  199. package/dist/services/dep-service.js.map +1 -1
  200. package/dist/services/diversifier-service.d.ts +2 -1
  201. package/dist/services/diversifier-service.d.ts.map +1 -1
  202. package/dist/services/diversifier-service.js +37 -43
  203. package/dist/services/diversifier-service.js.map +1 -1
  204. package/dist/services/doc-service.d.ts +49 -0
  205. package/dist/services/doc-service.d.ts.map +1 -0
  206. package/dist/services/doc-service.js +605 -0
  207. package/dist/services/doc-service.js.map +1 -0
  208. package/dist/services/edge-service.js +2 -2
  209. package/dist/services/edge-service.js.map +1 -1
  210. package/dist/services/embedding-service.d.ts +66 -2
  211. package/dist/services/embedding-service.d.ts.map +1 -1
  212. package/dist/services/embedding-service.js +138 -24
  213. package/dist/services/embedding-service.js.map +1 -1
  214. package/dist/services/file-learning-service.d.ts.map +1 -1
  215. package/dist/services/file-learning-service.js +8 -7
  216. package/dist/services/file-learning-service.js.map +1 -1
  217. package/dist/services/file-watcher-service.d.ts.map +1 -1
  218. package/dist/services/file-watcher-service.js +58 -11
  219. package/dist/services/file-watcher-service.js.map +1 -1
  220. package/dist/services/graph-expansion.d.ts +3 -0
  221. package/dist/services/graph-expansion.d.ts.map +1 -1
  222. package/dist/services/graph-expansion.js +28 -7
  223. package/dist/services/graph-expansion.js.map +1 -1
  224. package/dist/services/hierarchy-service.d.ts +1 -1
  225. package/dist/services/hierarchy-service.d.ts.map +1 -1
  226. package/dist/services/hierarchy-service.js +50 -32
  227. package/dist/services/hierarchy-service.js.map +1 -1
  228. package/dist/services/index.d.ts +13 -15
  229. package/dist/services/index.d.ts.map +1 -1
  230. package/dist/services/index.js +13 -15
  231. package/dist/services/index.js.map +1 -1
  232. package/dist/services/learning-service.d.ts +4 -4
  233. package/dist/services/learning-service.d.ts.map +1 -1
  234. package/dist/services/learning-service.js +75 -42
  235. package/dist/services/learning-service.js.map +1 -1
  236. package/dist/services/llm-service.d.ts +62 -0
  237. package/dist/services/llm-service.d.ts.map +1 -0
  238. package/dist/services/llm-service.js +172 -0
  239. package/dist/services/llm-service.js.map +1 -0
  240. package/dist/services/migration-service.d.ts +1 -1
  241. package/dist/services/migration-service.d.ts.map +1 -1
  242. package/dist/services/migration-service.js +18 -7
  243. package/dist/services/migration-service.js.map +1 -1
  244. package/dist/services/orchestrator-service.d.ts +4 -3
  245. package/dist/services/orchestrator-service.d.ts.map +1 -1
  246. package/dist/services/orchestrator-service.js +67 -29
  247. package/dist/services/orchestrator-service.js.map +1 -1
  248. package/dist/services/promotion-service.d.ts +1 -1
  249. package/dist/services/promotion-service.js +1 -1
  250. package/dist/services/promotion-service.js.map +1 -1
  251. package/dist/services/query-expansion-service.d.ts +30 -9
  252. package/dist/services/query-expansion-service.d.ts.map +1 -1
  253. package/dist/services/query-expansion-service.js +54 -63
  254. package/dist/services/query-expansion-service.js.map +1 -1
  255. package/dist/services/ready-service.d.ts +21 -1
  256. package/dist/services/ready-service.d.ts.map +1 -1
  257. package/dist/services/ready-service.js +44 -21
  258. package/dist/services/ready-service.js.map +1 -1
  259. package/dist/services/retriever-service.d.ts +10 -10
  260. package/dist/services/retriever-service.d.ts.map +1 -1
  261. package/dist/services/retriever-service.js +53 -161
  262. package/dist/services/retriever-service.js.map +1 -1
  263. package/dist/services/swarm-verification.d.ts +2 -2
  264. package/dist/services/swarm-verification.d.ts.map +1 -1
  265. package/dist/services/swarm-verification.js +12 -6
  266. package/dist/services/swarm-verification.js.map +1 -1
  267. package/dist/services/sync-service.d.ts +17 -4
  268. package/dist/services/sync-service.d.ts.map +1 -1
  269. package/dist/services/sync-service.js +378 -114
  270. package/dist/services/sync-service.js.map +1 -1
  271. package/dist/services/task-service.d.ts +6 -4
  272. package/dist/services/task-service.d.ts.map +1 -1
  273. package/dist/services/task-service.js +162 -33
  274. package/dist/services/task-service.js.map +1 -1
  275. package/dist/services/tracing-service.d.ts +55 -0
  276. package/dist/services/tracing-service.d.ts.map +1 -0
  277. package/dist/services/tracing-service.js +99 -0
  278. package/dist/services/tracing-service.js.map +1 -0
  279. package/dist/services/transcript-adapter.d.ts +99 -0
  280. package/dist/services/transcript-adapter.d.ts.map +1 -0
  281. package/dist/services/transcript-adapter.js +283 -0
  282. package/dist/services/transcript-adapter.js.map +1 -0
  283. package/dist/services/validation-service.d.ts +85 -0
  284. package/dist/services/validation-service.d.ts.map +1 -0
  285. package/dist/services/validation-service.js +289 -0
  286. package/dist/services/validation-service.js.map +1 -0
  287. package/dist/services/worker-process.d.ts +23 -4
  288. package/dist/services/worker-process.d.ts.map +1 -1
  289. package/dist/services/worker-process.js +159 -70
  290. package/dist/services/worker-process.js.map +1 -1
  291. package/dist/services/worker-service.d.ts.map +1 -1
  292. package/dist/services/worker-service.js +7 -12
  293. package/dist/services/worker-service.js.map +1 -1
  294. package/dist/sync/claude-task-writer.d.ts +49 -0
  295. package/dist/sync/claude-task-writer.d.ts.map +1 -0
  296. package/dist/sync/claude-task-writer.js +135 -0
  297. package/dist/sync/claude-task-writer.js.map +1 -0
  298. package/dist/utils/doc-hash.d.ts +10 -0
  299. package/dist/utils/doc-hash.d.ts.map +1 -0
  300. package/dist/utils/doc-hash.js +14 -0
  301. package/dist/utils/doc-hash.js.map +1 -0
  302. package/dist/utils/doc-renderer.d.ts +44 -0
  303. package/dist/utils/doc-renderer.d.ts.map +1 -0
  304. package/dist/utils/doc-renderer.js +202 -0
  305. package/dist/utils/doc-renderer.js.map +1 -0
  306. package/dist/utils/math.d.ts +5 -1
  307. package/dist/utils/math.d.ts.map +1 -1
  308. package/dist/utils/math.js +12 -4
  309. package/dist/utils/math.js.map +1 -1
  310. package/dist/utils/sql.d.ts +9 -0
  311. package/dist/utils/sql.d.ts.map +1 -0
  312. package/dist/utils/sql.js +9 -0
  313. package/dist/utils/sql.js.map +1 -0
  314. package/dist/utils/toml-config.d.ts +22 -0
  315. package/dist/utils/toml-config.d.ts.map +1 -0
  316. package/dist/utils/toml-config.js +75 -0
  317. package/dist/utils/toml-config.js.map +1 -0
  318. package/dist/worker/hooks.d.ts +102 -0
  319. package/dist/worker/hooks.d.ts.map +1 -0
  320. package/dist/worker/hooks.js +11 -0
  321. package/dist/worker/hooks.js.map +1 -0
  322. package/dist/worker/index.d.ts +9 -0
  323. package/dist/worker/index.d.ts.map +1 -0
  324. package/dist/worker/index.js +8 -0
  325. package/dist/worker/index.js.map +1 -0
  326. package/dist/worker/run-worker.d.ts +33 -0
  327. package/dist/worker/run-worker.d.ts.map +1 -0
  328. package/dist/worker/run-worker.js +265 -0
  329. package/dist/worker/run-worker.js.map +1 -0
  330. package/package.json +14 -12
@@ -0,0 +1,369 @@
1
+ /**
2
+ * CompactionService - Compacts completed tasks and exports learnings
3
+ *
4
+ * Implements PRD-006: Task Compaction & Learnings Export
5
+ * See DD-006: LLM Integration for implementation details
6
+ */
7
+ import { Context, Effect, Layer, Config, Option } from "effect";
8
+ import { writeFileSync, existsSync, readFileSync } from "node:fs";
9
+ import { resolve, sep } from "node:path";
10
+ import { SqliteClient } from "../db.js";
11
+ import { DatabaseError, ExtractionUnavailableError, ValidationError } from "../errors.js";
12
+ import { CompactionRepository } from "../repo/compaction-repo.js";
13
+ import { rowToTask } from "../mappers/task.js";
14
+ /**
15
+ * Parse LLM JSON response, handling common formatting issues.
16
+ * Robust parser following DD-006 patterns.
17
+ */
18
+ const parseLlmJson = (raw) => {
19
+ // Step 1: Try direct parse
20
+ try {
21
+ return JSON.parse(raw);
22
+ }
23
+ catch { /* continue */ }
24
+ // Step 2: Strip markdown code fences
25
+ const fenceMatch = raw.match(/```(?:json)?\s*\n?([\s\S]*?)```/);
26
+ if (fenceMatch && fenceMatch[1]) {
27
+ try {
28
+ return JSON.parse(fenceMatch[1].trim());
29
+ }
30
+ catch { /* continue */ }
31
+ }
32
+ // Step 3: Find first [ or { and parse from there
33
+ const jsonStart = raw.search(/[[{]/);
34
+ if (jsonStart >= 0) {
35
+ const candidate = raw.slice(jsonStart);
36
+ try {
37
+ return JSON.parse(candidate);
38
+ }
39
+ catch { /* continue */ }
40
+ // Step 4: Find matching bracket and extract
41
+ const openChar = candidate[0];
42
+ const closeChar = openChar === "[" ? "]" : "}";
43
+ const lastClose = candidate.lastIndexOf(closeChar);
44
+ if (lastClose > 0) {
45
+ try {
46
+ return JSON.parse(candidate.slice(0, lastClose + 1));
47
+ }
48
+ catch { /* continue */ }
49
+ }
50
+ }
51
+ return null;
52
+ };
53
+ /**
54
+ * LLM prompt template for compaction.
55
+ */
56
+ const COMPACTION_PROMPT = `Analyze these completed tasks and generate two outputs:
57
+
58
+ Completed Tasks:
59
+ {tasks}
60
+
61
+ Generate a JSON response with two fields:
62
+
63
+ 1. "summary": A 2-4 paragraph summary capturing what was accomplished, grouped by related work. Keep under 500 words.
64
+
65
+ 2. "learnings": Bullet points of actionable learnings that would help an AI agent working on similar tasks in the future. Focus on:
66
+ - Key technical decisions and why they were made
67
+ - Gotchas or pitfalls to avoid
68
+ - Patterns that worked well
69
+ - Things that should be done differently next time
70
+
71
+ Format learnings as markdown bullet points, suitable for appending to a CLAUDE.md file.
72
+
73
+ Example response format:
74
+ {
75
+ "summary": "## Task Summary\\n\\nCompleted authentication system implementation...",
76
+ "learnings": "- JWT tokens should use RS256 for production signing\\n- Token validation middleware must run before route handlers"
77
+ }`;
78
+ /**
79
+ * Validate that a target file path does not escape the project directory
80
+ * via path traversal (e.g. "../../etc/passwd" or absolute paths outside
81
+ * the project root). Returns the resolved absolute path on success.
82
+ */
83
+ const validateProjectPath = (targetFile) => {
84
+ const projectRoot = process.cwd();
85
+ const resolved = resolve(projectRoot, targetFile);
86
+ if (!resolved.startsWith(projectRoot + sep)) {
87
+ return Effect.fail(new ValidationError({
88
+ reason: `Path traversal rejected: resolved path '${resolved}' escapes project directory '${projectRoot}'`
89
+ }));
90
+ }
91
+ return Effect.succeed(resolved);
92
+ };
93
+ /**
94
+ * CompactionService provides compaction operations for completed tasks.
95
+ *
96
+ * Design: Following DD-006 patterns for LLM integration with graceful degradation.
97
+ * When ANTHROPIC_API_KEY is not set, compact() fails gracefully while preview()
98
+ * and getSummaries() still work.
99
+ */
100
+ export class CompactionService extends Context.Tag("CompactionService")() {
101
+ }
102
+ /**
103
+ * Noop implementation - returns failures for LLM operations.
104
+ * Used for testing and when no API key is configured.
105
+ */
106
+ export const CompactionServiceNoop = Layer.effect(CompactionService, Effect.gen(function* () {
107
+ const compactionRepo = yield* CompactionRepository;
108
+ const db = yield* SqliteClient;
109
+ const findCompactableTasks = (before) => Effect.try({
110
+ try: () => {
111
+ // Find tasks that are:
112
+ // 1. Status = 'done'
113
+ // 2. completed_at < before
114
+ // 3. All children are also done (subquery check)
115
+ const beforeStr = before.toISOString();
116
+ const rows = db.prepare(`
117
+ SELECT t.*
118
+ FROM tasks t
119
+ WHERE t.status = 'done'
120
+ AND t.completed_at IS NOT NULL
121
+ AND t.completed_at < ?
122
+ AND NOT EXISTS (
123
+ SELECT 1 FROM tasks child
124
+ WHERE child.parent_id = t.id
125
+ AND child.status != 'done'
126
+ )
127
+ ORDER BY t.completed_at ASC
128
+ `).all(beforeStr);
129
+ return rows.map(rowToTask);
130
+ },
131
+ catch: (cause) => new DatabaseError({ cause })
132
+ });
133
+ return {
134
+ compact: (_options) => Effect.fail(new ExtractionUnavailableError({
135
+ reason: "Task compaction requires ANTHROPIC_API_KEY. Set it as an environment variable to enable this feature."
136
+ })),
137
+ preview: (before) => findCompactableTasks(before),
138
+ getSummaries: () => compactionRepo.findAll(),
139
+ exportLearnings: (learnings, targetFile) => Effect.gen(function* () {
140
+ const filePath = yield* validateProjectPath(targetFile);
141
+ yield* Effect.try({
142
+ try: () => {
143
+ const date = new Date().toISOString().split("T")[0];
144
+ const content = `\n\n## Agent Learnings (${date})\n\n${learnings}\n`;
145
+ if (existsSync(filePath)) {
146
+ const existing = readFileSync(filePath, "utf-8");
147
+ writeFileSync(filePath, existing + content);
148
+ }
149
+ else {
150
+ writeFileSync(filePath, `# Project Context\n${content}`);
151
+ }
152
+ },
153
+ catch: (cause) => new DatabaseError({ cause })
154
+ });
155
+ }),
156
+ isAvailable: () => Effect.succeed(false)
157
+ };
158
+ }));
159
+ /**
160
+ * Live implementation with Anthropic LLM support.
161
+ */
162
+ export const CompactionServiceLive = Layer.effect(CompactionService, Effect.gen(function* () {
163
+ const compactionRepo = yield* CompactionRepository;
164
+ const db = yield* SqliteClient;
165
+ // Read API key from environment (optional)
166
+ const apiKeyOption = yield* Config.string("ANTHROPIC_API_KEY").pipe(Effect.option);
167
+ const hasApiKey = Option.isSome(apiKeyOption) && apiKeyOption.value.trim().length > 0;
168
+ const apiKey = hasApiKey ? apiKeyOption.value : null;
169
+ // Lazy-load Anthropic client
170
+ let client = null;
171
+ const ensureClient = Effect.gen(function* () {
172
+ if (!apiKey) {
173
+ return yield* Effect.fail(new ExtractionUnavailableError({
174
+ reason: "Task compaction requires ANTHROPIC_API_KEY. Set it as an environment variable to enable this feature."
175
+ }));
176
+ }
177
+ if (client)
178
+ return client;
179
+ // Dynamic import of Anthropic SDK (optional peer dependency)
180
+ const Anthropic = yield* Effect.tryPromise({
181
+ try: async () => {
182
+ // @ts-expect-error - @anthropic-ai/sdk is an optional peer dependency
183
+ const mod = await import("@anthropic-ai/sdk");
184
+ return mod.default;
185
+ },
186
+ catch: () => new ExtractionUnavailableError({
187
+ reason: "@anthropic-ai/sdk is not installed"
188
+ })
189
+ });
190
+ client = new Anthropic({ apiKey });
191
+ return client;
192
+ });
193
+ const findCompactableTasks = (before) => Effect.try({
194
+ try: () => {
195
+ // Find tasks that are:
196
+ // 1. Status = 'done'
197
+ // 2. completed_at < before
198
+ // 3. All children are also done (subquery check)
199
+ const beforeStr = before.toISOString();
200
+ const rows = db.prepare(`
201
+ SELECT t.*
202
+ FROM tasks t
203
+ WHERE t.status = 'done'
204
+ AND t.completed_at IS NOT NULL
205
+ AND t.completed_at < ?
206
+ AND NOT EXISTS (
207
+ SELECT 1 FROM tasks child
208
+ WHERE child.parent_id = t.id
209
+ AND child.status != 'done'
210
+ )
211
+ ORDER BY t.completed_at ASC
212
+ `).all(beforeStr);
213
+ return rows.map(rowToTask);
214
+ },
215
+ catch: (cause) => new DatabaseError({ cause })
216
+ });
217
+ const generateSummary = (tasks) => Effect.gen(function* () {
218
+ const anthropic = yield* ensureClient;
219
+ // Build task list for prompt
220
+ const taskList = tasks.map(t => `- ${t.id}: ${t.title} (completed: ${t.completedAt?.toISOString().split("T")[0] ?? "unknown"})\n ${t.description || "(no description)"}`).join("\n");
221
+ const prompt = COMPACTION_PROMPT.replace("{tasks}", taskList);
222
+ const response = yield* Effect.tryPromise({
223
+ try: () => anthropic.messages.create({
224
+ model: "claude-haiku-4-20250514",
225
+ max_tokens: 2048,
226
+ messages: [{
227
+ role: "user",
228
+ content: prompt
229
+ }]
230
+ }),
231
+ catch: (e) => new ExtractionUnavailableError({
232
+ reason: `Anthropic API call failed: ${String(e)}`
233
+ })
234
+ });
235
+ // Extract text from response
236
+ const textContent = response.content.find(c => c.type === "text");
237
+ if (!textContent || !textContent.text) {
238
+ return {
239
+ summary: "No summary generated",
240
+ learnings: "- No learnings extracted"
241
+ };
242
+ }
243
+ // Parse the JSON response
244
+ const parsed = parseLlmJson(textContent.text);
245
+ if (!parsed || !parsed.summary || !parsed.learnings) {
246
+ // Fallback: treat raw response as summary/learnings
247
+ return {
248
+ summary: textContent.text.slice(0, 1000),
249
+ learnings: "- No structured learnings extracted"
250
+ };
251
+ }
252
+ return parsed;
253
+ });
254
+ const exportLearningsToFile = (learnings, targetFile) => Effect.gen(function* () {
255
+ const filePath = yield* validateProjectPath(targetFile);
256
+ yield* Effect.try({
257
+ try: () => {
258
+ const date = new Date().toISOString().split("T")[0];
259
+ const content = `\n\n## Agent Learnings (${date})\n\n${learnings}\n`;
260
+ if (existsSync(filePath)) {
261
+ const existing = readFileSync(filePath, "utf-8");
262
+ writeFileSync(filePath, existing + content);
263
+ }
264
+ else {
265
+ writeFileSync(filePath, `# Project Context\n${content}`);
266
+ }
267
+ },
268
+ catch: (cause) => new DatabaseError({ cause })
269
+ });
270
+ });
271
+ return {
272
+ compact: (options) => Effect.gen(function* () {
273
+ const tasks = yield* findCompactableTasks(options.before);
274
+ // Default to 'both' per DOCTRINE RULE 2
275
+ const outputMode = options.outputMode ?? 'both';
276
+ if (tasks.length === 0) {
277
+ return {
278
+ compactedCount: 0,
279
+ summary: "No tasks to compact",
280
+ learnings: "",
281
+ taskIds: [],
282
+ learningsExportedTo: null,
283
+ outputMode
284
+ };
285
+ }
286
+ // Generate LLM summary (outside transaction - LLM calls are slow)
287
+ const { summary, learnings } = yield* generateSummary(tasks);
288
+ const taskIds = tasks.map(t => t.id);
289
+ const outputFile = options.outputFile ?? "CLAUDE.md";
290
+ const shouldExportToMarkdown = outputMode === 'markdown' || outputMode === 'both';
291
+ const shouldStoreInDatabase = outputMode === 'database' || outputMode === 'both';
292
+ if (options.dryRun) {
293
+ // Preview mode: return what would be compacted without making changes
294
+ return {
295
+ compactedCount: tasks.length,
296
+ summary,
297
+ learnings,
298
+ taskIds,
299
+ learningsExportedTo: shouldExportToMarkdown ? outputFile : null,
300
+ outputMode
301
+ };
302
+ }
303
+ // CRITICAL: Export learnings to file FIRST, before database transaction.
304
+ // This ordering prevents a false positive where the database records
305
+ // learnings_exported_to but the file export actually failed.
306
+ // If file export fails, we fail loudly here before any DB changes.
307
+ // See task tx-b2aa12e1 and regression test in compaction.test.ts.
308
+ if (shouldExportToMarkdown) {
309
+ yield* exportLearningsToFile(learnings, outputFile);
310
+ }
311
+ // Transaction: store log (optionally with learnings) + delete tasks atomically
312
+ yield* Effect.try({
313
+ try: () => {
314
+ db.exec("BEGIN IMMEDIATE");
315
+ try {
316
+ if (shouldStoreInDatabase) {
317
+ // Insert compaction log
318
+ // When outputMode is 'both', store learnings in DB as backup
319
+ // When outputMode is 'database', learnings are stored only in DB
320
+ const now = new Date().toISOString();
321
+ db.prepare(`INSERT INTO compaction_log (compacted_at, task_count, summary, task_ids, learnings_exported_to, learnings)
322
+ VALUES (?, ?, ?, ?, ?, ?)`).run(now, tasks.length, summary, JSON.stringify(taskIds), shouldExportToMarkdown ? outputFile : null, learnings);
323
+ }
324
+ // Delete compacted tasks
325
+ for (const task of tasks) {
326
+ // First delete any dependencies involving this task
327
+ db.prepare("DELETE FROM task_dependencies WHERE blocker_id = ? OR blocked_id = ?").run(task.id, task.id);
328
+ // Then delete the task
329
+ db.prepare("DELETE FROM tasks WHERE id = ?").run(task.id);
330
+ }
331
+ db.exec("COMMIT");
332
+ }
333
+ catch (e) {
334
+ db.exec("ROLLBACK");
335
+ throw e;
336
+ }
337
+ },
338
+ catch: (cause) => new DatabaseError({ cause })
339
+ });
340
+ return {
341
+ compactedCount: tasks.length,
342
+ summary,
343
+ learnings,
344
+ taskIds,
345
+ learningsExportedTo: shouldExportToMarkdown ? outputFile : null,
346
+ outputMode
347
+ };
348
+ }),
349
+ preview: (before) => findCompactableTasks(before),
350
+ getSummaries: () => compactionRepo.findAll(),
351
+ exportLearnings: exportLearningsToFile,
352
+ isAvailable: () => Effect.succeed(hasApiKey)
353
+ };
354
+ }));
355
+ /**
356
+ * Auto-detecting layer that selects the appropriate backend based on environment.
357
+ *
358
+ * Priority:
359
+ * 1. ANTHROPIC_API_KEY set -> Use Live implementation
360
+ * 2. Not set -> Use Noop (graceful degradation)
361
+ */
362
+ export const CompactionServiceAuto = Layer.unwrapEffect(Effect.gen(function* () {
363
+ const anthropicKey = yield* Config.string("ANTHROPIC_API_KEY").pipe(Effect.option);
364
+ if (Option.isSome(anthropicKey) && anthropicKey.value.trim().length > 0) {
365
+ return CompactionServiceLive;
366
+ }
367
+ return CompactionServiceNoop;
368
+ }));
369
+ //# sourceMappingURL=compaction-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compaction-service.js","sourceRoot":"","sources":["../../src/services/compaction-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * CycleScanService — Cycle-Based Issue Discovery
3
+ *
4
+ * Orchestrates sub-agent swarms via AgentService to scan for codebase issues,
5
+ * deduplicates findings against known issues using an LLM-as-judge, and
6
+ * optionally fixes them. Repeats in rounds within each cycle until convergence.
7
+ *
8
+ * Replaces scripts/cycle-scan.ts with proper Effect service patterns.
9
+ */
10
+ import { Context, Effect, Layer } from "effect";
11
+ import type { Finding, CycleConfig, CycleResult, CycleProgressEvent } from "@jamesaphoenix/tx-types";
12
+ import { CycleScanError } from "../errors.js";
13
+ import { AgentService } from "./agent-service.js";
14
+ import { SqliteClient } from "../db.js";
15
+ declare const CycleScanService_base: Context.TagClass<CycleScanService, "CycleScanService", {
16
+ /** Run one or more scan cycles with the given configuration. */
17
+ readonly runCycles: (config: CycleConfig, onProgress?: (event: CycleProgressEvent) => void) => Effect.Effect<CycleResult[], CycleScanError>;
18
+ /** Compute loss from a set of findings using weighted severity formula. */
19
+ readonly computeLoss: (findings: readonly Finding[]) => number;
20
+ }>;
21
+ /**
22
+ * CycleScanService orchestrates cycle-based issue discovery.
23
+ */
24
+ export declare class CycleScanService extends CycleScanService_base {
25
+ }
26
+ /**
27
+ * Live implementation of CycleScanService.
28
+ * Depends on AgentService for sub-agent dispatch and SqliteClient for DB ops.
29
+ */
30
+ export declare const CycleScanServiceLive: Layer.Layer<CycleScanService, never, SqliteClient | AgentService>;
31
+ export {};
32
+ //# sourceMappingURL=cycle-scan-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cycle-scan-service.d.ts","sourceRoot":"","sources":["../../src/services/cycle-scan-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAK/C,OAAO,KAAK,EACV,OAAO,EAEP,WAAW,EACX,WAAW,EACX,kBAAkB,EACnB,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAuB,MAAM,oBAAoB,CAAA;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;;IA8LnC,gEAAgE;wBAC5C,CAClB,MAAM,EAAE,WAAW,EACnB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,KAC7C,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,cAAc,CAAC;IAEjD,2EAA2E;0BACrD,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,KAAK,MAAM;;AAblE;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,qBAYnC;CAAG;AAEN;;;GAGG;AACH,eAAO,MAAM,oBAAoB,mEAmchC,CAAA"}