@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,542 @@
|
|
|
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 { appendFileSync, mkdirSync } from "node:fs";
|
|
12
|
+
import { resolve } from "node:path";
|
|
13
|
+
import { randomBytes } from "node:crypto";
|
|
14
|
+
import { readFileSync, existsSync, statSync } from "node:fs";
|
|
15
|
+
import { LOSS_WEIGHTS } from "@jamesaphoenix/tx-types";
|
|
16
|
+
import { CycleScanError } from "../errors.js";
|
|
17
|
+
import { AgentService } from "./agent-service.js";
|
|
18
|
+
import { SqliteClient } from "../db.js";
|
|
19
|
+
// =============================================================================
|
|
20
|
+
// JSON Schemas for Structured Output
|
|
21
|
+
// =============================================================================
|
|
22
|
+
const FINDINGS_SCHEMA = {
|
|
23
|
+
type: "object",
|
|
24
|
+
properties: {
|
|
25
|
+
findings: {
|
|
26
|
+
type: "array",
|
|
27
|
+
items: {
|
|
28
|
+
type: "object",
|
|
29
|
+
properties: {
|
|
30
|
+
title: { type: "string", description: "Short, descriptive issue title" },
|
|
31
|
+
description: { type: "string", description: "Detailed explanation of the issue and why it matters" },
|
|
32
|
+
severity: { type: "string", enum: ["high", "medium", "low"] },
|
|
33
|
+
issueType: { type: "string", description: "Category: bug, anti-pattern, security, performance, testing, ddd, etc." },
|
|
34
|
+
file: { type: "string", description: "File path relative to project root" },
|
|
35
|
+
line: { type: "number", description: "Approximate line number" },
|
|
36
|
+
},
|
|
37
|
+
required: ["title", "description", "severity", "issueType", "file", "line"],
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
required: ["findings"],
|
|
42
|
+
};
|
|
43
|
+
const DEDUP_SCHEMA = {
|
|
44
|
+
type: "object",
|
|
45
|
+
properties: {
|
|
46
|
+
newIssues: {
|
|
47
|
+
type: "array",
|
|
48
|
+
items: {
|
|
49
|
+
type: "object",
|
|
50
|
+
properties: {
|
|
51
|
+
title: { type: "string" },
|
|
52
|
+
description: { type: "string" },
|
|
53
|
+
severity: { type: "string", enum: ["high", "medium", "low"] },
|
|
54
|
+
issueType: { type: "string" },
|
|
55
|
+
file: { type: "string" },
|
|
56
|
+
line: { type: "number" },
|
|
57
|
+
},
|
|
58
|
+
required: ["title", "description", "severity", "issueType", "file", "line"],
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
duplicates: {
|
|
62
|
+
type: "array",
|
|
63
|
+
items: {
|
|
64
|
+
type: "object",
|
|
65
|
+
properties: {
|
|
66
|
+
findingIdx: { type: "number", description: "Index into the findings array" },
|
|
67
|
+
existingIssueId: { type: "string", description: "Task ID of the existing issue this duplicates" },
|
|
68
|
+
reason: { type: "string", description: "Why this is considered a duplicate" },
|
|
69
|
+
},
|
|
70
|
+
required: ["findingIdx", "existingIssueId", "reason"],
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
required: ["newIssues", "duplicates"],
|
|
75
|
+
};
|
|
76
|
+
// =============================================================================
|
|
77
|
+
// Helpers
|
|
78
|
+
// =============================================================================
|
|
79
|
+
function composeScanPrompt(task, scan) {
|
|
80
|
+
return `## Context
|
|
81
|
+
${task}
|
|
82
|
+
|
|
83
|
+
## Your Mission
|
|
84
|
+
${scan}
|
|
85
|
+
|
|
86
|
+
## Instructions
|
|
87
|
+
Explore the codebase thoroughly using Read, Glob, and Grep.
|
|
88
|
+
Look for real issues — not style nits. Focus on bugs, logic errors,
|
|
89
|
+
missing error handling, security vulnerabilities, and structural problems.
|
|
90
|
+
|
|
91
|
+
Return your findings as structured JSON. Only report issues you are
|
|
92
|
+
confident about after reading the actual code.`;
|
|
93
|
+
}
|
|
94
|
+
function composeDedupPrompt(findings, existingIssues) {
|
|
95
|
+
return `## Task
|
|
96
|
+
Compare these new findings against known issues. Return only genuinely new issues.
|
|
97
|
+
|
|
98
|
+
## New Findings (${findings.length} total)
|
|
99
|
+
${JSON.stringify(findings, null, 2)}
|
|
100
|
+
|
|
101
|
+
## Known Issues (${existingIssues.length} total)
|
|
102
|
+
${JSON.stringify(existingIssues, null, 2)}
|
|
103
|
+
|
|
104
|
+
## Instructions
|
|
105
|
+
For each new finding, check if it describes the same problem as any known issue.
|
|
106
|
+
Use semantic understanding — the same issue might be worded differently or reference
|
|
107
|
+
a slightly different line number in the same file. Be conservative: if in doubt,
|
|
108
|
+
treat it as new rather than duplicate.
|
|
109
|
+
|
|
110
|
+
Return your analysis as structured JSON.`;
|
|
111
|
+
}
|
|
112
|
+
function composeFixPrompt(issues) {
|
|
113
|
+
const issuesSummary = issues
|
|
114
|
+
.map((i, idx) => `${idx + 1}. [${i.severity.toUpperCase()}] ${i.title} (${i.file}:${i.line})\n ${i.description}`)
|
|
115
|
+
.join("\n\n");
|
|
116
|
+
return `## Task
|
|
117
|
+
Fix these ${issues.length} issues found in the codebase:
|
|
118
|
+
|
|
119
|
+
${issuesSummary}
|
|
120
|
+
|
|
121
|
+
## Instructions
|
|
122
|
+
Work through the issues above. For each one:
|
|
123
|
+
1. Read the relevant file to understand context
|
|
124
|
+
2. Make the minimal fix needed
|
|
125
|
+
3. Move to the next issue
|
|
126
|
+
|
|
127
|
+
Focus on correctness. Skip issues you're not confident about fixing safely.`;
|
|
128
|
+
}
|
|
129
|
+
function resolvePrompt(value) {
|
|
130
|
+
const filePath = resolve(value);
|
|
131
|
+
if (existsSync(filePath) && statSync(filePath).isFile()) {
|
|
132
|
+
return readFileSync(filePath, "utf-8").trim();
|
|
133
|
+
}
|
|
134
|
+
return value;
|
|
135
|
+
}
|
|
136
|
+
function generateId(prefix) {
|
|
137
|
+
return `${prefix}-${randomBytes(4).toString("hex")}`;
|
|
138
|
+
}
|
|
139
|
+
// =============================================================================
|
|
140
|
+
// Transcript Logging
|
|
141
|
+
// =============================================================================
|
|
142
|
+
const LOGS_DIR = resolve(".tx", "logs");
|
|
143
|
+
function ensureLogsDir() {
|
|
144
|
+
mkdirSync(LOGS_DIR, { recursive: true });
|
|
145
|
+
}
|
|
146
|
+
function logPath(runId) {
|
|
147
|
+
return resolve(LOGS_DIR, `${runId}.jsonl`);
|
|
148
|
+
}
|
|
149
|
+
function writeTranscriptLine(runId, message) {
|
|
150
|
+
try {
|
|
151
|
+
const line = JSON.stringify(message) + "\n";
|
|
152
|
+
appendFileSync(logPath(runId), line);
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
// Don't let transcript writing break the scan
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function writeOrchestratorLog(runId, text) {
|
|
159
|
+
writeTranscriptLine(runId, {
|
|
160
|
+
type: "assistant",
|
|
161
|
+
message: {
|
|
162
|
+
role: "assistant",
|
|
163
|
+
content: [{ type: "text", text }],
|
|
164
|
+
},
|
|
165
|
+
timestamp: new Date().toISOString(),
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
// =============================================================================
|
|
169
|
+
// Service Definition
|
|
170
|
+
// =============================================================================
|
|
171
|
+
/**
|
|
172
|
+
* CycleScanService orchestrates cycle-based issue discovery.
|
|
173
|
+
*/
|
|
174
|
+
export class CycleScanService extends Context.Tag("CycleScanService")() {
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Live implementation of CycleScanService.
|
|
178
|
+
* Depends on AgentService for sub-agent dispatch and SqliteClient for DB ops.
|
|
179
|
+
*/
|
|
180
|
+
export const CycleScanServiceLive = Layer.effect(CycleScanService, Effect.gen(function* () {
|
|
181
|
+
const agentService = yield* AgentService;
|
|
182
|
+
const sqliteClient = yield* SqliteClient;
|
|
183
|
+
const computeLoss = (findings) => {
|
|
184
|
+
let loss = 0;
|
|
185
|
+
for (const f of findings) {
|
|
186
|
+
loss += LOSS_WEIGHTS[f.severity] ?? 1;
|
|
187
|
+
}
|
|
188
|
+
return loss;
|
|
189
|
+
};
|
|
190
|
+
const countBySeverity = (findings) => {
|
|
191
|
+
let high = 0, medium = 0, low = 0;
|
|
192
|
+
for (const f of findings) {
|
|
193
|
+
if (f.severity === "high")
|
|
194
|
+
high++;
|
|
195
|
+
else if (f.severity === "medium")
|
|
196
|
+
medium++;
|
|
197
|
+
else
|
|
198
|
+
low++;
|
|
199
|
+
}
|
|
200
|
+
return { high, medium, low };
|
|
201
|
+
};
|
|
202
|
+
// DB helpers
|
|
203
|
+
// sqliteClient IS the SqliteDatabase (not .db property)
|
|
204
|
+
const db = sqliteClient;
|
|
205
|
+
const dbCreateRun = (agent) => {
|
|
206
|
+
const id = generateId("run");
|
|
207
|
+
const now = new Date().toISOString();
|
|
208
|
+
const transcriptPath = logPath(id);
|
|
209
|
+
db.prepare(`INSERT INTO runs (id, agent, started_at, status, metadata, transcript_path)
|
|
210
|
+
VALUES (?, ?, ?, 'running', '{}', ?)`).run(id, agent, now, transcriptPath);
|
|
211
|
+
return id;
|
|
212
|
+
};
|
|
213
|
+
const dbUpdateRun = (runId, updates) => {
|
|
214
|
+
const sets = [];
|
|
215
|
+
const params = [];
|
|
216
|
+
if (updates.status) {
|
|
217
|
+
sets.push("status = ?");
|
|
218
|
+
params.push(updates.status);
|
|
219
|
+
if (updates.status === "completed" || updates.status === "failed") {
|
|
220
|
+
sets.push("ended_at = datetime('now')");
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (updates.summary) {
|
|
224
|
+
sets.push("summary = ?");
|
|
225
|
+
params.push(updates.summary);
|
|
226
|
+
}
|
|
227
|
+
if (updates.errorMessage) {
|
|
228
|
+
sets.push("error_message = ?");
|
|
229
|
+
params.push(updates.errorMessage);
|
|
230
|
+
}
|
|
231
|
+
if (sets.length > 0) {
|
|
232
|
+
params.push(runId);
|
|
233
|
+
db.prepare(`UPDATE runs SET ${sets.join(", ")} WHERE id = ?`).run(...params);
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
const dbUpdateRunMetadata = (runId, metadata) => {
|
|
237
|
+
db.prepare(`UPDATE runs SET metadata = ? WHERE id = ?`).run(JSON.stringify(metadata), runId);
|
|
238
|
+
};
|
|
239
|
+
const dbCreateTask = (data) => {
|
|
240
|
+
const id = generateId("tx");
|
|
241
|
+
const now = new Date().toISOString();
|
|
242
|
+
db.prepare(`INSERT INTO tasks (id, title, description, status, parent_id, score, created_at, updated_at, completed_at, metadata)
|
|
243
|
+
VALUES (?, ?, ?, 'backlog', NULL, ?, ?, ?, NULL, ?)`).run(id, data.title, data.description, data.score, now, now, JSON.stringify(data.metadata));
|
|
244
|
+
return id;
|
|
245
|
+
};
|
|
246
|
+
const emitMetric = (runId, metricName, metadata) => {
|
|
247
|
+
db.prepare(`INSERT INTO events (timestamp, event_type, run_id, content, metadata)
|
|
248
|
+
VALUES (datetime('now'), 'metric', ?, ?, ?)`).run(runId, metricName, JSON.stringify(metadata));
|
|
249
|
+
};
|
|
250
|
+
// Agent dispatch helpers
|
|
251
|
+
const runScanAgent = (task, scan, agentModel, runId) => Effect.gen(function* () {
|
|
252
|
+
const prompt = composeScanPrompt(task, scan);
|
|
253
|
+
const config = {
|
|
254
|
+
prompt,
|
|
255
|
+
options: {
|
|
256
|
+
tools: ["Read", "Glob", "Grep"],
|
|
257
|
+
permissionMode: "bypassPermissions",
|
|
258
|
+
allowDangerouslySkipPermissions: true,
|
|
259
|
+
model: agentModel,
|
|
260
|
+
maxTurns: 20,
|
|
261
|
+
persistSession: false,
|
|
262
|
+
outputFormat: { type: "json_schema", schema: FINDINGS_SCHEMA },
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
const result = yield* agentService.run(config, (msg) => {
|
|
266
|
+
writeTranscriptLine(runId, { ...msg, timestamp: new Date().toISOString() });
|
|
267
|
+
}).pipe(Effect.mapError((e) => new CycleScanError({ phase: "scan", reason: e.reason, cause: e })));
|
|
268
|
+
// Try structured output first, then parse text
|
|
269
|
+
const output = result.structuredOutput;
|
|
270
|
+
if (output?.findings) {
|
|
271
|
+
return output.findings;
|
|
272
|
+
}
|
|
273
|
+
try {
|
|
274
|
+
const parsed = JSON.parse(result.text);
|
|
275
|
+
return (parsed.findings ?? []);
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
return [];
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
const runDedupAgent = (findings, issuesMap, agentModel, runId) => Effect.gen(function* () {
|
|
282
|
+
if (issuesMap.size === 0) {
|
|
283
|
+
return { newIssues: findings, duplicates: [] };
|
|
284
|
+
}
|
|
285
|
+
if (findings.length === 0) {
|
|
286
|
+
return { newIssues: [], duplicates: [] };
|
|
287
|
+
}
|
|
288
|
+
const existingIssues = Array.from(issuesMap.entries()).map(([id, issue]) => ({
|
|
289
|
+
id,
|
|
290
|
+
title: issue.title,
|
|
291
|
+
description: issue.description,
|
|
292
|
+
severity: issue.severity,
|
|
293
|
+
file: issue.file,
|
|
294
|
+
line: issue.line,
|
|
295
|
+
}));
|
|
296
|
+
const prompt = composeDedupPrompt(findings, existingIssues);
|
|
297
|
+
const config = {
|
|
298
|
+
prompt,
|
|
299
|
+
options: {
|
|
300
|
+
tools: [],
|
|
301
|
+
model: agentModel,
|
|
302
|
+
maxTurns: 1,
|
|
303
|
+
persistSession: false,
|
|
304
|
+
outputFormat: { type: "json_schema", schema: DEDUP_SCHEMA },
|
|
305
|
+
},
|
|
306
|
+
};
|
|
307
|
+
const result = yield* agentService.run(config, (msg) => {
|
|
308
|
+
writeTranscriptLine(runId, { ...msg, timestamp: new Date().toISOString() });
|
|
309
|
+
}).pipe(Effect.mapError((e) => new CycleScanError({ phase: "dedup", reason: e.reason, cause: e })));
|
|
310
|
+
const output = result.structuredOutput;
|
|
311
|
+
if (output?.newIssues) {
|
|
312
|
+
return output;
|
|
313
|
+
}
|
|
314
|
+
try {
|
|
315
|
+
return JSON.parse(result.text);
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
return { newIssues: findings, duplicates: [] };
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
const runFixAgent = (issues, agentModel, runId) => Effect.gen(function* () {
|
|
322
|
+
const prompt = composeFixPrompt(issues);
|
|
323
|
+
const config = {
|
|
324
|
+
prompt,
|
|
325
|
+
options: {
|
|
326
|
+
tools: ["Read", "Edit", "Write", "Bash", "Glob", "Grep"],
|
|
327
|
+
permissionMode: "acceptEdits",
|
|
328
|
+
model: agentModel,
|
|
329
|
+
maxTurns: 50,
|
|
330
|
+
persistSession: false,
|
|
331
|
+
},
|
|
332
|
+
};
|
|
333
|
+
yield* agentService.run(config, (msg) => {
|
|
334
|
+
writeTranscriptLine(runId, { ...msg, timestamp: new Date().toISOString() });
|
|
335
|
+
}).pipe(Effect.mapError((e) => new CycleScanError({ phase: "fix", reason: e.reason, cause: e })));
|
|
336
|
+
});
|
|
337
|
+
return {
|
|
338
|
+
computeLoss,
|
|
339
|
+
runCycles: (config, onProgress) => Effect.gen(function* () {
|
|
340
|
+
ensureLogsDir();
|
|
341
|
+
const taskPrompt = resolvePrompt(config.taskPrompt);
|
|
342
|
+
const scanPrompt = config.scanPrompt
|
|
343
|
+
? resolvePrompt(config.scanPrompt)
|
|
344
|
+
: "Find bugs, anti-patterns, missing error handling, security vulnerabilities, and untested code paths.";
|
|
345
|
+
const cycleCount = config.cycles ?? 1;
|
|
346
|
+
const maxRounds = config.maxRounds ?? 10;
|
|
347
|
+
const agentCount = config.agents ?? 3;
|
|
348
|
+
const model = config.model ?? "claude-opus-4-6";
|
|
349
|
+
const scanOnly = config.scanOnly ?? false;
|
|
350
|
+
const dryRun = config.dryRun ?? false;
|
|
351
|
+
const doFix = (config.fix ?? false) && !scanOnly && !dryRun;
|
|
352
|
+
const effectiveMaxRounds = (scanOnly || (!doFix && !dryRun)) ? 1 : maxRounds;
|
|
353
|
+
const baseScore = config.score ?? 500;
|
|
354
|
+
const cycleName = config.name ?? taskPrompt.slice(0, 60).replace(/\n/g, " ");
|
|
355
|
+
const cycleDescription = config.description ?? scanPrompt.slice(0, 200).replace(/\n/g, " ");
|
|
356
|
+
const results = [];
|
|
357
|
+
for (let cycle = 1; cycle <= cycleCount; cycle++) {
|
|
358
|
+
onProgress?.({ type: "cycle_start", cycle, totalCycles: cycleCount, name: cycleName });
|
|
359
|
+
// Create cycle group run
|
|
360
|
+
const cycleRunId = dbCreateRun("cycle-scanner");
|
|
361
|
+
dbUpdateRunMetadata(cycleRunId, { type: "cycle", cycle, name: cycleName, description: cycleDescription });
|
|
362
|
+
writeOrchestratorLog(cycleRunId, `Starting cycle ${cycle}/${cycleCount}: "${cycleName}" with ${agentCount} agents, model: ${model}`);
|
|
363
|
+
// Load existing issues for this cycle
|
|
364
|
+
const issuesMap = new Map();
|
|
365
|
+
const existingRows = db
|
|
366
|
+
.prepare(`SELECT id, title, description, metadata FROM tasks
|
|
367
|
+
WHERE json_extract(metadata, '$.foundByScan') = 1
|
|
368
|
+
AND json_extract(metadata, '$.cycleId') = ?`)
|
|
369
|
+
.all(cycleRunId);
|
|
370
|
+
for (const row of existingRows) {
|
|
371
|
+
const meta = JSON.parse(row.metadata || "{}");
|
|
372
|
+
issuesMap.set(row.id, {
|
|
373
|
+
id: row.id,
|
|
374
|
+
title: row.title,
|
|
375
|
+
description: row.description,
|
|
376
|
+
severity: meta.severity ?? "low",
|
|
377
|
+
file: meta.file ?? "",
|
|
378
|
+
line: meta.line ?? 0,
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
let totalNewIssues = 0;
|
|
382
|
+
let finalLoss = 0;
|
|
383
|
+
let converged = false;
|
|
384
|
+
let roundCount = 0;
|
|
385
|
+
for (let round = 1; round <= effectiveMaxRounds; round++) {
|
|
386
|
+
roundCount = round;
|
|
387
|
+
// SCAN PHASE — N agents in parallel
|
|
388
|
+
writeOrchestratorLog(cycleRunId, `Round ${round}: Dispatching ${agentCount} scan agents...`);
|
|
389
|
+
const scanStart = Date.now();
|
|
390
|
+
const scanEffects = Array.from({ length: agentCount }, (_, i) => Effect.gen(function* () {
|
|
391
|
+
const scanRunId = dbCreateRun(`scan-agent-${i + 1}`);
|
|
392
|
+
dbUpdateRunMetadata(scanRunId, { type: "scan", cycle, round, cycleRunId });
|
|
393
|
+
const findings = yield* runScanAgent(taskPrompt, scanPrompt, model, scanRunId).pipe(Effect.tap(() => Effect.sync(() => dbUpdateRun(scanRunId, { status: "completed" }))), Effect.tapError(() => Effect.sync(() => dbUpdateRun(scanRunId, { status: "failed" }))), Effect.catchAll(() => Effect.succeed([])));
|
|
394
|
+
return findings;
|
|
395
|
+
}));
|
|
396
|
+
const scanResults = yield* Effect.all(scanEffects, { concurrency: agentCount });
|
|
397
|
+
const allFindings = scanResults.flat();
|
|
398
|
+
const scanDuration = Date.now() - scanStart;
|
|
399
|
+
writeOrchestratorLog(cycleRunId, `Round ${round}: Scan complete — ${allFindings.length} findings in ${(scanDuration / 1000).toFixed(1)}s`);
|
|
400
|
+
onProgress?.({ type: "scan_complete", cycle, round, findings: allFindings.length, durationMs: scanDuration });
|
|
401
|
+
if (allFindings.length === 0) {
|
|
402
|
+
writeOrchestratorLog(cycleRunId, `Round ${round}: No findings — converged!`);
|
|
403
|
+
emitMetric(cycleRunId, "cycle.round.loss", {
|
|
404
|
+
metric: "cycle.round.loss",
|
|
405
|
+
cycleId: cycleRunId,
|
|
406
|
+
cycle, round, loss: 0,
|
|
407
|
+
newIssues: 0, existingIssues: issuesMap.size, duplicates: 0,
|
|
408
|
+
high: 0, medium: 0, low: 0,
|
|
409
|
+
});
|
|
410
|
+
onProgress?.({ type: "converged", cycle, round });
|
|
411
|
+
converged = true;
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
// DEDUP PHASE
|
|
415
|
+
const dedupRunId = dbCreateRun("dedup-agent");
|
|
416
|
+
dbUpdateRunMetadata(dedupRunId, { type: "dedup", cycle, round, cycleRunId });
|
|
417
|
+
const dedupResult = yield* runDedupAgent(allFindings, issuesMap, model, dedupRunId).pipe(Effect.tap(() => Effect.sync(() => dbUpdateRun(dedupRunId, { status: "completed" }))), Effect.tapError(() => Effect.sync(() => dbUpdateRun(dedupRunId, { status: "failed" }))), Effect.catchAll(() => Effect.succeed({ newIssues: allFindings, duplicates: [] })));
|
|
418
|
+
writeOrchestratorLog(cycleRunId, `Round ${round}: Dedup complete — ${dedupResult.newIssues.length} new, ${dedupResult.duplicates.length} duplicates`);
|
|
419
|
+
onProgress?.({ type: "dedup_complete", cycle, round, newIssues: dedupResult.newIssues.length, duplicates: dedupResult.duplicates.length });
|
|
420
|
+
// CREATE TASKS for new issues
|
|
421
|
+
if (!dryRun && dedupResult.newIssues.length > 0) {
|
|
422
|
+
for (const issue of dedupResult.newIssues) {
|
|
423
|
+
const taskId = dbCreateTask({
|
|
424
|
+
title: `${issue.severity.toUpperCase()}: ${issue.title}`,
|
|
425
|
+
description: issue.description,
|
|
426
|
+
score: baseScore,
|
|
427
|
+
metadata: {
|
|
428
|
+
foundByScan: true,
|
|
429
|
+
cycleId: cycleRunId,
|
|
430
|
+
cycle, round,
|
|
431
|
+
severity: issue.severity,
|
|
432
|
+
issueType: issue.issueType,
|
|
433
|
+
file: issue.file,
|
|
434
|
+
line: issue.line,
|
|
435
|
+
},
|
|
436
|
+
});
|
|
437
|
+
issuesMap.set(taskId, {
|
|
438
|
+
id: taskId,
|
|
439
|
+
title: issue.title,
|
|
440
|
+
description: issue.description,
|
|
441
|
+
severity: issue.severity,
|
|
442
|
+
file: issue.file,
|
|
443
|
+
line: issue.line,
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
else if (dryRun && dedupResult.newIssues.length > 0) {
|
|
448
|
+
// Still add to in-memory map for dedup in subsequent rounds
|
|
449
|
+
for (const issue of dedupResult.newIssues) {
|
|
450
|
+
const fakeId = `dry-${cycle}-${round}-${issuesMap.size}`;
|
|
451
|
+
issuesMap.set(fakeId, {
|
|
452
|
+
id: fakeId,
|
|
453
|
+
title: issue.title,
|
|
454
|
+
description: issue.description,
|
|
455
|
+
severity: issue.severity,
|
|
456
|
+
file: issue.file,
|
|
457
|
+
line: issue.line,
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
totalNewIssues += dedupResult.newIssues.length;
|
|
462
|
+
// COMPUTE ROUND LOSS
|
|
463
|
+
const { high, medium, low } = countBySeverity(dedupResult.newIssues);
|
|
464
|
+
const loss = computeLoss(dedupResult.newIssues);
|
|
465
|
+
finalLoss = loss;
|
|
466
|
+
writeOrchestratorLog(cycleRunId, `Round ${round}: Loss = ${loss} (${high}H x3 + ${medium}M x2 + ${low}L x1)`);
|
|
467
|
+
onProgress?.({ type: "round_loss", cycle, round, loss, high, medium, low });
|
|
468
|
+
// FIX PHASE
|
|
469
|
+
if (doFix && dedupResult.newIssues.length > 0) {
|
|
470
|
+
const fixRunId = dbCreateRun("fix-agent");
|
|
471
|
+
dbUpdateRunMetadata(fixRunId, { type: "fix", cycle, round, cycleRunId });
|
|
472
|
+
yield* runFixAgent(dedupResult.newIssues, model, fixRunId).pipe(Effect.tap(() => Effect.sync(() => dbUpdateRun(fixRunId, { status: "completed" }))), Effect.tapError(() => Effect.sync(() => dbUpdateRun(fixRunId, { status: "failed" }))), Effect.catchAll(() => Effect.void));
|
|
473
|
+
}
|
|
474
|
+
// EMIT ROUND METRICS
|
|
475
|
+
emitMetric(cycleRunId, "cycle.round.loss", {
|
|
476
|
+
metric: "cycle.round.loss",
|
|
477
|
+
cycleId: cycleRunId,
|
|
478
|
+
cycle, round, loss,
|
|
479
|
+
newIssues: dedupResult.newIssues.length,
|
|
480
|
+
existingIssues: issuesMap.size,
|
|
481
|
+
duplicates: dedupResult.duplicates.length,
|
|
482
|
+
high, medium, low,
|
|
483
|
+
});
|
|
484
|
+
// CHECK CONVERGENCE
|
|
485
|
+
if (dedupResult.newIssues.length === 0) {
|
|
486
|
+
converged = true;
|
|
487
|
+
break;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
// EMIT CYCLE-LEVEL METRIC
|
|
491
|
+
emitMetric(cycleRunId, "cycle.complete", {
|
|
492
|
+
metric: "cycle.complete",
|
|
493
|
+
cycleId: cycleRunId,
|
|
494
|
+
cycle,
|
|
495
|
+
name: cycleName,
|
|
496
|
+
description: cycleDescription,
|
|
497
|
+
rounds: roundCount,
|
|
498
|
+
totalNewIssues,
|
|
499
|
+
existingIssues: issuesMap.size,
|
|
500
|
+
finalLoss,
|
|
501
|
+
converged,
|
|
502
|
+
});
|
|
503
|
+
// UPDATE CYCLE RUN
|
|
504
|
+
dbUpdateRun(cycleRunId, {
|
|
505
|
+
status: "completed",
|
|
506
|
+
summary: `Cycle ${cycle}: ${roundCount} rounds, ${totalNewIssues} new issues, loss ${finalLoss}${converged ? " (converged)" : ""}`,
|
|
507
|
+
});
|
|
508
|
+
dbUpdateRunMetadata(cycleRunId, {
|
|
509
|
+
type: "cycle",
|
|
510
|
+
cycle,
|
|
511
|
+
name: cycleName,
|
|
512
|
+
description: cycleDescription,
|
|
513
|
+
rounds: roundCount,
|
|
514
|
+
totalNewIssues,
|
|
515
|
+
existingIssues: issuesMap.size,
|
|
516
|
+
finalLoss,
|
|
517
|
+
converged,
|
|
518
|
+
});
|
|
519
|
+
writeOrchestratorLog(cycleRunId, `Cycle ${cycle} complete: ${roundCount} rounds, ${totalNewIssues} new issues, final loss ${finalLoss}${converged ? " — CONVERGED" : ""}`);
|
|
520
|
+
const cycleResult = {
|
|
521
|
+
cycleRunId,
|
|
522
|
+
cycle,
|
|
523
|
+
name: cycleName,
|
|
524
|
+
description: cycleDescription,
|
|
525
|
+
rounds: roundCount,
|
|
526
|
+
totalNewIssues,
|
|
527
|
+
existingIssues: issuesMap.size,
|
|
528
|
+
finalLoss,
|
|
529
|
+
converged,
|
|
530
|
+
};
|
|
531
|
+
onProgress?.({ type: "cycle_complete", result: cycleResult });
|
|
532
|
+
results.push(cycleResult);
|
|
533
|
+
}
|
|
534
|
+
return results;
|
|
535
|
+
}).pipe(Effect.catchAllDefect((defect) => Effect.fail(new CycleScanError({
|
|
536
|
+
phase: "unknown",
|
|
537
|
+
reason: `Unexpected defect: ${defect instanceof Error ? defect.message : String(defect)}`,
|
|
538
|
+
cause: defect,
|
|
539
|
+
})))),
|
|
540
|
+
};
|
|
541
|
+
}));
|
|
542
|
+
//# sourceMappingURL=cycle-scan-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cycle-scan-service.js","sourceRoot":"","sources":["../../src/services/cycle-scan-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { Context, Effect, Layer } from "effect";
|
|
2
2
|
import { DaemonError } from "../errors.js";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Get the path for the daemon PID file.
|
|
5
|
+
* Resolved relative to cwd at call time so tests can chdir() to temp dirs.
|
|
5
6
|
*/
|
|
6
|
-
export declare const
|
|
7
|
+
export declare const getPidFilePath: () => string;
|
|
8
|
+
/**
|
|
9
|
+
* @deprecated Use getPidFilePath() instead. Kept for backwards compatibility.
|
|
10
|
+
* Note: This is resolved at module load time and won't reflect cwd changes.
|
|
11
|
+
*/
|
|
12
|
+
export declare const PID_FILE_PATH: string;
|
|
7
13
|
/**
|
|
8
14
|
* Default install path for the launchd plist file.
|
|
9
15
|
* Located in the user's LaunchAgents directory for per-user daemons.
|
|
@@ -163,6 +169,20 @@ export declare const readPid: () => Effect.Effect<number | null, DaemonError>;
|
|
|
163
169
|
* @returns Effect that resolves to void on success
|
|
164
170
|
*/
|
|
165
171
|
export declare const removePid: () => Effect.Effect<void, DaemonError>;
|
|
172
|
+
/**
|
|
173
|
+
* Remove the PID file only if its current content matches the expected value.
|
|
174
|
+
*
|
|
175
|
+
* This is a compare-and-swap guard that prevents the TOCTOU race where
|
|
176
|
+
* readPid()'s stale cleanup could delete a freshly-written PID file created
|
|
177
|
+
* by a concurrent daemon start. Between isProcessRunning() returning false
|
|
178
|
+
* and removePid() executing, a new daemon may have written a fresh PID.
|
|
179
|
+
*
|
|
180
|
+
* If the file no longer exists or its content has changed, this is a no-op.
|
|
181
|
+
*
|
|
182
|
+
* @param expectedContent - The PID file content we originally read
|
|
183
|
+
* @returns Effect that resolves to void on success
|
|
184
|
+
*/
|
|
185
|
+
export declare const removePidIfContentMatches: (expectedContent: string) => Effect.Effect<void, DaemonError>;
|
|
166
186
|
/**
|
|
167
187
|
* Configuration for the daemon service.
|
|
168
188
|
*/
|
|
@@ -200,6 +220,24 @@ export interface DaemonConfig {
|
|
|
200
220
|
* Default daemon configuration.
|
|
201
221
|
*/
|
|
202
222
|
export declare const defaultDaemonConfig: DaemonConfig;
|
|
223
|
+
/**
|
|
224
|
+
* Try to atomically create the PID file using O_EXCL.
|
|
225
|
+
* Returns true if created successfully, false if the file already exists.
|
|
226
|
+
* This is the atomic primitive that prevents the TOCTOU race condition.
|
|
227
|
+
*/
|
|
228
|
+
export declare const tryAtomicPidCreate: () => Effect.Effect<boolean, DaemonError>;
|
|
229
|
+
/**
|
|
230
|
+
* Atomically acquire the daemon PID file lock.
|
|
231
|
+
*
|
|
232
|
+
* Uses O_EXCL flag to prevent the TOCTOU race condition where two concurrent
|
|
233
|
+
* `tx daemon start` commands both pass the existence check before either writes
|
|
234
|
+
* the PID file. With O_EXCL, the filesystem guarantees only one process can
|
|
235
|
+
* create the file — the loser gets EEXIST immediately.
|
|
236
|
+
*
|
|
237
|
+
* If the file already exists, checks whether the PID is stale (process dead).
|
|
238
|
+
* Stale files are removed and creation is retried once.
|
|
239
|
+
*/
|
|
240
|
+
export declare const acquirePidLock: () => Effect.Effect<void, DaemonError>;
|
|
203
241
|
/**
|
|
204
242
|
* DaemonServiceLive implementation that manages a real daemon process.
|
|
205
243
|
* Uses child_process.spawn with detached:true to fork the daemon.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon-service.d.ts","sourceRoot":"","sources":["../../src/services/daemon-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAK/C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1C
|
|
1
|
+
{"version":3,"file":"daemon-service.d.ts","sourceRoot":"","sources":["../../src/services/daemon-service.ts"],"names":[],"mappings":"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"}
|