@phuetz/code-buddy 0.1.25 → 0.1.26

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 (253) hide show
  1. package/README.md +1049 -741
  2. package/dist/agent/codebuddy-agent.d.ts +5 -0
  3. package/dist/agent/codebuddy-agent.js +46 -1
  4. package/dist/agent/codebuddy-agent.js.map +1 -1
  5. package/dist/agent/execution/agent-executor.d.ts +12 -0
  6. package/dist/agent/execution/agent-executor.js +147 -6
  7. package/dist/agent/execution/agent-executor.js.map +1 -1
  8. package/dist/agent/lessons-tracker.d.ts +50 -0
  9. package/dist/agent/lessons-tracker.js +234 -0
  10. package/dist/agent/lessons-tracker.js.map +1 -0
  11. package/dist/agent/message-queue.d.ts +39 -2
  12. package/dist/agent/message-queue.js +67 -2
  13. package/dist/agent/message-queue.js.map +1 -1
  14. package/dist/agent/middleware/index.d.ts +1 -0
  15. package/dist/agent/middleware/index.js +1 -0
  16. package/dist/agent/middleware/index.js.map +1 -1
  17. package/dist/agent/middleware/workflow-guard.d.ts +21 -0
  18. package/dist/agent/middleware/workflow-guard.js +94 -0
  19. package/dist/agent/middleware/workflow-guard.js.map +1 -0
  20. package/dist/agent/repo-profiler.d.ts +61 -0
  21. package/dist/agent/repo-profiler.js +295 -0
  22. package/dist/agent/repo-profiler.js.map +1 -0
  23. package/dist/agent/response-constraint.d.ts +61 -0
  24. package/dist/agent/response-constraint.js +91 -0
  25. package/dist/agent/response-constraint.js.map +1 -0
  26. package/dist/agent/todo-tracker.d.ts +67 -0
  27. package/dist/agent/todo-tracker.js +245 -0
  28. package/dist/agent/todo-tracker.js.map +1 -0
  29. package/dist/agent/tool-handler.d.ts +11 -0
  30. package/dist/agent/tool-handler.js +79 -1
  31. package/dist/agent/tool-handler.js.map +1 -1
  32. package/dist/agent/types.d.ts +20 -2
  33. package/dist/agent/wide-research.d.ts +93 -0
  34. package/dist/agent/wide-research.js +232 -0
  35. package/dist/agent/wide-research.js.map +1 -0
  36. package/dist/channels/index.d.ts +2 -0
  37. package/dist/channels/index.js +2 -0
  38. package/dist/channels/index.js.map +1 -1
  39. package/dist/channels/pro/callback-router.d.ts +54 -0
  40. package/dist/channels/pro/callback-router.js +178 -0
  41. package/dist/channels/pro/callback-router.js.map +1 -0
  42. package/dist/channels/pro/ci-watcher.d.ts +86 -0
  43. package/dist/channels/pro/ci-watcher.js +343 -0
  44. package/dist/channels/pro/ci-watcher.js.map +1 -0
  45. package/dist/channels/pro/diff-first.d.ts +63 -0
  46. package/dist/channels/pro/diff-first.js +187 -0
  47. package/dist/channels/pro/diff-first.js.map +1 -0
  48. package/dist/channels/pro/enhanced-commands.d.ts +83 -0
  49. package/dist/channels/pro/enhanced-commands.js +218 -0
  50. package/dist/channels/pro/enhanced-commands.js.map +1 -0
  51. package/dist/channels/pro/index.d.ts +19 -0
  52. package/dist/channels/pro/index.js +21 -0
  53. package/dist/channels/pro/index.js.map +1 -0
  54. package/dist/channels/pro/pro-features.d.ts +79 -0
  55. package/dist/channels/pro/pro-features.js +203 -0
  56. package/dist/channels/pro/pro-features.js.map +1 -0
  57. package/dist/channels/pro/run-commands.d.ts +59 -0
  58. package/dist/channels/pro/run-commands.js +122 -0
  59. package/dist/channels/pro/run-commands.js.map +1 -0
  60. package/dist/channels/pro/run-tracker.d.ts +74 -0
  61. package/dist/channels/pro/run-tracker.js +252 -0
  62. package/dist/channels/pro/run-tracker.js.map +1 -0
  63. package/dist/channels/pro/scoped-auth.d.ts +97 -0
  64. package/dist/channels/pro/scoped-auth.js +340 -0
  65. package/dist/channels/pro/scoped-auth.js.map +1 -0
  66. package/dist/channels/pro/text-formatter.d.ts +27 -0
  67. package/dist/channels/pro/text-formatter.js +269 -0
  68. package/dist/channels/pro/text-formatter.js.map +1 -0
  69. package/dist/channels/pro/types.d.ts +242 -0
  70. package/dist/channels/pro/types.js +14 -0
  71. package/dist/channels/pro/types.js.map +1 -0
  72. package/dist/channels/streaming-policy.d.ts +66 -0
  73. package/dist/channels/streaming-policy.js +266 -0
  74. package/dist/channels/streaming-policy.js.map +1 -0
  75. package/dist/channels/telegram/ci-watcher.d.ts +5 -0
  76. package/dist/channels/telegram/ci-watcher.js +5 -0
  77. package/dist/channels/telegram/ci-watcher.js.map +1 -0
  78. package/dist/channels/telegram/client.d.ts +28 -0
  79. package/dist/channels/telegram/client.js +147 -1
  80. package/dist/channels/telegram/client.js.map +1 -1
  81. package/dist/channels/telegram/diff-first.d.ts +5 -0
  82. package/dist/channels/telegram/diff-first.js +5 -0
  83. package/dist/channels/telegram/diff-first.js.map +1 -0
  84. package/dist/channels/telegram/enhanced-commands.d.ts +6 -0
  85. package/dist/channels/telegram/enhanced-commands.js +6 -0
  86. package/dist/channels/telegram/enhanced-commands.js.map +1 -0
  87. package/dist/channels/telegram/index.d.ts +6 -0
  88. package/dist/channels/telegram/index.js +6 -0
  89. package/dist/channels/telegram/index.js.map +1 -1
  90. package/dist/channels/telegram/pro-formatter.d.ts +30 -0
  91. package/dist/channels/telegram/pro-formatter.js +276 -0
  92. package/dist/channels/telegram/pro-formatter.js.map +1 -0
  93. package/dist/channels/telegram/run-commands.d.ts +5 -0
  94. package/dist/channels/telegram/run-commands.js +6 -0
  95. package/dist/channels/telegram/run-commands.js.map +1 -0
  96. package/dist/channels/telegram/run-tracker.d.ts +5 -0
  97. package/dist/channels/telegram/run-tracker.js +5 -0
  98. package/dist/channels/telegram/run-tracker.js.map +1 -0
  99. package/dist/channels/telegram/scoped-auth.d.ts +6 -0
  100. package/dist/channels/telegram/scoped-auth.js +5 -0
  101. package/dist/channels/telegram/scoped-auth.js.map +1 -0
  102. package/dist/channels/telegram/types.d.ts +34 -0
  103. package/dist/codebuddy/client.js +14 -1
  104. package/dist/codebuddy/client.js.map +1 -1
  105. package/dist/commands/dev/index.d.ts +12 -0
  106. package/dist/commands/dev/index.js +231 -0
  107. package/dist/commands/dev/index.js.map +1 -0
  108. package/dist/commands/dev/workflows.d.ts +31 -0
  109. package/dist/commands/dev/workflows.js +214 -0
  110. package/dist/commands/dev/workflows.js.map +1 -0
  111. package/dist/commands/execpolicy.d.ts +17 -0
  112. package/dist/commands/execpolicy.js +155 -0
  113. package/dist/commands/execpolicy.js.map +1 -0
  114. package/dist/commands/knowledge.d.ts +13 -0
  115. package/dist/commands/knowledge.js +142 -0
  116. package/dist/commands/knowledge.js.map +1 -0
  117. package/dist/commands/lessons.d.ts +11 -0
  118. package/dist/commands/lessons.js +129 -0
  119. package/dist/commands/lessons.js.map +1 -0
  120. package/dist/commands/pairing.d.ts +14 -0
  121. package/dist/commands/pairing.js +132 -0
  122. package/dist/commands/pairing.js.map +1 -0
  123. package/dist/commands/research/index.d.ts +13 -0
  124. package/dist/commands/research/index.js +91 -0
  125. package/dist/commands/research/index.js.map +1 -0
  126. package/dist/commands/run-cli/index.d.ts +11 -0
  127. package/dist/commands/run-cli/index.js +49 -0
  128. package/dist/commands/run-cli/index.js.map +1 -0
  129. package/dist/commands/todos.d.ts +9 -0
  130. package/dist/commands/todos.js +119 -0
  131. package/dist/commands/todos.js.map +1 -0
  132. package/dist/config/toml-config.d.ts +21 -0
  133. package/dist/config/toml-config.js +15 -0
  134. package/dist/config/toml-config.js.map +1 -1
  135. package/dist/context/enhanced-compression.js +12 -1
  136. package/dist/context/enhanced-compression.js.map +1 -1
  137. package/dist/context/observation-variator.d.ts +44 -0
  138. package/dist/context/observation-variator.js +83 -0
  139. package/dist/context/observation-variator.js.map +1 -0
  140. package/dist/context/precompaction-flush.d.ts +40 -0
  141. package/dist/context/precompaction-flush.js +134 -0
  142. package/dist/context/precompaction-flush.js.map +1 -0
  143. package/dist/context/restorable-compression.d.ts +80 -0
  144. package/dist/context/restorable-compression.js +228 -0
  145. package/dist/context/restorable-compression.js.map +1 -0
  146. package/dist/daemon/daily-reset.d.ts +77 -0
  147. package/dist/daemon/daily-reset.js +175 -0
  148. package/dist/daemon/daily-reset.js.map +1 -0
  149. package/dist/daemon/index.d.ts +1 -0
  150. package/dist/daemon/index.js +1 -0
  151. package/dist/daemon/index.js.map +1 -1
  152. package/dist/index.js +53 -0
  153. package/dist/index.js.map +1 -1
  154. package/dist/knowledge/knowledge-manager.d.ts +77 -0
  155. package/dist/knowledge/knowledge-manager.js +244 -0
  156. package/dist/knowledge/knowledge-manager.js.map +1 -0
  157. package/dist/observability/run-store.d.ts +133 -0
  158. package/dist/observability/run-store.js +419 -0
  159. package/dist/observability/run-store.js.map +1 -0
  160. package/dist/observability/run-viewer.d.ts +33 -0
  161. package/dist/observability/run-viewer.js +254 -0
  162. package/dist/observability/run-viewer.js.map +1 -0
  163. package/dist/optimization/cache-breakpoints.d.ts +52 -0
  164. package/dist/optimization/cache-breakpoints.js +97 -0
  165. package/dist/optimization/cache-breakpoints.js.map +1 -0
  166. package/dist/persistence/session-store.d.ts +3 -1
  167. package/dist/persistence/session-store.js +1 -1
  168. package/dist/persistence/session-store.js.map +1 -1
  169. package/dist/prompts/system-base.js +51 -7
  170. package/dist/prompts/system-base.js.map +1 -1
  171. package/dist/prompts/variation-injector.d.ts +55 -0
  172. package/dist/prompts/variation-injector.js +171 -0
  173. package/dist/prompts/variation-injector.js.map +1 -0
  174. package/dist/prompts/workflow-rules.d.ts +10 -0
  175. package/dist/prompts/workflow-rules.js +79 -0
  176. package/dist/prompts/workflow-rules.js.map +1 -0
  177. package/dist/sandbox/execpolicy.d.ts +45 -0
  178. package/dist/sandbox/execpolicy.js +80 -0
  179. package/dist/sandbox/execpolicy.js.map +1 -1
  180. package/dist/sandbox/os-sandbox.d.ts +25 -0
  181. package/dist/sandbox/os-sandbox.js +73 -0
  182. package/dist/sandbox/os-sandbox.js.map +1 -1
  183. package/dist/security/security-audit.d.ts +10 -0
  184. package/dist/security/security-audit.js +116 -0
  185. package/dist/security/security-audit.js.map +1 -1
  186. package/dist/security/shell-env-policy.d.ts +45 -0
  187. package/dist/security/shell-env-policy.js +141 -0
  188. package/dist/security/shell-env-policy.js.map +1 -0
  189. package/dist/security/ssrf-guard.d.ts +61 -0
  190. package/dist/security/ssrf-guard.js +382 -0
  191. package/dist/security/ssrf-guard.js.map +1 -0
  192. package/dist/security/write-policy.d.ts +57 -0
  193. package/dist/security/write-policy.js +117 -0
  194. package/dist/security/write-policy.js.map +1 -0
  195. package/dist/services/prompt-builder.js +37 -0
  196. package/dist/services/prompt-builder.js.map +1 -1
  197. package/dist/themes/theme-schema.d.ts +10 -10
  198. package/dist/tools/ask-human-tool.d.ts +62 -0
  199. package/dist/tools/ask-human-tool.js +112 -0
  200. package/dist/tools/ask-human-tool.js.map +1 -0
  201. package/dist/tools/bash/bash-tool.d.ts +15 -0
  202. package/dist/tools/bash/bash-tool.js +62 -0
  203. package/dist/tools/bash/bash-tool.js.map +1 -1
  204. package/dist/tools/bash/command-validator.d.ts +1 -0
  205. package/dist/tools/bash/command-validator.js +5 -0
  206. package/dist/tools/bash/command-validator.js.map +1 -1
  207. package/dist/tools/create-skill-tool.d.ts +87 -0
  208. package/dist/tools/create-skill-tool.js +142 -0
  209. package/dist/tools/create-skill-tool.js.map +1 -0
  210. package/dist/tools/fetch-tool.js +5 -3
  211. package/dist/tools/fetch-tool.js.map +1 -1
  212. package/dist/tools/index.d.ts +1 -0
  213. package/dist/tools/index.js +1 -0
  214. package/dist/tools/index.js.map +1 -1
  215. package/dist/tools/plan-tool.d.ts +22 -0
  216. package/dist/tools/plan-tool.js +128 -0
  217. package/dist/tools/plan-tool.js.map +1 -0
  218. package/dist/tools/registry/attention-tools.d.ts +32 -0
  219. package/dist/tools/registry/attention-tools.js +225 -0
  220. package/dist/tools/registry/attention-tools.js.map +1 -0
  221. package/dist/tools/registry/index.d.ts +9 -1
  222. package/dist/tools/registry/index.js +30 -2
  223. package/dist/tools/registry/index.js.map +1 -1
  224. package/dist/tools/registry/knowledge-tools.d.ts +46 -0
  225. package/dist/tools/registry/knowledge-tools.js +293 -0
  226. package/dist/tools/registry/knowledge-tools.js.map +1 -0
  227. package/dist/tools/registry/lessons-tools.d.ts +48 -0
  228. package/dist/tools/registry/lessons-tools.js +359 -0
  229. package/dist/tools/registry/lessons-tools.js.map +1 -0
  230. package/dist/tools/registry/plan-tools.d.ts +2 -0
  231. package/dist/tools/registry/plan-tools.js +7 -0
  232. package/dist/tools/registry/plan-tools.js.map +1 -0
  233. package/dist/tools/registry/script-tools.d.ts +2 -0
  234. package/dist/tools/registry/script-tools.js +7 -0
  235. package/dist/tools/registry/script-tools.js.map +1 -0
  236. package/dist/tools/registry/tool-aliases.d.ts +44 -0
  237. package/dist/tools/registry/tool-aliases.js +130 -0
  238. package/dist/tools/registry/tool-aliases.js.map +1 -0
  239. package/dist/tools/run-script-tool.d.ts +13 -0
  240. package/dist/tools/run-script-tool.js +146 -0
  241. package/dist/tools/run-script-tool.js.map +1 -0
  242. package/dist/tools/web-search.d.ts +25 -0
  243. package/dist/tools/web-search.js +68 -6
  244. package/dist/tools/web-search.js.map +1 -1
  245. package/dist/utils/config-validation/schema.d.ts +2 -2
  246. package/dist/utils/debug-logger.d.ts +1 -1
  247. package/dist/utils/stable-json.d.ts +27 -0
  248. package/dist/utils/stable-json.js +50 -0
  249. package/dist/utils/stable-json.js.map +1 -0
  250. package/dist/webhooks/webhook-manager.d.ts +7 -0
  251. package/dist/webhooks/webhook-manager.js +29 -0
  252. package/dist/webhooks/webhook-manager.js.map +1 -1
  253. package/package.json +1 -1
@@ -0,0 +1,133 @@
1
+ /**
2
+ * RunStore — JSONL-based observability store for agent runs.
3
+ *
4
+ * Each run gets its own directory under .codebuddy/runs/run_<id>/ with:
5
+ * events.jsonl — append-only event log (one JSON object per line)
6
+ * metrics.json — tokens, cost, duration, failover count
7
+ * artifacts/ — plan.md, patch.diff, commands.log, summary.md …
8
+ *
9
+ * Written in append mode for performance — no full-file parsing per event.
10
+ * Automatic pruning keeps the 30 most recent runs.
11
+ */
12
+ export type RunEventType = 'run_start' | 'run_end' | 'step_start' | 'step_end' | 'tool_call' | 'tool_result' | 'patch_created' | 'patch_applied' | 'decision' | 'error' | 'metric';
13
+ export interface RunEvent {
14
+ ts: number;
15
+ type: RunEventType;
16
+ runId: string;
17
+ data: Record<string, unknown>;
18
+ }
19
+ export interface RunMetadata {
20
+ /** Channel or context (e.g. 'terminal', 'telegram') */
21
+ channel?: string;
22
+ /** User ID if applicable */
23
+ userId?: string;
24
+ /** Session ID */
25
+ sessionId?: string;
26
+ /** Tags for filtering */
27
+ tags?: string[];
28
+ /**
29
+ * Session Fork / Rollout unification (Codex-inspired).
30
+ * When a run is forked (e.g. retry from checkpoint, A/B rollout variant),
31
+ * this field links it to the original parent run ID so lineage can be
32
+ * reconstructed. Enables `buddy run replay --from-fork` and cost attribution.
33
+ */
34
+ parentRolloutId?: string;
35
+ /** Fork reason for traceability (e.g. 'retry', 'ab-variant-B', 'checkpoint-rollback') */
36
+ forkReason?: string;
37
+ }
38
+ export interface RunMetrics {
39
+ totalTokens: number;
40
+ promptTokens: number;
41
+ completionTokens: number;
42
+ totalCost: number;
43
+ durationMs: number;
44
+ toolCallCount: number;
45
+ failoverCount: number;
46
+ }
47
+ export interface RunSummary {
48
+ runId: string;
49
+ objective: string;
50
+ status: 'running' | 'completed' | 'failed' | 'cancelled';
51
+ startedAt: number;
52
+ endedAt?: number;
53
+ eventCount: number;
54
+ artifactCount: number;
55
+ metadata?: RunMetadata;
56
+ }
57
+ export interface RunRecord {
58
+ summary: RunSummary;
59
+ metrics: Partial<RunMetrics>;
60
+ artifacts: string[];
61
+ }
62
+ export declare class RunStore {
63
+ private static _instance;
64
+ private runsDir;
65
+ /** File handles for active run event streams */
66
+ private handles;
67
+ /** In-memory event counts per run */
68
+ private eventCounts;
69
+ /** In-memory summaries for fast listing */
70
+ private summaries;
71
+ constructor(runsDir?: string);
72
+ static getInstance(): RunStore;
73
+ /**
74
+ * Create a new run and return its ID.
75
+ */
76
+ startRun(objective: string, metadata?: RunMetadata): string;
77
+ /**
78
+ * Fork an existing run — creates a new child run that inherits the parent's
79
+ * objective and metadata, with `parentRolloutId` set for lineage tracking.
80
+ *
81
+ * Codex-inspired session fork / rollout unification: both the checkpoint
82
+ * rollback path and A/B variant rollouts produce forked runs that can be
83
+ * compared via `buddy run show <id>`.
84
+ *
85
+ * @param parentRunId - The run being forked
86
+ * @param reason - Human-readable fork reason ('retry', 'ab-variant-B', etc.)
87
+ * @param overrides - Optional metadata overrides for the forked run
88
+ */
89
+ forkRun(parentRunId: string, reason: string, overrides?: Partial<RunMetadata>): string;
90
+ /**
91
+ * Emit an event for a run. Thread-safe: writes are serialized by the writable stream.
92
+ */
93
+ emit(runId: string, event: Omit<RunEvent, 'ts' | 'runId'>): void;
94
+ /**
95
+ * End a run and flush the event stream.
96
+ */
97
+ endRun(runId: string, status: 'completed' | 'failed' | 'cancelled'): void;
98
+ /**
99
+ * Save an artifact file for a run. Returns the absolute path.
100
+ */
101
+ saveArtifact(runId: string, name: string, content: string): string;
102
+ /**
103
+ * Update metrics for a run (merges with existing).
104
+ */
105
+ updateMetrics(runId: string, metrics: Partial<RunMetrics>): void;
106
+ /**
107
+ * Get the full record for a run (summary + metrics + artifact list).
108
+ */
109
+ getRun(runId: string): RunRecord | null;
110
+ /**
111
+ * List runs, most recent first.
112
+ */
113
+ listRuns(limit?: number): RunSummary[];
114
+ /**
115
+ * Read all events from a run's JSONL file.
116
+ */
117
+ getEvents(runId: string): RunEvent[];
118
+ /**
119
+ * Async generator that yields new events as they are appended to events.jsonl.
120
+ * Stops when the run ends (status no longer 'running') or after timeout.
121
+ */
122
+ streamEvents(runId: string, timeoutMs?: number): AsyncIterable<RunEvent>;
123
+ /**
124
+ * Read artifact content.
125
+ */
126
+ getArtifact(runId: string, name: string): string | null;
127
+ private runDir;
128
+ private ensureDir;
129
+ private saveMetrics;
130
+ private saveSummary;
131
+ private loadSummaries;
132
+ private pruneOldRuns;
133
+ }
@@ -0,0 +1,419 @@
1
+ /**
2
+ * RunStore — JSONL-based observability store for agent runs.
3
+ *
4
+ * Each run gets its own directory under .codebuddy/runs/run_<id>/ with:
5
+ * events.jsonl — append-only event log (one JSON object per line)
6
+ * metrics.json — tokens, cost, duration, failover count
7
+ * artifacts/ — plan.md, patch.diff, commands.log, summary.md …
8
+ *
9
+ * Written in append mode for performance — no full-file parsing per event.
10
+ * Automatic pruning keeps the 30 most recent runs.
11
+ */
12
+ import fs from 'fs';
13
+ import path from 'path';
14
+ import os from 'os';
15
+ import { randomBytes } from 'crypto';
16
+ import { logger } from '../utils/logger.js';
17
+ const MAX_RUNS = 30;
18
+ // ──────────────────────────────────────────────────────────────────
19
+ // RunStore
20
+ // ──────────────────────────────────────────────────────────────────
21
+ export class RunStore {
22
+ static _instance = null;
23
+ runsDir;
24
+ /** File handles for active run event streams */
25
+ handles = new Map();
26
+ /** In-memory event counts per run */
27
+ eventCounts = new Map();
28
+ /** In-memory summaries for fast listing */
29
+ summaries = new Map();
30
+ constructor(runsDir) {
31
+ this.runsDir = runsDir || path.join(os.homedir(), '.codebuddy', 'runs');
32
+ this.ensureDir(this.runsDir);
33
+ this.loadSummaries();
34
+ }
35
+ static getInstance() {
36
+ if (!RunStore._instance) {
37
+ RunStore._instance = new RunStore();
38
+ }
39
+ return RunStore._instance;
40
+ }
41
+ // ──────────────────────────────────────────────────────────────
42
+ // Run lifecycle
43
+ // ──────────────────────────────────────────────────────────────
44
+ /**
45
+ * Create a new run and return its ID.
46
+ */
47
+ startRun(objective, metadata) {
48
+ const runId = `run_${Date.now().toString(36)}_${randomBytes(3).toString('hex')}`;
49
+ const runDir = this.runDir(runId);
50
+ this.ensureDir(runDir);
51
+ this.ensureDir(path.join(runDir, 'artifacts'));
52
+ const summary = {
53
+ runId,
54
+ objective,
55
+ status: 'running',
56
+ startedAt: Date.now(),
57
+ eventCount: 0,
58
+ artifactCount: 0,
59
+ metadata,
60
+ };
61
+ this.summaries.set(runId, summary);
62
+ this.eventCounts.set(runId, 0);
63
+ // Create events file synchronously, then open append stream
64
+ const eventsPath = path.join(runDir, 'events.jsonl');
65
+ fs.writeFileSync(eventsPath, '', { flag: 'a' }); // ensure file exists
66
+ const ws = fs.createWriteStream(eventsPath, { flags: 'a', encoding: 'utf-8' });
67
+ this.handles.set(runId, ws);
68
+ // Emit run_start event
69
+ this.emit(runId, { type: 'run_start', data: { objective, metadata } });
70
+ // Save initial metrics
71
+ this.saveMetrics(runId, {
72
+ totalTokens: 0,
73
+ promptTokens: 0,
74
+ completionTokens: 0,
75
+ totalCost: 0,
76
+ durationMs: 0,
77
+ toolCallCount: 0,
78
+ failoverCount: 0,
79
+ });
80
+ this.saveSummary(runId, summary);
81
+ this.pruneOldRuns();
82
+ logger.debug(`RunStore: started run ${runId}`, { objective });
83
+ return runId;
84
+ }
85
+ /**
86
+ * Fork an existing run — creates a new child run that inherits the parent's
87
+ * objective and metadata, with `parentRolloutId` set for lineage tracking.
88
+ *
89
+ * Codex-inspired session fork / rollout unification: both the checkpoint
90
+ * rollback path and A/B variant rollouts produce forked runs that can be
91
+ * compared via `buddy run show <id>`.
92
+ *
93
+ * @param parentRunId - The run being forked
94
+ * @param reason - Human-readable fork reason ('retry', 'ab-variant-B', etc.)
95
+ * @param overrides - Optional metadata overrides for the forked run
96
+ */
97
+ forkRun(parentRunId, reason, overrides) {
98
+ const parent = this.summaries.get(parentRunId);
99
+ const objective = parent
100
+ ? `[fork:${reason}] ${parent.objective}`
101
+ : `[fork:${reason}]`;
102
+ const parentMeta = parent?.metadata ?? {};
103
+ const forkMeta = {
104
+ ...parentMeta,
105
+ ...overrides,
106
+ parentRolloutId: parentRunId,
107
+ forkReason: reason,
108
+ };
109
+ const newRunId = this.startRun(objective, forkMeta);
110
+ this.emit(newRunId, {
111
+ type: 'decision',
112
+ data: { kind: 'fork', parentRunId, reason },
113
+ });
114
+ logger.debug(`RunStore: forked run ${parentRunId} → ${newRunId}`, { reason });
115
+ return newRunId;
116
+ }
117
+ /**
118
+ * Emit an event for a run. Thread-safe: writes are serialized by the writable stream.
119
+ */
120
+ emit(runId, event) {
121
+ const ws = this.handles.get(runId);
122
+ if (!ws)
123
+ return;
124
+ const fullEvent = {
125
+ ts: Date.now(),
126
+ runId,
127
+ ...event,
128
+ };
129
+ try {
130
+ ws.write(JSON.stringify(fullEvent) + '\n');
131
+ }
132
+ catch (err) {
133
+ logger.debug('RunStore: failed to write event', { runId, err });
134
+ }
135
+ // Update in-memory count
136
+ const count = (this.eventCounts.get(runId) || 0) + 1;
137
+ this.eventCounts.set(runId, count);
138
+ const summary = this.summaries.get(runId);
139
+ if (summary) {
140
+ summary.eventCount = count;
141
+ }
142
+ }
143
+ /**
144
+ * End a run and flush the event stream.
145
+ */
146
+ endRun(runId, status) {
147
+ this.emit(runId, { type: 'run_end', data: { status } });
148
+ const summary = this.summaries.get(runId);
149
+ if (summary) {
150
+ summary.status = status;
151
+ summary.endedAt = Date.now();
152
+ this.saveSummary(runId, summary);
153
+ }
154
+ // Update metrics duration
155
+ try {
156
+ const metricsPath = path.join(this.runDir(runId), 'metrics.json');
157
+ if (fs.existsSync(metricsPath)) {
158
+ const metrics = JSON.parse(fs.readFileSync(metricsPath, 'utf-8'));
159
+ metrics.durationMs = (summary?.endedAt || Date.now()) - (summary?.startedAt || Date.now());
160
+ fs.writeFileSync(metricsPath, JSON.stringify(metrics, null, 2));
161
+ }
162
+ }
163
+ catch {
164
+ // Ignore
165
+ }
166
+ // Close write stream
167
+ const ws = this.handles.get(runId);
168
+ if (ws) {
169
+ ws.end();
170
+ this.handles.delete(runId);
171
+ }
172
+ logger.debug(`RunStore: ended run ${runId} with status ${status}`);
173
+ }
174
+ // ──────────────────────────────────────────────────────────────
175
+ // Artifacts
176
+ // ──────────────────────────────────────────────────────────────
177
+ /**
178
+ * Save an artifact file for a run. Returns the absolute path.
179
+ */
180
+ saveArtifact(runId, name, content) {
181
+ const artifactsDir = path.join(this.runDir(runId), 'artifacts');
182
+ this.ensureDir(artifactsDir);
183
+ const filePath = path.join(artifactsDir, name);
184
+ fs.writeFileSync(filePath, content, 'utf-8');
185
+ const summary = this.summaries.get(runId);
186
+ if (summary) {
187
+ summary.artifactCount = (summary.artifactCount || 0) + 1;
188
+ this.saveSummary(runId, summary);
189
+ }
190
+ this.emit(runId, {
191
+ type: 'patch_created',
192
+ data: { artifact: name, path: filePath },
193
+ });
194
+ return filePath;
195
+ }
196
+ /**
197
+ * Update metrics for a run (merges with existing).
198
+ */
199
+ updateMetrics(runId, metrics) {
200
+ try {
201
+ const metricsPath = path.join(this.runDir(runId), 'metrics.json');
202
+ let existing = {};
203
+ if (fs.existsSync(metricsPath)) {
204
+ existing = JSON.parse(fs.readFileSync(metricsPath, 'utf-8'));
205
+ }
206
+ const merged = { ...existing, ...metrics };
207
+ fs.writeFileSync(metricsPath, JSON.stringify(merged, null, 2));
208
+ }
209
+ catch {
210
+ // Ignore
211
+ }
212
+ }
213
+ // ──────────────────────────────────────────────────────────────
214
+ // Reading
215
+ // ──────────────────────────────────────────────────────────────
216
+ /**
217
+ * Get the full record for a run (summary + metrics + artifact list).
218
+ */
219
+ getRun(runId) {
220
+ const summary = this.summaries.get(runId);
221
+ if (!summary)
222
+ return null;
223
+ const runDir = this.runDir(runId);
224
+ let metrics = {};
225
+ try {
226
+ const metricsPath = path.join(runDir, 'metrics.json');
227
+ if (fs.existsSync(metricsPath)) {
228
+ metrics = JSON.parse(fs.readFileSync(metricsPath, 'utf-8'));
229
+ }
230
+ }
231
+ catch {
232
+ // Ignore
233
+ }
234
+ const artifacts = [];
235
+ try {
236
+ const artifactsDir = path.join(runDir, 'artifacts');
237
+ if (fs.existsSync(artifactsDir)) {
238
+ artifacts.push(...fs.readdirSync(artifactsDir));
239
+ }
240
+ }
241
+ catch {
242
+ // Ignore
243
+ }
244
+ return { summary, metrics, artifacts };
245
+ }
246
+ /**
247
+ * List runs, most recent first.
248
+ */
249
+ listRuns(limit = 20) {
250
+ return Array.from(this.summaries.values())
251
+ .sort((a, b) => b.startedAt - a.startedAt)
252
+ .slice(0, limit);
253
+ }
254
+ /**
255
+ * Read all events from a run's JSONL file.
256
+ */
257
+ getEvents(runId) {
258
+ const eventsPath = path.join(this.runDir(runId), 'events.jsonl');
259
+ if (!fs.existsSync(eventsPath))
260
+ return [];
261
+ const events = [];
262
+ try {
263
+ const lines = fs.readFileSync(eventsPath, 'utf-8').split('\n');
264
+ for (const line of lines) {
265
+ if (!line.trim())
266
+ continue;
267
+ try {
268
+ events.push(JSON.parse(line));
269
+ }
270
+ catch {
271
+ // Skip malformed lines
272
+ }
273
+ }
274
+ }
275
+ catch {
276
+ // Ignore
277
+ }
278
+ return events;
279
+ }
280
+ /**
281
+ * Async generator that yields new events as they are appended to events.jsonl.
282
+ * Stops when the run ends (status no longer 'running') or after timeout.
283
+ */
284
+ async *streamEvents(runId, timeoutMs = 300_000) {
285
+ const eventsPath = path.join(this.runDir(runId), 'events.jsonl');
286
+ if (!fs.existsSync(eventsPath))
287
+ return;
288
+ let offset = 0;
289
+ const deadline = Date.now() + timeoutMs;
290
+ while (Date.now() < deadline) {
291
+ const summary = this.summaries.get(runId);
292
+ const isActive = summary?.status === 'running' || this.handles.has(runId);
293
+ // Read new bytes since last offset
294
+ try {
295
+ const buf = Buffer.alloc(1024 * 64);
296
+ const fd = fs.openSync(eventsPath, 'r');
297
+ const bytesRead = fs.readSync(fd, buf, 0, buf.length, offset);
298
+ fs.closeSync(fd);
299
+ if (bytesRead > 0) {
300
+ const chunk = buf.slice(0, bytesRead).toString('utf-8');
301
+ offset += bytesRead;
302
+ const lines = chunk.split('\n');
303
+ for (const line of lines) {
304
+ if (!line.trim())
305
+ continue;
306
+ try {
307
+ yield JSON.parse(line);
308
+ }
309
+ catch {
310
+ // Skip malformed
311
+ }
312
+ }
313
+ }
314
+ }
315
+ catch {
316
+ // Ignore read errors
317
+ }
318
+ if (!isActive)
319
+ break;
320
+ // Small delay before next poll
321
+ await new Promise((r) => setTimeout(r, 200));
322
+ }
323
+ }
324
+ /**
325
+ * Read artifact content.
326
+ */
327
+ getArtifact(runId, name) {
328
+ const filePath = path.join(this.runDir(runId), 'artifacts', name);
329
+ try {
330
+ return fs.readFileSync(filePath, 'utf-8');
331
+ }
332
+ catch {
333
+ return null;
334
+ }
335
+ }
336
+ // ──────────────────────────────────────────────────────────────
337
+ // Private helpers
338
+ // ──────────────────────────────────────────────────────────────
339
+ runDir(runId) {
340
+ return path.join(this.runsDir, runId);
341
+ }
342
+ ensureDir(dir) {
343
+ if (!fs.existsSync(dir)) {
344
+ fs.mkdirSync(dir, { recursive: true });
345
+ }
346
+ }
347
+ saveMetrics(runId, metrics) {
348
+ try {
349
+ const metricsPath = path.join(this.runDir(runId), 'metrics.json');
350
+ fs.writeFileSync(metricsPath, JSON.stringify(metrics, null, 2));
351
+ }
352
+ catch {
353
+ // Ignore
354
+ }
355
+ }
356
+ saveSummary(runId, summary) {
357
+ try {
358
+ const summaryPath = path.join(this.runDir(runId), 'summary.json');
359
+ fs.writeFileSync(summaryPath, JSON.stringify(summary, null, 2));
360
+ }
361
+ catch {
362
+ // Ignore
363
+ }
364
+ }
365
+ loadSummaries() {
366
+ try {
367
+ if (!fs.existsSync(this.runsDir))
368
+ return;
369
+ const dirs = fs.readdirSync(this.runsDir).filter((d) => d.startsWith('run_'));
370
+ for (const dir of dirs) {
371
+ try {
372
+ const summaryPath = path.join(this.runsDir, dir, 'summary.json');
373
+ if (fs.existsSync(summaryPath)) {
374
+ const summary = JSON.parse(fs.readFileSync(summaryPath, 'utf-8'));
375
+ this.summaries.set(summary.runId, summary);
376
+ // Count events from file size heuristic (avoid full parse on load)
377
+ const eventsPath = path.join(this.runsDir, dir, 'events.jsonl');
378
+ if (fs.existsSync(eventsPath)) {
379
+ this.eventCounts.set(summary.runId, summary.eventCount || 0);
380
+ }
381
+ }
382
+ }
383
+ catch {
384
+ // Skip malformed
385
+ }
386
+ }
387
+ }
388
+ catch {
389
+ // Ignore
390
+ }
391
+ }
392
+ pruneOldRuns() {
393
+ const sorted = Array.from(this.summaries.values()).sort((a, b) => b.startedAt - a.startedAt);
394
+ if (sorted.length <= MAX_RUNS)
395
+ return;
396
+ const toRemove = sorted.slice(MAX_RUNS);
397
+ for (const s of toRemove) {
398
+ const runDir = this.runDir(s.runId);
399
+ this.summaries.delete(s.runId);
400
+ this.eventCounts.delete(s.runId);
401
+ // Destroy handle immediately (force close, no flush needed for pruned runs)
402
+ const ws = this.handles.get(s.runId);
403
+ if (ws) {
404
+ ws.destroy();
405
+ this.handles.delete(s.runId);
406
+ }
407
+ // Remove directory after a short delay to let the stream fully close
408
+ setTimeout(() => {
409
+ try {
410
+ fs.rmSync(runDir, { recursive: true, force: true });
411
+ }
412
+ catch {
413
+ // Ignore
414
+ }
415
+ }, 20);
416
+ }
417
+ }
418
+ }
419
+ //# sourceMappingURL=run-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-store.js","sourceRoot":"","sources":["../../src/observability/run-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * RunViewer — terminal display helpers for RunStore runs.
3
+ *
4
+ * Provides:
5
+ * showRun() — display complete timeline + metrics + artifacts
6
+ * tailRun() — stream events in real-time (follow mode)
7
+ * replayRun() — show timeline then re-execute test steps
8
+ */
9
+ import { RunEvent, RunMetrics } from './run-store.js';
10
+ /**
11
+ * Build a full timeline string from a list of events.
12
+ */
13
+ export declare function prettyTimeline(events: RunEvent[]): string;
14
+ /**
15
+ * Format metrics for display.
16
+ */
17
+ export declare function showMetrics(metrics: Partial<RunMetrics>): string;
18
+ /**
19
+ * Print a complete run record to stdout.
20
+ */
21
+ export declare function showRun(runId: string): Promise<void>;
22
+ /**
23
+ * Tail a run's event stream live.
24
+ */
25
+ export declare function tailRun(runId: string): Promise<void>;
26
+ /**
27
+ * Replay: show timeline then list test steps that can be re-run.
28
+ */
29
+ export declare function replayRun(runId: string, rerun?: boolean): Promise<void>;
30
+ /**
31
+ * List runs summary to stdout.
32
+ */
33
+ export declare function listRuns(limit?: number): void;