@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.
- package/README.md +1049 -741
- package/dist/agent/codebuddy-agent.d.ts +5 -0
- package/dist/agent/codebuddy-agent.js +46 -1
- package/dist/agent/codebuddy-agent.js.map +1 -1
- package/dist/agent/execution/agent-executor.d.ts +12 -0
- package/dist/agent/execution/agent-executor.js +147 -6
- package/dist/agent/execution/agent-executor.js.map +1 -1
- package/dist/agent/lessons-tracker.d.ts +50 -0
- package/dist/agent/lessons-tracker.js +234 -0
- package/dist/agent/lessons-tracker.js.map +1 -0
- package/dist/agent/message-queue.d.ts +39 -2
- package/dist/agent/message-queue.js +67 -2
- package/dist/agent/message-queue.js.map +1 -1
- package/dist/agent/middleware/index.d.ts +1 -0
- package/dist/agent/middleware/index.js +1 -0
- package/dist/agent/middleware/index.js.map +1 -1
- package/dist/agent/middleware/workflow-guard.d.ts +21 -0
- package/dist/agent/middleware/workflow-guard.js +94 -0
- package/dist/agent/middleware/workflow-guard.js.map +1 -0
- package/dist/agent/repo-profiler.d.ts +61 -0
- package/dist/agent/repo-profiler.js +295 -0
- package/dist/agent/repo-profiler.js.map +1 -0
- package/dist/agent/response-constraint.d.ts +61 -0
- package/dist/agent/response-constraint.js +91 -0
- package/dist/agent/response-constraint.js.map +1 -0
- package/dist/agent/todo-tracker.d.ts +67 -0
- package/dist/agent/todo-tracker.js +245 -0
- package/dist/agent/todo-tracker.js.map +1 -0
- package/dist/agent/tool-handler.d.ts +11 -0
- package/dist/agent/tool-handler.js +79 -1
- package/dist/agent/tool-handler.js.map +1 -1
- package/dist/agent/types.d.ts +20 -2
- package/dist/agent/wide-research.d.ts +93 -0
- package/dist/agent/wide-research.js +232 -0
- package/dist/agent/wide-research.js.map +1 -0
- package/dist/channels/index.d.ts +2 -0
- package/dist/channels/index.js +2 -0
- package/dist/channels/index.js.map +1 -1
- package/dist/channels/pro/callback-router.d.ts +54 -0
- package/dist/channels/pro/callback-router.js +178 -0
- package/dist/channels/pro/callback-router.js.map +1 -0
- package/dist/channels/pro/ci-watcher.d.ts +86 -0
- package/dist/channels/pro/ci-watcher.js +343 -0
- package/dist/channels/pro/ci-watcher.js.map +1 -0
- package/dist/channels/pro/diff-first.d.ts +63 -0
- package/dist/channels/pro/diff-first.js +187 -0
- package/dist/channels/pro/diff-first.js.map +1 -0
- package/dist/channels/pro/enhanced-commands.d.ts +83 -0
- package/dist/channels/pro/enhanced-commands.js +218 -0
- package/dist/channels/pro/enhanced-commands.js.map +1 -0
- package/dist/channels/pro/index.d.ts +19 -0
- package/dist/channels/pro/index.js +21 -0
- package/dist/channels/pro/index.js.map +1 -0
- package/dist/channels/pro/pro-features.d.ts +79 -0
- package/dist/channels/pro/pro-features.js +203 -0
- package/dist/channels/pro/pro-features.js.map +1 -0
- package/dist/channels/pro/run-commands.d.ts +59 -0
- package/dist/channels/pro/run-commands.js +122 -0
- package/dist/channels/pro/run-commands.js.map +1 -0
- package/dist/channels/pro/run-tracker.d.ts +74 -0
- package/dist/channels/pro/run-tracker.js +252 -0
- package/dist/channels/pro/run-tracker.js.map +1 -0
- package/dist/channels/pro/scoped-auth.d.ts +97 -0
- package/dist/channels/pro/scoped-auth.js +340 -0
- package/dist/channels/pro/scoped-auth.js.map +1 -0
- package/dist/channels/pro/text-formatter.d.ts +27 -0
- package/dist/channels/pro/text-formatter.js +269 -0
- package/dist/channels/pro/text-formatter.js.map +1 -0
- package/dist/channels/pro/types.d.ts +242 -0
- package/dist/channels/pro/types.js +14 -0
- package/dist/channels/pro/types.js.map +1 -0
- package/dist/channels/streaming-policy.d.ts +66 -0
- package/dist/channels/streaming-policy.js +266 -0
- package/dist/channels/streaming-policy.js.map +1 -0
- package/dist/channels/telegram/ci-watcher.d.ts +5 -0
- package/dist/channels/telegram/ci-watcher.js +5 -0
- package/dist/channels/telegram/ci-watcher.js.map +1 -0
- package/dist/channels/telegram/client.d.ts +28 -0
- package/dist/channels/telegram/client.js +147 -1
- package/dist/channels/telegram/client.js.map +1 -1
- package/dist/channels/telegram/diff-first.d.ts +5 -0
- package/dist/channels/telegram/diff-first.js +5 -0
- package/dist/channels/telegram/diff-first.js.map +1 -0
- package/dist/channels/telegram/enhanced-commands.d.ts +6 -0
- package/dist/channels/telegram/enhanced-commands.js +6 -0
- package/dist/channels/telegram/enhanced-commands.js.map +1 -0
- package/dist/channels/telegram/index.d.ts +6 -0
- package/dist/channels/telegram/index.js +6 -0
- package/dist/channels/telegram/index.js.map +1 -1
- package/dist/channels/telegram/pro-formatter.d.ts +30 -0
- package/dist/channels/telegram/pro-formatter.js +276 -0
- package/dist/channels/telegram/pro-formatter.js.map +1 -0
- package/dist/channels/telegram/run-commands.d.ts +5 -0
- package/dist/channels/telegram/run-commands.js +6 -0
- package/dist/channels/telegram/run-commands.js.map +1 -0
- package/dist/channels/telegram/run-tracker.d.ts +5 -0
- package/dist/channels/telegram/run-tracker.js +5 -0
- package/dist/channels/telegram/run-tracker.js.map +1 -0
- package/dist/channels/telegram/scoped-auth.d.ts +6 -0
- package/dist/channels/telegram/scoped-auth.js +5 -0
- package/dist/channels/telegram/scoped-auth.js.map +1 -0
- package/dist/channels/telegram/types.d.ts +34 -0
- package/dist/codebuddy/client.js +14 -1
- package/dist/codebuddy/client.js.map +1 -1
- package/dist/commands/dev/index.d.ts +12 -0
- package/dist/commands/dev/index.js +231 -0
- package/dist/commands/dev/index.js.map +1 -0
- package/dist/commands/dev/workflows.d.ts +31 -0
- package/dist/commands/dev/workflows.js +214 -0
- package/dist/commands/dev/workflows.js.map +1 -0
- package/dist/commands/execpolicy.d.ts +17 -0
- package/dist/commands/execpolicy.js +155 -0
- package/dist/commands/execpolicy.js.map +1 -0
- package/dist/commands/knowledge.d.ts +13 -0
- package/dist/commands/knowledge.js +142 -0
- package/dist/commands/knowledge.js.map +1 -0
- package/dist/commands/lessons.d.ts +11 -0
- package/dist/commands/lessons.js +129 -0
- package/dist/commands/lessons.js.map +1 -0
- package/dist/commands/pairing.d.ts +14 -0
- package/dist/commands/pairing.js +132 -0
- package/dist/commands/pairing.js.map +1 -0
- package/dist/commands/research/index.d.ts +13 -0
- package/dist/commands/research/index.js +91 -0
- package/dist/commands/research/index.js.map +1 -0
- package/dist/commands/run-cli/index.d.ts +11 -0
- package/dist/commands/run-cli/index.js +49 -0
- package/dist/commands/run-cli/index.js.map +1 -0
- package/dist/commands/todos.d.ts +9 -0
- package/dist/commands/todos.js +119 -0
- package/dist/commands/todos.js.map +1 -0
- package/dist/config/toml-config.d.ts +21 -0
- package/dist/config/toml-config.js +15 -0
- package/dist/config/toml-config.js.map +1 -1
- package/dist/context/enhanced-compression.js +12 -1
- package/dist/context/enhanced-compression.js.map +1 -1
- package/dist/context/observation-variator.d.ts +44 -0
- package/dist/context/observation-variator.js +83 -0
- package/dist/context/observation-variator.js.map +1 -0
- package/dist/context/precompaction-flush.d.ts +40 -0
- package/dist/context/precompaction-flush.js +134 -0
- package/dist/context/precompaction-flush.js.map +1 -0
- package/dist/context/restorable-compression.d.ts +80 -0
- package/dist/context/restorable-compression.js +228 -0
- package/dist/context/restorable-compression.js.map +1 -0
- package/dist/daemon/daily-reset.d.ts +77 -0
- package/dist/daemon/daily-reset.js +175 -0
- package/dist/daemon/daily-reset.js.map +1 -0
- package/dist/daemon/index.d.ts +1 -0
- package/dist/daemon/index.js +1 -0
- package/dist/daemon/index.js.map +1 -1
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -1
- package/dist/knowledge/knowledge-manager.d.ts +77 -0
- package/dist/knowledge/knowledge-manager.js +244 -0
- package/dist/knowledge/knowledge-manager.js.map +1 -0
- package/dist/observability/run-store.d.ts +133 -0
- package/dist/observability/run-store.js +419 -0
- package/dist/observability/run-store.js.map +1 -0
- package/dist/observability/run-viewer.d.ts +33 -0
- package/dist/observability/run-viewer.js +254 -0
- package/dist/observability/run-viewer.js.map +1 -0
- package/dist/optimization/cache-breakpoints.d.ts +52 -0
- package/dist/optimization/cache-breakpoints.js +97 -0
- package/dist/optimization/cache-breakpoints.js.map +1 -0
- package/dist/persistence/session-store.d.ts +3 -1
- package/dist/persistence/session-store.js +1 -1
- package/dist/persistence/session-store.js.map +1 -1
- package/dist/prompts/system-base.js +51 -7
- package/dist/prompts/system-base.js.map +1 -1
- package/dist/prompts/variation-injector.d.ts +55 -0
- package/dist/prompts/variation-injector.js +171 -0
- package/dist/prompts/variation-injector.js.map +1 -0
- package/dist/prompts/workflow-rules.d.ts +10 -0
- package/dist/prompts/workflow-rules.js +79 -0
- package/dist/prompts/workflow-rules.js.map +1 -0
- package/dist/sandbox/execpolicy.d.ts +45 -0
- package/dist/sandbox/execpolicy.js +80 -0
- package/dist/sandbox/execpolicy.js.map +1 -1
- package/dist/sandbox/os-sandbox.d.ts +25 -0
- package/dist/sandbox/os-sandbox.js +73 -0
- package/dist/sandbox/os-sandbox.js.map +1 -1
- package/dist/security/security-audit.d.ts +10 -0
- package/dist/security/security-audit.js +116 -0
- package/dist/security/security-audit.js.map +1 -1
- package/dist/security/shell-env-policy.d.ts +45 -0
- package/dist/security/shell-env-policy.js +141 -0
- package/dist/security/shell-env-policy.js.map +1 -0
- package/dist/security/ssrf-guard.d.ts +61 -0
- package/dist/security/ssrf-guard.js +382 -0
- package/dist/security/ssrf-guard.js.map +1 -0
- package/dist/security/write-policy.d.ts +57 -0
- package/dist/security/write-policy.js +117 -0
- package/dist/security/write-policy.js.map +1 -0
- package/dist/services/prompt-builder.js +37 -0
- package/dist/services/prompt-builder.js.map +1 -1
- package/dist/themes/theme-schema.d.ts +10 -10
- package/dist/tools/ask-human-tool.d.ts +62 -0
- package/dist/tools/ask-human-tool.js +112 -0
- package/dist/tools/ask-human-tool.js.map +1 -0
- package/dist/tools/bash/bash-tool.d.ts +15 -0
- package/dist/tools/bash/bash-tool.js +62 -0
- package/dist/tools/bash/bash-tool.js.map +1 -1
- package/dist/tools/bash/command-validator.d.ts +1 -0
- package/dist/tools/bash/command-validator.js +5 -0
- package/dist/tools/bash/command-validator.js.map +1 -1
- package/dist/tools/create-skill-tool.d.ts +87 -0
- package/dist/tools/create-skill-tool.js +142 -0
- package/dist/tools/create-skill-tool.js.map +1 -0
- package/dist/tools/fetch-tool.js +5 -3
- package/dist/tools/fetch-tool.js.map +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.js +1 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/plan-tool.d.ts +22 -0
- package/dist/tools/plan-tool.js +128 -0
- package/dist/tools/plan-tool.js.map +1 -0
- package/dist/tools/registry/attention-tools.d.ts +32 -0
- package/dist/tools/registry/attention-tools.js +225 -0
- package/dist/tools/registry/attention-tools.js.map +1 -0
- package/dist/tools/registry/index.d.ts +9 -1
- package/dist/tools/registry/index.js +30 -2
- package/dist/tools/registry/index.js.map +1 -1
- package/dist/tools/registry/knowledge-tools.d.ts +46 -0
- package/dist/tools/registry/knowledge-tools.js +293 -0
- package/dist/tools/registry/knowledge-tools.js.map +1 -0
- package/dist/tools/registry/lessons-tools.d.ts +48 -0
- package/dist/tools/registry/lessons-tools.js +359 -0
- package/dist/tools/registry/lessons-tools.js.map +1 -0
- package/dist/tools/registry/plan-tools.d.ts +2 -0
- package/dist/tools/registry/plan-tools.js +7 -0
- package/dist/tools/registry/plan-tools.js.map +1 -0
- package/dist/tools/registry/script-tools.d.ts +2 -0
- package/dist/tools/registry/script-tools.js +7 -0
- package/dist/tools/registry/script-tools.js.map +1 -0
- package/dist/tools/registry/tool-aliases.d.ts +44 -0
- package/dist/tools/registry/tool-aliases.js +130 -0
- package/dist/tools/registry/tool-aliases.js.map +1 -0
- package/dist/tools/run-script-tool.d.ts +13 -0
- package/dist/tools/run-script-tool.js +146 -0
- package/dist/tools/run-script-tool.js.map +1 -0
- package/dist/tools/web-search.d.ts +25 -0
- package/dist/tools/web-search.js +68 -6
- package/dist/tools/web-search.js.map +1 -1
- package/dist/utils/config-validation/schema.d.ts +2 -2
- package/dist/utils/debug-logger.d.ts +1 -1
- package/dist/utils/stable-json.d.ts +27 -0
- package/dist/utils/stable-json.js +50 -0
- package/dist/utils/stable-json.js.map +1 -0
- package/dist/webhooks/webhook-manager.d.ts +7 -0
- package/dist/webhooks/webhook-manager.js +29 -0
- package/dist/webhooks/webhook-manager.js.map +1 -1
- 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;
|