@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.
- package/README.md +480 -0
- package/dist/db.d.ts +28 -14
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +102 -14
- package/dist/db.js.map +1 -1
- package/dist/errors.d.ts +178 -34
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +119 -26
- package/dist/errors.js.map +1 -1
- package/dist/id.d.ts +10 -0
- package/dist/id.d.ts.map +1 -1
- package/dist/id.js +17 -1
- package/dist/id.js.map +1 -1
- package/dist/index.d.ts +15 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +62 -8
- package/dist/index.js.map +1 -1
- package/dist/layer.d.ts +23 -14
- package/dist/layer.d.ts.map +1 -1
- package/dist/layer.js +75 -76
- package/dist/layer.js.map +1 -1
- package/dist/mappers/anchor.d.ts +15 -1
- package/dist/mappers/anchor.d.ts.map +1 -1
- package/dist/mappers/anchor.js +95 -28
- package/dist/mappers/anchor.js.map +1 -1
- package/dist/mappers/attempt.d.ts +3 -1
- package/dist/mappers/attempt.d.ts.map +1 -1
- package/dist/mappers/attempt.js +23 -9
- package/dist/mappers/attempt.js.map +1 -1
- package/dist/mappers/candidate.d.ts +3 -1
- package/dist/mappers/candidate.d.ts.map +1 -1
- package/dist/mappers/candidate.js +46 -16
- package/dist/mappers/candidate.js.map +1 -1
- package/dist/mappers/claim.d.ts +1 -1
- package/dist/mappers/claim.d.ts.map +1 -1
- package/dist/mappers/claim.js +11 -4
- package/dist/mappers/claim.js.map +1 -1
- package/dist/mappers/deduplication.d.ts +13 -1
- package/dist/mappers/deduplication.d.ts.map +1 -1
- package/dist/mappers/deduplication.js +22 -3
- package/dist/mappers/deduplication.js.map +1 -1
- package/dist/mappers/doc.d.ts +24 -0
- package/dist/mappers/doc.d.ts.map +1 -0
- package/dist/mappers/doc.js +161 -0
- package/dist/mappers/doc.js.map +1 -0
- package/dist/mappers/edge.d.ts +10 -1
- package/dist/mappers/edge.d.ts.map +1 -1
- package/dist/mappers/edge.js +74 -12
- package/dist/mappers/edge.js.map +1 -1
- package/dist/mappers/file-learning.d.ts.map +1 -1
- package/dist/mappers/file-learning.js +2 -1
- package/dist/mappers/file-learning.js.map +1 -1
- package/dist/mappers/index.d.ts +6 -7
- package/dist/mappers/index.d.ts.map +1 -1
- package/dist/mappers/index.js +10 -12
- package/dist/mappers/index.js.map +1 -1
- package/dist/mappers/learning.d.ts +9 -1
- package/dist/mappers/learning.d.ts.map +1 -1
- package/dist/mappers/learning.js +94 -14
- package/dist/mappers/learning.js.map +1 -1
- package/dist/mappers/orchestrator-state.d.ts +1 -1
- package/dist/mappers/orchestrator-state.d.ts.map +1 -1
- package/dist/mappers/orchestrator-state.js +31 -5
- package/dist/mappers/orchestrator-state.js.map +1 -1
- package/dist/mappers/parse-date.d.ts +11 -0
- package/dist/mappers/parse-date.d.ts.map +1 -0
- package/dist/mappers/parse-date.js +18 -0
- package/dist/mappers/parse-date.js.map +1 -0
- package/dist/mappers/run.d.ts +14 -4
- package/dist/mappers/run.d.ts.map +1 -1
- package/dist/mappers/run.js +49 -18
- package/dist/mappers/run.js.map +1 -1
- package/dist/mappers/task.d.ts +5 -1
- package/dist/mappers/task.d.ts.map +1 -1
- package/dist/mappers/task.js +66 -16
- package/dist/mappers/task.js.map +1 -1
- package/dist/mappers/tracked-project.d.ts +3 -1
- package/dist/mappers/tracked-project.d.ts.map +1 -1
- package/dist/mappers/tracked-project.js +23 -9
- package/dist/mappers/tracked-project.js.map +1 -1
- package/dist/mappers/worker.d.ts +1 -1
- package/dist/mappers/worker.d.ts.map +1 -1
- package/dist/mappers/worker.js +44 -6
- package/dist/mappers/worker.js.map +1 -1
- package/dist/repo/anchor-repo.d.ts +2 -2
- package/dist/repo/anchor-repo.d.ts.map +1 -1
- package/dist/repo/anchor-repo.js +46 -5
- package/dist/repo/anchor-repo.js.map +1 -1
- package/dist/repo/attempt-repo.d.ts +2 -2
- package/dist/repo/attempt-repo.d.ts.map +1 -1
- package/dist/repo/attempt-repo.js +16 -6
- package/dist/repo/attempt-repo.js.map +1 -1
- package/dist/repo/candidate-repo.d.ts.map +1 -1
- package/dist/repo/candidate-repo.js +22 -1
- package/dist/repo/candidate-repo.js.map +1 -1
- package/dist/repo/claim-repo.d.ts +46 -2
- package/dist/repo/claim-repo.d.ts.map +1 -1
- package/dist/repo/claim-repo.js +113 -6
- package/dist/repo/claim-repo.js.map +1 -1
- package/dist/repo/compaction-repo.d.ts +41 -0
- package/dist/repo/compaction-repo.d.ts.map +1 -0
- package/dist/repo/compaction-repo.js +84 -0
- package/dist/repo/compaction-repo.js.map +1 -0
- package/dist/repo/deduplication-repo.d.ts +9 -1
- package/dist/repo/deduplication-repo.d.ts.map +1 -1
- package/dist/repo/deduplication-repo.js +46 -9
- package/dist/repo/deduplication-repo.js.map +1 -1
- package/dist/repo/dep-repo.d.ts +27 -3
- package/dist/repo/dep-repo.d.ts.map +1 -1
- package/dist/repo/dep-repo.js +166 -39
- package/dist/repo/dep-repo.js.map +1 -1
- package/dist/repo/doc-repo.d.ts +59 -0
- package/dist/repo/doc-repo.d.ts.map +1 -0
- package/dist/repo/doc-repo.js +276 -0
- package/dist/repo/doc-repo.js.map +1 -0
- package/dist/repo/edge-repo.d.ts +1 -1
- package/dist/repo/edge-repo.d.ts.map +1 -1
- package/dist/repo/edge-repo.js +65 -34
- package/dist/repo/edge-repo.js.map +1 -1
- package/dist/repo/file-learning-repo.d.ts +3 -3
- package/dist/repo/file-learning-repo.d.ts.map +1 -1
- package/dist/repo/file-learning-repo.js +19 -8
- package/dist/repo/file-learning-repo.js.map +1 -1
- package/dist/repo/index.d.ts +4 -6
- package/dist/repo/index.d.ts.map +1 -1
- package/dist/repo/index.js +3 -5
- package/dist/repo/index.js.map +1 -1
- package/dist/repo/learning-repo.d.ts +10 -3
- package/dist/repo/learning-repo.d.ts.map +1 -1
- package/dist/repo/learning-repo.js +68 -11
- package/dist/repo/learning-repo.js.map +1 -1
- package/dist/repo/orchestrator-state-repo.d.ts.map +1 -1
- package/dist/repo/orchestrator-state-repo.js +8 -1
- package/dist/repo/orchestrator-state-repo.js.map +1 -1
- package/dist/repo/run-repo.d.ts +3 -3
- package/dist/repo/run-repo.d.ts.map +1 -1
- package/dist/repo/run-repo.js +40 -19
- package/dist/repo/run-repo.js.map +1 -1
- package/dist/repo/task-repo.d.ts +14 -3
- package/dist/repo/task-repo.d.ts.map +1 -1
- package/dist/repo/task-repo.js +194 -20
- package/dist/repo/task-repo.js.map +1 -1
- package/dist/repo/tracked-project-repo.d.ts.map +1 -1
- package/dist/repo/tracked-project-repo.js +15 -1
- package/dist/repo/tracked-project-repo.js.map +1 -1
- package/dist/repo/worker-repo.d.ts +3 -2
- package/dist/repo/worker-repo.d.ts.map +1 -1
- package/dist/repo/worker-repo.js +54 -8
- package/dist/repo/worker-repo.js.map +1 -1
- package/dist/schemas/sync.js +2 -2
- package/dist/schemas/sync.js.map +1 -1
- package/dist/schemas/worker.d.ts +1 -0
- package/dist/schemas/worker.d.ts.map +1 -1
- package/dist/schemas/worker.js +1 -0
- package/dist/schemas/worker.js.map +1 -1
- package/dist/services/agent-service.d.ts +57 -0
- package/dist/services/agent-service.d.ts.map +1 -0
- package/dist/services/agent-service.js +81 -0
- package/dist/services/agent-service.js.map +1 -0
- package/dist/services/anchor-service.js +1 -1
- package/dist/services/anchor-service.js.map +1 -1
- package/dist/services/anchor-verification.d.ts +8 -0
- package/dist/services/anchor-verification.d.ts.map +1 -1
- package/dist/services/anchor-verification.js +237 -37
- package/dist/services/anchor-verification.js.map +1 -1
- package/dist/services/ast-grep-service.d.ts.map +1 -1
- package/dist/services/ast-grep-service.js +93 -22
- package/dist/services/ast-grep-service.js.map +1 -1
- package/dist/services/attempt-service.d.ts.map +1 -1
- package/dist/services/attempt-service.js +1 -4
- package/dist/services/attempt-service.js.map +1 -1
- package/dist/services/auto-sync-service.d.ts +1 -1
- package/dist/services/auto-sync-service.d.ts.map +1 -1
- package/dist/services/auto-sync-service.js +18 -10
- package/dist/services/auto-sync-service.js.map +1 -1
- package/dist/services/claim-service.d.ts +8 -2
- package/dist/services/claim-service.d.ts.map +1 -1
- package/dist/services/claim-service.js +37 -23
- package/dist/services/claim-service.js.map +1 -1
- package/dist/services/compaction-service.d.ts +105 -0
- package/dist/services/compaction-service.d.ts.map +1 -0
- package/dist/services/compaction-service.js +369 -0
- package/dist/services/compaction-service.js.map +1 -0
- package/dist/services/cycle-scan-service.d.ts +32 -0
- package/dist/services/cycle-scan-service.d.ts.map +1 -0
- package/dist/services/cycle-scan-service.js +542 -0
- package/dist/services/cycle-scan-service.js.map +1 -0
- package/dist/services/daemon-service.d.ts +40 -2
- package/dist/services/daemon-service.d.ts.map +1 -1
- package/dist/services/daemon-service.js +199 -52
- package/dist/services/daemon-service.js.map +1 -1
- package/dist/services/deduplication-service.d.ts +8 -4
- package/dist/services/deduplication-service.d.ts.map +1 -1
- package/dist/services/deduplication-service.js +79 -25
- package/dist/services/deduplication-service.js.map +1 -1
- package/dist/services/dep-service.d.ts +2 -2
- package/dist/services/dep-service.d.ts.map +1 -1
- package/dist/services/dep-service.js +9 -5
- package/dist/services/dep-service.js.map +1 -1
- package/dist/services/diversifier-service.d.ts +2 -1
- package/dist/services/diversifier-service.d.ts.map +1 -1
- package/dist/services/diversifier-service.js +37 -43
- package/dist/services/diversifier-service.js.map +1 -1
- package/dist/services/doc-service.d.ts +49 -0
- package/dist/services/doc-service.d.ts.map +1 -0
- package/dist/services/doc-service.js +605 -0
- package/dist/services/doc-service.js.map +1 -0
- package/dist/services/edge-service.js +2 -2
- package/dist/services/edge-service.js.map +1 -1
- package/dist/services/embedding-service.d.ts +66 -2
- package/dist/services/embedding-service.d.ts.map +1 -1
- package/dist/services/embedding-service.js +138 -24
- package/dist/services/embedding-service.js.map +1 -1
- package/dist/services/file-learning-service.d.ts.map +1 -1
- package/dist/services/file-learning-service.js +8 -7
- package/dist/services/file-learning-service.js.map +1 -1
- package/dist/services/file-watcher-service.d.ts.map +1 -1
- package/dist/services/file-watcher-service.js +58 -11
- package/dist/services/file-watcher-service.js.map +1 -1
- package/dist/services/graph-expansion.d.ts +3 -0
- package/dist/services/graph-expansion.d.ts.map +1 -1
- package/dist/services/graph-expansion.js +28 -7
- package/dist/services/graph-expansion.js.map +1 -1
- package/dist/services/hierarchy-service.d.ts +1 -1
- package/dist/services/hierarchy-service.d.ts.map +1 -1
- package/dist/services/hierarchy-service.js +50 -32
- package/dist/services/hierarchy-service.js.map +1 -1
- package/dist/services/index.d.ts +13 -15
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +13 -15
- package/dist/services/index.js.map +1 -1
- package/dist/services/learning-service.d.ts +4 -4
- package/dist/services/learning-service.d.ts.map +1 -1
- package/dist/services/learning-service.js +75 -42
- package/dist/services/learning-service.js.map +1 -1
- package/dist/services/llm-service.d.ts +62 -0
- package/dist/services/llm-service.d.ts.map +1 -0
- package/dist/services/llm-service.js +172 -0
- package/dist/services/llm-service.js.map +1 -0
- package/dist/services/migration-service.d.ts +1 -1
- package/dist/services/migration-service.d.ts.map +1 -1
- package/dist/services/migration-service.js +18 -7
- package/dist/services/migration-service.js.map +1 -1
- package/dist/services/orchestrator-service.d.ts +4 -3
- package/dist/services/orchestrator-service.d.ts.map +1 -1
- package/dist/services/orchestrator-service.js +67 -29
- package/dist/services/orchestrator-service.js.map +1 -1
- package/dist/services/promotion-service.d.ts +1 -1
- package/dist/services/promotion-service.js +1 -1
- package/dist/services/promotion-service.js.map +1 -1
- package/dist/services/query-expansion-service.d.ts +30 -9
- package/dist/services/query-expansion-service.d.ts.map +1 -1
- package/dist/services/query-expansion-service.js +54 -63
- package/dist/services/query-expansion-service.js.map +1 -1
- package/dist/services/ready-service.d.ts +21 -1
- package/dist/services/ready-service.d.ts.map +1 -1
- package/dist/services/ready-service.js +44 -21
- package/dist/services/ready-service.js.map +1 -1
- package/dist/services/retriever-service.d.ts +10 -10
- package/dist/services/retriever-service.d.ts.map +1 -1
- package/dist/services/retriever-service.js +53 -161
- package/dist/services/retriever-service.js.map +1 -1
- package/dist/services/swarm-verification.d.ts +2 -2
- package/dist/services/swarm-verification.d.ts.map +1 -1
- package/dist/services/swarm-verification.js +12 -6
- package/dist/services/swarm-verification.js.map +1 -1
- package/dist/services/sync-service.d.ts +17 -4
- package/dist/services/sync-service.d.ts.map +1 -1
- package/dist/services/sync-service.js +378 -114
- package/dist/services/sync-service.js.map +1 -1
- package/dist/services/task-service.d.ts +6 -4
- package/dist/services/task-service.d.ts.map +1 -1
- package/dist/services/task-service.js +162 -33
- package/dist/services/task-service.js.map +1 -1
- package/dist/services/tracing-service.d.ts +55 -0
- package/dist/services/tracing-service.d.ts.map +1 -0
- package/dist/services/tracing-service.js +99 -0
- package/dist/services/tracing-service.js.map +1 -0
- package/dist/services/transcript-adapter.d.ts +99 -0
- package/dist/services/transcript-adapter.d.ts.map +1 -0
- package/dist/services/transcript-adapter.js +283 -0
- package/dist/services/transcript-adapter.js.map +1 -0
- package/dist/services/validation-service.d.ts +85 -0
- package/dist/services/validation-service.d.ts.map +1 -0
- package/dist/services/validation-service.js +289 -0
- package/dist/services/validation-service.js.map +1 -0
- package/dist/services/worker-process.d.ts +23 -4
- package/dist/services/worker-process.d.ts.map +1 -1
- package/dist/services/worker-process.js +159 -70
- package/dist/services/worker-process.js.map +1 -1
- package/dist/services/worker-service.d.ts.map +1 -1
- package/dist/services/worker-service.js +7 -12
- package/dist/services/worker-service.js.map +1 -1
- package/dist/sync/claude-task-writer.d.ts +49 -0
- package/dist/sync/claude-task-writer.d.ts.map +1 -0
- package/dist/sync/claude-task-writer.js +135 -0
- package/dist/sync/claude-task-writer.js.map +1 -0
- package/dist/utils/doc-hash.d.ts +10 -0
- package/dist/utils/doc-hash.d.ts.map +1 -0
- package/dist/utils/doc-hash.js +14 -0
- package/dist/utils/doc-hash.js.map +1 -0
- package/dist/utils/doc-renderer.d.ts +44 -0
- package/dist/utils/doc-renderer.d.ts.map +1 -0
- package/dist/utils/doc-renderer.js +202 -0
- package/dist/utils/doc-renderer.js.map +1 -0
- package/dist/utils/math.d.ts +5 -1
- package/dist/utils/math.d.ts.map +1 -1
- package/dist/utils/math.js +12 -4
- package/dist/utils/math.js.map +1 -1
- package/dist/utils/sql.d.ts +9 -0
- package/dist/utils/sql.d.ts.map +1 -0
- package/dist/utils/sql.js +9 -0
- package/dist/utils/sql.js.map +1 -0
- package/dist/utils/toml-config.d.ts +22 -0
- package/dist/utils/toml-config.d.ts.map +1 -0
- package/dist/utils/toml-config.js +75 -0
- package/dist/utils/toml-config.js.map +1 -0
- package/dist/worker/hooks.d.ts +102 -0
- package/dist/worker/hooks.d.ts.map +1 -0
- package/dist/worker/hooks.js +11 -0
- package/dist/worker/hooks.js.map +1 -0
- package/dist/worker/index.d.ts +9 -0
- package/dist/worker/index.d.ts.map +1 -0
- package/dist/worker/index.js +8 -0
- package/dist/worker/index.js.map +1 -0
- package/dist/worker/run-worker.d.ts +33 -0
- package/dist/worker/run-worker.d.ts.map +1 -0
- package/dist/worker/run-worker.js +265 -0
- package/dist/worker/run-worker.js.map +1 -0
- 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"}
|