@viraatdas/rudder 2.10.21 → 2.10.23
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 +42 -0
- package/dist/improve/advisor.d.ts +10 -0
- package/dist/improve/advisor.js +115 -0
- package/dist/improve/advisor.js.map +1 -0
- package/dist/improve/collect.d.ts +10 -0
- package/dist/improve/collect.js +202 -0
- package/dist/improve/collect.js.map +1 -0
- package/dist/improve/gate.d.ts +17 -0
- package/dist/improve/gate.js +60 -0
- package/dist/improve/gate.js.map +1 -0
- package/dist/improve/index.d.ts +9 -0
- package/dist/improve/index.js +336 -0
- package/dist/improve/index.js.map +1 -0
- package/dist/improve/judge.d.ts +22 -0
- package/dist/improve/judge.js +101 -0
- package/dist/improve/judge.js.map +1 -0
- package/dist/improve/mine.d.ts +25 -0
- package/dist/improve/mine.js +173 -0
- package/dist/improve/mine.js.map +1 -0
- package/dist/improve/propose.d.ts +51 -0
- package/dist/improve/propose.js +150 -0
- package/dist/improve/propose.js.map +1 -0
- package/dist/improve/rank.d.ts +16 -0
- package/dist/improve/rank.js +49 -0
- package/dist/improve/rank.js.map +1 -0
- package/dist/improve/schedule.d.ts +1 -0
- package/dist/improve/schedule.js +93 -0
- package/dist/improve/schedule.js.map +1 -0
- package/dist/improve/ship.d.ts +25 -0
- package/dist/improve/ship.js +82 -0
- package/dist/improve/ship.js.map +1 -0
- package/dist/improve/state.d.ts +149 -0
- package/dist/improve/state.js +261 -0
- package/dist/improve/state.js.map +1 -0
- package/dist/main.js +11 -0
- package/dist/main.js.map +1 -1
- package/dist/native/darwin-arm64/rudder-native +0 -0
- package/dist/native/darwin-x64/rudder-native +0 -0
- package/dist/native/linux-x64/rudder-native +0 -0
- package/dist/state.js +2 -0
- package/dist/state.js.map +1 -1
- package/dist/task-summary.d.ts +6 -0
- package/dist/task-summary.js +6 -1
- package/dist/task-summary.js.map +1 -1
- package/dist/types.d.ts +16 -0
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { runCommand } from "../util.js";
|
|
2
|
+
import { execStep, tail } from "./state.js";
|
|
3
|
+
const MINUTE = 60 * 1000;
|
|
4
|
+
/**
|
|
5
|
+
* Ship a judged proposal. In `ship` autonomy this follows the repo release
|
|
6
|
+
* rule end to end: rebase onto the latest origin/main, re-typecheck, `npm
|
|
7
|
+
* version patch` (commit + tag vX.Y.Z), and push commit + tag together so the
|
|
8
|
+
* tag-driven release workflow publishes to npm. Non-force push: if main moved
|
|
9
|
+
* between the rebase and the push, this fails cleanly and is recorded as a
|
|
10
|
+
* push-conflict for the next cycle. In `propose` autonomy only the branch is
|
|
11
|
+
* pushed for human review.
|
|
12
|
+
*/
|
|
13
|
+
export async function shipProposal(params) {
|
|
14
|
+
const { settings, proposal } = params;
|
|
15
|
+
const cwd = proposal.worktree;
|
|
16
|
+
await assertAllowedRemote(settings);
|
|
17
|
+
if (settings.autonomy === "propose") {
|
|
18
|
+
const push = await runCommand("git", ["push", "-u", "origin", proposal.branch], {
|
|
19
|
+
cwd,
|
|
20
|
+
allowFailure: true,
|
|
21
|
+
});
|
|
22
|
+
if (push.code !== 0) {
|
|
23
|
+
return { status: "push-conflict", detail: tail(push.stderr || push.stdout, 800) };
|
|
24
|
+
}
|
|
25
|
+
return { status: "branch-pushed", branch: proposal.branch };
|
|
26
|
+
}
|
|
27
|
+
// Rebase onto the freshest main so the version bump reads the latest
|
|
28
|
+
// package.json (two winners in one cycle ship sequentially through here).
|
|
29
|
+
const fetch = await runCommand("git", ["fetch", "origin", "main"], { cwd, allowFailure: true });
|
|
30
|
+
if (fetch.code !== 0) {
|
|
31
|
+
return { status: "push-conflict", detail: `fetch failed: ${tail(fetch.stderr, 400)}` };
|
|
32
|
+
}
|
|
33
|
+
const rebase = await runCommand("git", ["rebase", "origin/main"], { cwd, allowFailure: true });
|
|
34
|
+
if (rebase.code !== 0) {
|
|
35
|
+
await runCommand("git", ["rebase", "--abort"], { cwd, allowFailure: true });
|
|
36
|
+
return { status: "push-conflict", detail: `rebase onto origin/main failed: ${tail(rebase.stderr, 800)}` };
|
|
37
|
+
}
|
|
38
|
+
// Cheap re-gate after the rebase; the full suites already passed pre-judge.
|
|
39
|
+
const recheck = await execStep({
|
|
40
|
+
command: "npm",
|
|
41
|
+
args: ["run", "check"],
|
|
42
|
+
cwd,
|
|
43
|
+
timeoutMs: 10 * MINUTE,
|
|
44
|
+
});
|
|
45
|
+
if (recheck.code !== 0) {
|
|
46
|
+
return { status: "push-conflict", detail: `post-rebase typecheck failed: ${tail(recheck.output, 800)}` };
|
|
47
|
+
}
|
|
48
|
+
const version = await runCommand("npm", ["version", "patch", "-m", `improve: ${proposal.finding.title} (v%s)`], { cwd, allowFailure: true });
|
|
49
|
+
if (version.code !== 0) {
|
|
50
|
+
return { status: "push-conflict", detail: `npm version patch failed: ${tail(version.stderr || version.stdout, 800)}` };
|
|
51
|
+
}
|
|
52
|
+
const tag = version.stdout.trim().split("\n").at(-1)?.trim() ?? "";
|
|
53
|
+
if (!/^v\d+\.\d+\.\d+$/.test(tag)) {
|
|
54
|
+
return { status: "push-conflict", detail: `unexpected npm version output: ${tail(version.stdout, 200)}` };
|
|
55
|
+
}
|
|
56
|
+
const push = await runCommand("git", ["push", "origin", `HEAD:main`, `refs/tags/${tag}`], {
|
|
57
|
+
cwd,
|
|
58
|
+
allowFailure: true,
|
|
59
|
+
});
|
|
60
|
+
if (push.code !== 0) {
|
|
61
|
+
// Undo the local tag so a retry next cycle does not collide with it.
|
|
62
|
+
await runCommand("git", ["tag", "-d", tag], { cwd, allowFailure: true });
|
|
63
|
+
return { status: "push-conflict", detail: `push failed: ${tail(push.stderr || push.stdout, 800)}` };
|
|
64
|
+
}
|
|
65
|
+
return { status: "shipped", version: tag };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The ship stage refuses to push anywhere but the configured rudder remote.
|
|
69
|
+
* This is the guard that keeps an unattended loop from ever pushing another
|
|
70
|
+
* project.
|
|
71
|
+
*/
|
|
72
|
+
async function assertAllowedRemote(settings) {
|
|
73
|
+
const remote = await runCommand("git", ["remote", "get-url", "origin"], {
|
|
74
|
+
cwd: settings.repoPath,
|
|
75
|
+
allowFailure: true,
|
|
76
|
+
});
|
|
77
|
+
const url = remote.stdout.trim();
|
|
78
|
+
if (remote.code !== 0 || !url.includes(settings.allowedRemote)) {
|
|
79
|
+
throw new Error(`refusing to ship: origin (${url || "missing"}) does not match improve.allowedRemote (${settings.allowedRemote})`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=ship.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ship.js","sourceRoot":"","sources":["../../src/improve/ship.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import type { RudderConfig } from "../types.js";
|
|
2
|
+
export declare function improveHome(): string;
|
|
3
|
+
export declare function watermarkPath(): string;
|
|
4
|
+
export declare function metricsPath(): string;
|
|
5
|
+
export declare function ledgerPath(): string;
|
|
6
|
+
export declare function reportsDir(): string;
|
|
7
|
+
export declare function logsDir(): string;
|
|
8
|
+
export declare function worktreesDir(): string;
|
|
9
|
+
export declare function cycleLockDir(): string;
|
|
10
|
+
export type ImproveAutonomy = "observe" | "propose" | "ship";
|
|
11
|
+
export type ImproveSettings = {
|
|
12
|
+
enabled: boolean;
|
|
13
|
+
autonomy: ImproveAutonomy;
|
|
14
|
+
budgetUsd: number;
|
|
15
|
+
maxFindings: number;
|
|
16
|
+
/** The rudder checkout the loop improves. */
|
|
17
|
+
repoPath: string;
|
|
18
|
+
/** Remote slug guard: ship only when `origin` matches. */
|
|
19
|
+
allowedRemote: string;
|
|
20
|
+
excludeProjects: string[];
|
|
21
|
+
minerModel: string;
|
|
22
|
+
judgeModel: string;
|
|
23
|
+
/**
|
|
24
|
+
* Advisor tool model for mining/judging calls (Anthropic advisor pattern:
|
|
25
|
+
* cheap executor + high-intelligence advisor). Empty string disables.
|
|
26
|
+
*/
|
|
27
|
+
advisorModel: string;
|
|
28
|
+
/** Model passed to the improvement agent CLI; empty = CLI default. */
|
|
29
|
+
workerModel: string;
|
|
30
|
+
agentTimeoutMs: number;
|
|
31
|
+
};
|
|
32
|
+
export declare const IMPROVE_DEFAULTS: {
|
|
33
|
+
autonomy: ImproveAutonomy;
|
|
34
|
+
budgetUsd: number;
|
|
35
|
+
maxFindings: number;
|
|
36
|
+
allowedRemote: string;
|
|
37
|
+
minerModel: string;
|
|
38
|
+
judgeModel: string;
|
|
39
|
+
advisorModel: string;
|
|
40
|
+
agentTimeoutMs: number;
|
|
41
|
+
};
|
|
42
|
+
export declare function resolveImproveSettings(config: RudderConfig, repoFallback: string): ImproveSettings;
|
|
43
|
+
export type SessionRecord = {
|
|
44
|
+
project: string;
|
|
45
|
+
repoRoot: string;
|
|
46
|
+
runId: string;
|
|
47
|
+
task: string;
|
|
48
|
+
backend: string;
|
|
49
|
+
model?: string;
|
|
50
|
+
effort?: string;
|
|
51
|
+
status: string;
|
|
52
|
+
createdAt: string;
|
|
53
|
+
updatedAt: string;
|
|
54
|
+
durationMs?: number;
|
|
55
|
+
steerCount: number;
|
|
56
|
+
autoSteerCount: number;
|
|
57
|
+
tokensIn: number;
|
|
58
|
+
tokensOut: number;
|
|
59
|
+
verifierSatisfied?: boolean;
|
|
60
|
+
verifierMissing?: string[];
|
|
61
|
+
mergeStatus?: string;
|
|
62
|
+
errorExcerpts: string[];
|
|
63
|
+
};
|
|
64
|
+
export type MetricsSnapshot = {
|
|
65
|
+
ts: string;
|
|
66
|
+
cycleId: string;
|
|
67
|
+
runsSeen: number;
|
|
68
|
+
failedRate: number;
|
|
69
|
+
cancelledRate: number;
|
|
70
|
+
steerRate: number;
|
|
71
|
+
mergeConflictRate: number;
|
|
72
|
+
verifierMissRate: number;
|
|
73
|
+
medianDurationMs: number;
|
|
74
|
+
totalTokensIn: number;
|
|
75
|
+
totalTokensOut: number;
|
|
76
|
+
};
|
|
77
|
+
export type FindingClass = "prompt" | "orchestration" | "ux" | "perf" | "crash" | "other";
|
|
78
|
+
export type Finding = {
|
|
79
|
+
id: string;
|
|
80
|
+
class: FindingClass;
|
|
81
|
+
title: string;
|
|
82
|
+
detail: string;
|
|
83
|
+
evidence: Array<{
|
|
84
|
+
project: string;
|
|
85
|
+
runId: string;
|
|
86
|
+
excerpt: string;
|
|
87
|
+
}>;
|
|
88
|
+
severity: number;
|
|
89
|
+
frequency: number;
|
|
90
|
+
suspectedSurfaces: string[];
|
|
91
|
+
score?: number;
|
|
92
|
+
};
|
|
93
|
+
export type LedgerStatus = "reported" | "banked" | "agent-failed" | "gated-out" | "judge-rejected" | "branch-pushed" | "push-conflict" | "shipped" | "outcome";
|
|
94
|
+
export type LedgerEntry = {
|
|
95
|
+
ts: string;
|
|
96
|
+
cycleId: string;
|
|
97
|
+
findingId: string;
|
|
98
|
+
titleKey: string;
|
|
99
|
+
title: string;
|
|
100
|
+
class: string;
|
|
101
|
+
status: LedgerStatus;
|
|
102
|
+
detail?: string;
|
|
103
|
+
version?: string;
|
|
104
|
+
branch?: string;
|
|
105
|
+
targetMetric?: string;
|
|
106
|
+
metricAtShip?: number;
|
|
107
|
+
outcome?: "confirmed" | "no-effect" | "regressed";
|
|
108
|
+
};
|
|
109
|
+
export declare function titleKey(title: string): string;
|
|
110
|
+
export declare function appendJsonl(filePath: string, value: unknown): Promise<void>;
|
|
111
|
+
export declare function readJsonl<T>(filePath: string): Promise<T[]>;
|
|
112
|
+
export type Watermark = {
|
|
113
|
+
version: 1;
|
|
114
|
+
projects: Record<string, string>;
|
|
115
|
+
};
|
|
116
|
+
export declare function loadWatermark(): Promise<Watermark>;
|
|
117
|
+
export declare function saveWatermark(mark: Watermark): Promise<void>;
|
|
118
|
+
export declare function acquireCycleLock(): Promise<boolean>;
|
|
119
|
+
export declare function releaseCycleLock(): Promise<void>;
|
|
120
|
+
export declare const AGENT_RUN_FLAT_USD = 0.75;
|
|
121
|
+
export declare class SpendMeter {
|
|
122
|
+
private readonly budgetUsd;
|
|
123
|
+
private spent;
|
|
124
|
+
constructor(budgetUsd: number);
|
|
125
|
+
addModelCall(model: string, inChars: number, outChars: number): void;
|
|
126
|
+
/** Exact token accounting (used when the API reports usage.iterations). */
|
|
127
|
+
addModelTokens(model: string, inputTokens: number, outputTokens: number): void;
|
|
128
|
+
addFlat(usd: number): void;
|
|
129
|
+
spentUsd(): number;
|
|
130
|
+
remainingUsd(): number;
|
|
131
|
+
/** True when there is room for at least `usd` more estimated spend. */
|
|
132
|
+
canAfford(usd: number): boolean;
|
|
133
|
+
}
|
|
134
|
+
export type StepResult = {
|
|
135
|
+
code: number;
|
|
136
|
+
timedOut: boolean;
|
|
137
|
+
output: string;
|
|
138
|
+
};
|
|
139
|
+
export declare function execStep(params: {
|
|
140
|
+
command: string;
|
|
141
|
+
args: string[];
|
|
142
|
+
cwd: string;
|
|
143
|
+
timeoutMs: number;
|
|
144
|
+
stdin?: string;
|
|
145
|
+
env?: NodeJS.ProcessEnv;
|
|
146
|
+
logFile?: string;
|
|
147
|
+
}): Promise<StepResult>;
|
|
148
|
+
export declare function tail(text: string, maxChars: number): string;
|
|
149
|
+
export declare function fileExists(filePath: string): Promise<boolean>;
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { promises as fs } from "node:fs";
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
import { commandEnv, ensureDir, pathExists, readJson, rudderHome, writeJson } from "../util.js";
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// The continual improvement loop's on-disk state lives under ~/.rudder/improve.
|
|
7
|
+
// Everything here is append-only JSONL or atomic JSON via writeJson, matching
|
|
8
|
+
// the repo persistence conventions. See docs/continual-improvement.md.
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
export function improveHome() {
|
|
11
|
+
return path.join(rudderHome(), "improve");
|
|
12
|
+
}
|
|
13
|
+
export function watermarkPath() {
|
|
14
|
+
return path.join(improveHome(), "watermark.json");
|
|
15
|
+
}
|
|
16
|
+
export function metricsPath() {
|
|
17
|
+
return path.join(improveHome(), "metrics.jsonl");
|
|
18
|
+
}
|
|
19
|
+
export function ledgerPath() {
|
|
20
|
+
return path.join(improveHome(), "ledger.jsonl");
|
|
21
|
+
}
|
|
22
|
+
export function reportsDir() {
|
|
23
|
+
return path.join(improveHome(), "reports");
|
|
24
|
+
}
|
|
25
|
+
export function logsDir() {
|
|
26
|
+
return path.join(improveHome(), "logs");
|
|
27
|
+
}
|
|
28
|
+
export function worktreesDir() {
|
|
29
|
+
return path.join(improveHome(), "worktrees");
|
|
30
|
+
}
|
|
31
|
+
export function cycleLockDir() {
|
|
32
|
+
return path.join(improveHome(), "cycle.lock");
|
|
33
|
+
}
|
|
34
|
+
export const IMPROVE_DEFAULTS = {
|
|
35
|
+
autonomy: "ship",
|
|
36
|
+
budgetUsd: 5,
|
|
37
|
+
maxFindings: 3,
|
|
38
|
+
allowedRemote: "viraatdas/rudder",
|
|
39
|
+
minerModel: "claude-sonnet-4-6",
|
|
40
|
+
judgeModel: "claude-sonnet-4-6",
|
|
41
|
+
advisorModel: "claude-fable-5",
|
|
42
|
+
agentTimeoutMs: 25 * 60 * 1000,
|
|
43
|
+
};
|
|
44
|
+
export function resolveImproveSettings(config, repoFallback) {
|
|
45
|
+
const raw = config.improve ?? {};
|
|
46
|
+
const envDisabled = process.env.RUDDER_IMPROVE === "0";
|
|
47
|
+
return {
|
|
48
|
+
enabled: !envDisabled && raw.enabled !== false,
|
|
49
|
+
autonomy: raw.autonomy ?? IMPROVE_DEFAULTS.autonomy,
|
|
50
|
+
budgetUsd: raw.budgetUsd ?? IMPROVE_DEFAULTS.budgetUsd,
|
|
51
|
+
maxFindings: raw.maxFindings ?? IMPROVE_DEFAULTS.maxFindings,
|
|
52
|
+
repoPath: raw.repoPath ?? repoFallback,
|
|
53
|
+
allowedRemote: raw.allowedRemote ?? IMPROVE_DEFAULTS.allowedRemote,
|
|
54
|
+
excludeProjects: raw.excludeProjects ?? [],
|
|
55
|
+
minerModel: raw.minerModel ?? IMPROVE_DEFAULTS.minerModel,
|
|
56
|
+
judgeModel: raw.judgeModel ?? IMPROVE_DEFAULTS.judgeModel,
|
|
57
|
+
advisorModel: raw.advisorModel ?? IMPROVE_DEFAULTS.advisorModel,
|
|
58
|
+
workerModel: raw.workerModel ?? "",
|
|
59
|
+
agentTimeoutMs: raw.agentTimeoutMs ?? IMPROVE_DEFAULTS.agentTimeoutMs,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export function titleKey(title) {
|
|
63
|
+
return title
|
|
64
|
+
.toLowerCase()
|
|
65
|
+
.replace(/[^a-z0-9 ]+/g, "")
|
|
66
|
+
.split(/\s+/)
|
|
67
|
+
.filter(Boolean)
|
|
68
|
+
.slice(0, 8)
|
|
69
|
+
.join("-");
|
|
70
|
+
}
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
// JSONL helpers
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
export async function appendJsonl(filePath, value) {
|
|
75
|
+
await ensureDir(path.dirname(filePath));
|
|
76
|
+
await fs.appendFile(filePath, `${JSON.stringify(value)}\n`, "utf8");
|
|
77
|
+
}
|
|
78
|
+
export async function readJsonl(filePath) {
|
|
79
|
+
try {
|
|
80
|
+
const raw = await fs.readFile(filePath, "utf8");
|
|
81
|
+
const out = [];
|
|
82
|
+
for (const line of raw.split("\n")) {
|
|
83
|
+
const trimmed = line.trim();
|
|
84
|
+
if (!trimmed)
|
|
85
|
+
continue;
|
|
86
|
+
try {
|
|
87
|
+
out.push(JSON.parse(trimmed));
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// skip torn/corrupt lines; the files are append-only diagnostics
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return out;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export async function loadWatermark() {
|
|
100
|
+
const existing = await readJson(watermarkPath());
|
|
101
|
+
if (existing?.version === 1 && existing.projects) {
|
|
102
|
+
return existing;
|
|
103
|
+
}
|
|
104
|
+
return { version: 1, projects: {} };
|
|
105
|
+
}
|
|
106
|
+
export async function saveWatermark(mark) {
|
|
107
|
+
await ensureDir(improveHome());
|
|
108
|
+
await writeJson(watermarkPath(), mark);
|
|
109
|
+
}
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
// Single-instance cycle lock (mkdir lock, stale takeover), the same shape as
|
|
112
|
+
// .rudder/integrate.lock. Not reentrant.
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
const LOCK_STALE_MS = 6 * 60 * 60 * 1000;
|
|
115
|
+
export async function acquireCycleLock() {
|
|
116
|
+
await ensureDir(improveHome());
|
|
117
|
+
const lock = cycleLockDir();
|
|
118
|
+
try {
|
|
119
|
+
await fs.mkdir(lock);
|
|
120
|
+
await fs.writeFile(path.join(lock, "pid"), String(process.pid), "utf8");
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
try {
|
|
125
|
+
const stat = await fs.stat(lock);
|
|
126
|
+
if (Date.now() - stat.mtimeMs > LOCK_STALE_MS) {
|
|
127
|
+
await fs.rm(lock, { recursive: true, force: true });
|
|
128
|
+
await fs.mkdir(lock);
|
|
129
|
+
await fs.writeFile(path.join(lock, "pid"), String(process.pid), "utf8");
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// fall through: someone else holds it
|
|
135
|
+
}
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
export async function releaseCycleLock() {
|
|
140
|
+
await fs.rm(cycleLockDir(), { recursive: true, force: true });
|
|
141
|
+
}
|
|
142
|
+
// ---------------------------------------------------------------------------
|
|
143
|
+
// Spend meter: a coarse budget guardrail, not accounting. Model calls are
|
|
144
|
+
// estimated at chars/4 tokens against a small price table; agent runs are a
|
|
145
|
+
// flat estimate because the CLI's own auth (subscription) hides real cost.
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
const PRICE_PER_MTOK = [
|
|
148
|
+
{ match: /haiku/i, inUsd: 1, outUsd: 5 },
|
|
149
|
+
{ match: /sonnet/i, inUsd: 3, outUsd: 15 },
|
|
150
|
+
{ match: /opus|fable/i, inUsd: 5, outUsd: 25 },
|
|
151
|
+
];
|
|
152
|
+
export const AGENT_RUN_FLAT_USD = 0.75;
|
|
153
|
+
export class SpendMeter {
|
|
154
|
+
budgetUsd;
|
|
155
|
+
spent = 0;
|
|
156
|
+
constructor(budgetUsd) {
|
|
157
|
+
this.budgetUsd = budgetUsd;
|
|
158
|
+
}
|
|
159
|
+
addModelCall(model, inChars, outChars) {
|
|
160
|
+
this.addModelTokens(model, inChars / 4, outChars / 4);
|
|
161
|
+
}
|
|
162
|
+
/** Exact token accounting (used when the API reports usage.iterations). */
|
|
163
|
+
addModelTokens(model, inputTokens, outputTokens) {
|
|
164
|
+
const price = PRICE_PER_MTOK.find((p) => p.match.test(model)) ?? PRICE_PER_MTOK[1];
|
|
165
|
+
this.spent += (inputTokens / 1_000_000) * price.inUsd + (outputTokens / 1_000_000) * price.outUsd;
|
|
166
|
+
}
|
|
167
|
+
addFlat(usd) {
|
|
168
|
+
this.spent += usd;
|
|
169
|
+
}
|
|
170
|
+
spentUsd() {
|
|
171
|
+
return this.spent;
|
|
172
|
+
}
|
|
173
|
+
remainingUsd() {
|
|
174
|
+
return Math.max(0, this.budgetUsd - this.spent);
|
|
175
|
+
}
|
|
176
|
+
/** True when there is room for at least `usd` more estimated spend. */
|
|
177
|
+
canAfford(usd) {
|
|
178
|
+
return this.spent + usd <= this.budgetUsd;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
export async function execStep(params) {
|
|
182
|
+
return await new Promise((resolve) => {
|
|
183
|
+
let settled = false;
|
|
184
|
+
let timedOut = false;
|
|
185
|
+
let output = "";
|
|
186
|
+
const finish = (code) => {
|
|
187
|
+
if (settled)
|
|
188
|
+
return;
|
|
189
|
+
settled = true;
|
|
190
|
+
if (params.logFile) {
|
|
191
|
+
void ensureDir(path.dirname(params.logFile)).then(() => fs.appendFile(params.logFile, `\n===== ${params.command} ${params.args.join(" ")} (exit ${code}${timedOut ? ", timed out" : ""}) =====\n${output}`, "utf8"));
|
|
192
|
+
}
|
|
193
|
+
resolve({ code, timedOut, output });
|
|
194
|
+
};
|
|
195
|
+
let child;
|
|
196
|
+
try {
|
|
197
|
+
child = spawn(params.command, params.args, {
|
|
198
|
+
cwd: params.cwd,
|
|
199
|
+
env: commandEnv(params.env),
|
|
200
|
+
stdio: [params.stdin === undefined ? "ignore" : "pipe", "pipe", "pipe"],
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
output = String(error);
|
|
205
|
+
finish(127);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const timer = setTimeout(() => {
|
|
209
|
+
timedOut = true;
|
|
210
|
+
try {
|
|
211
|
+
child.kill("SIGTERM");
|
|
212
|
+
setTimeout(() => {
|
|
213
|
+
try {
|
|
214
|
+
child.kill("SIGKILL");
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
// already gone
|
|
218
|
+
}
|
|
219
|
+
}, 5000).unref();
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
// already gone
|
|
223
|
+
}
|
|
224
|
+
}, params.timeoutMs);
|
|
225
|
+
child.stdout?.setEncoding("utf8");
|
|
226
|
+
child.stderr?.setEncoding("utf8");
|
|
227
|
+
child.stdout?.on("data", (chunk) => {
|
|
228
|
+
output += chunk;
|
|
229
|
+
});
|
|
230
|
+
child.stderr?.on("data", (chunk) => {
|
|
231
|
+
output += chunk;
|
|
232
|
+
});
|
|
233
|
+
child.on("error", (error) => {
|
|
234
|
+
clearTimeout(timer);
|
|
235
|
+
output += `\n${String(error)}`;
|
|
236
|
+
finish(127);
|
|
237
|
+
});
|
|
238
|
+
child.on("close", (code) => {
|
|
239
|
+
clearTimeout(timer);
|
|
240
|
+
finish(timedOut ? 124 : (code ?? 1));
|
|
241
|
+
});
|
|
242
|
+
if (params.stdin !== undefined) {
|
|
243
|
+
try {
|
|
244
|
+
child.stdin?.write(params.stdin);
|
|
245
|
+
child.stdin?.end();
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
// child error handler will fire
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
export function tail(text, maxChars) {
|
|
254
|
+
if (text.length <= maxChars)
|
|
255
|
+
return text;
|
|
256
|
+
return `…${text.slice(text.length - maxChars)}`;
|
|
257
|
+
}
|
|
258
|
+
export async function fileExists(filePath) {
|
|
259
|
+
return await pathExists(filePath);
|
|
260
|
+
}
|
|
261
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/improve/state.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGhG,8EAA8E;AAC9E,gFAAgF;AAChF,8EAA8E;AAC9E,uEAAuE;AACvE,8EAA8E;AAE9E,MAAM,UAAU,WAAW;IACzB,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,SAAS,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,gBAAgB,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,eAAe,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,cAAc,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,SAAS,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,WAAW,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,YAAY,CAAC,CAAC;AAChD,CAAC;AA8BD,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,QAAQ,EAAE,MAAyB;IACnC,SAAS,EAAE,CAAC;IACZ,WAAW,EAAE,CAAC;IACd,aAAa,EAAE,kBAAkB;IACjC,UAAU,EAAE,mBAAmB;IAC/B,UAAU,EAAE,mBAAmB;IAC/B,YAAY,EAAE,gBAAgB;IAC9B,cAAc,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;CAC/B,CAAC;AAEF,MAAM,UAAU,sBAAsB,CAAC,MAAoB,EAAE,YAAoB;IAC/E,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;IACjC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,GAAG,CAAC;IACvD,OAAO;QACL,OAAO,EAAE,CAAC,WAAW,IAAI,GAAG,CAAC,OAAO,KAAK,KAAK;QAC9C,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,gBAAgB,CAAC,QAAQ;QACnD,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,gBAAgB,CAAC,SAAS;QACtD,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,gBAAgB,CAAC,WAAW;QAC5D,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,YAAY;QACtC,aAAa,EAAE,GAAG,CAAC,aAAa,IAAI,gBAAgB,CAAC,aAAa;QAClE,eAAe,EAAE,GAAG,CAAC,eAAe,IAAI,EAAE;QAC1C,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,gBAAgB,CAAC,UAAU;QACzD,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,gBAAgB,CAAC,UAAU;QACzD,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,gBAAgB,CAAC,YAAY;QAC/D,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,EAAE;QAClC,cAAc,EAAE,GAAG,CAAC,cAAc,IAAI,gBAAgB,CAAC,cAAc;KACtE,CAAC;AACJ,CAAC;AA+ED,MAAM,UAAU,QAAQ,CAAC,KAAa;IACpC,OAAO,KAAK;SACT,WAAW,EAAE;SACb,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;SAC3B,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,OAAO,CAAC;SACf,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAgB,EAAE,KAAc;IAChE,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxC,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAI,QAAgB;IACjD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAChD,MAAM,GAAG,GAAQ,EAAE,CAAC;QACpB,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,CAAC,OAAO;gBAAE,SAAS;YACvB,IAAI,CAAC;gBACH,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAM,CAAC,CAAC;YACrC,CAAC;YAAC,MAAM,CAAC;gBACP,iEAAiE;YACnE,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAY,aAAa,EAAE,CAAC,CAAC;IAC5D,IAAI,QAAQ,EAAE,OAAO,KAAK,CAAC,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACjD,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AACtC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAe;IACjD,MAAM,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/B,MAAM,SAAS,CAAC,aAAa,EAAE,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,8EAA8E;AAC9E,6EAA6E;AAC7E,yCAAyC;AACzC,8EAA8E;AAE9E,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACrB,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QACxE,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,GAAG,aAAa,EAAE,CAAC;gBAC9C,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpD,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACrB,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;gBACxE,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,sCAAsC;QACxC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,EAAE,CAAC,EAAE,CAAC,YAAY,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAChE,CAAC;AAED,8EAA8E;AAC9E,0EAA0E;AAC1E,4EAA4E;AAC5E,2EAA2E;AAC3E,8EAA8E;AAE9E,MAAM,cAAc,GAA4D;IAC9E,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;IACxC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;IAC1C,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;CAC/C,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEvC,MAAM,OAAO,UAAU;IAEQ;IADrB,KAAK,GAAG,CAAC,CAAC;IAClB,YAA6B,SAAiB;QAAjB,cAAS,GAAT,SAAS,CAAQ;IAAG,CAAC;IAElD,YAAY,CAAC,KAAa,EAAE,OAAe,EAAE,QAAgB;QAC3D,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,2EAA2E;IAC3E,cAAc,CAAC,KAAa,EAAE,WAAmB,EAAE,YAAoB;QACrE,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC;QACnF,IAAI,CAAC,KAAK,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,YAAY,GAAG,SAAS,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;IACpG,CAAC;IAED,OAAO,CAAC,GAAW;QACjB,IAAI,CAAC,KAAK,IAAI,GAAG,CAAC;IACpB,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC;IAED,uEAAuE;IACvE,SAAS,CAAC,GAAW;QACnB,OAAO,IAAI,CAAC,KAAK,GAAG,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC;IAC5C,CAAC;CACF;AASD,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,MAQ9B;IACC,OAAO,MAAM,IAAI,OAAO,CAAa,CAAC,OAAO,EAAE,EAAE;QAC/C,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE;YAC9B,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,KAAK,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CACrD,EAAE,CAAC,UAAU,CACX,MAAM,CAAC,OAAiB,EACxB,WAAW,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,YAAY,MAAM,EAAE,EACpH,MAAM,CACP,CACF,CAAC;YACJ,CAAC;YACD,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QACtC,CAAC,CAAC;QACF,IAAI,KAAK,CAAC;QACV,IAAI,CAAC;YACH,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE;gBACzC,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC;gBAC3B,KAAK,EAAE,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;aACxE,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YACvB,MAAM,CAAC,GAAG,CAAC,CAAC;YACZ,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,QAAQ,GAAG,IAAI,CAAC;YAChB,IAAI,CAAC;gBACH,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACtB,UAAU,CAAC,GAAG,EAAE;oBACd,IAAI,CAAC;wBACH,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBACxB,CAAC;oBAAC,MAAM,CAAC;wBACP,eAAe;oBACjB,CAAC;gBACH,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YACnB,CAAC;YAAC,MAAM,CAAC;gBACP,eAAe;YACjB,CAAC;QACH,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QACrB,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QAClC,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QAClC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACzC,MAAM,IAAI,KAAK,CAAC;QAClB,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACzC,MAAM,IAAI,KAAK,CAAC;QAClB,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC1B,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,IAAI,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QACH,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACjC,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC;YACrB,CAAC;YAAC,MAAM,CAAC;gBACP,gCAAgC;YAClC,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,IAAY,EAAE,QAAgB;IACjD,IAAI,IAAI,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO,IAAI,CAAC;IACzC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,OAAO,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;AACpC,CAAC"}
|
package/dist/main.js
CHANGED
|
@@ -236,6 +236,11 @@ export async function main() {
|
|
|
236
236
|
case "gc":
|
|
237
237
|
await runGc({ dryRun: Boolean(parsed.flags.dryRun) });
|
|
238
238
|
return;
|
|
239
|
+
case "improve": {
|
|
240
|
+
const { runImprove } = await import("./improve/index.js");
|
|
241
|
+
await runImprove(parsed);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
239
244
|
case "board":
|
|
240
245
|
case "serve": {
|
|
241
246
|
await runBoard(parsed);
|
|
@@ -924,6 +929,12 @@ Run management:
|
|
|
924
929
|
rudder gc [--dry-run] Prune bounded diagnostics, old binaries, and stale run records
|
|
925
930
|
rudder undo [opId] Rewind jj to an op id, or the last undo-stack entry (global)
|
|
926
931
|
|
|
932
|
+
Improvement loop:
|
|
933
|
+
rudder improve run [--dry-run] [--budget-usd N] Mine telemetry, propose+judge fixes, ship a release
|
|
934
|
+
rudder improve status Last cycle, shipped versions, ledger tail
|
|
935
|
+
rudder improve report [date] Print a cycle report
|
|
936
|
+
rudder improve schedule install|uninstall|status Nightly launchd schedule (macOS)
|
|
937
|
+
|
|
927
938
|
Planner:
|
|
928
939
|
rudder plan "task" Decompose a task into a DAG, scaffold empty jj changes, write graph.json
|
|
929
940
|
rudder fanout "task" [--n N] Fan out N variant agents on one task, then a judge picks/merges the best (default N=3)
|