cruo-agent 0.1.7 → 0.1.9
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/dist/VERSION +1 -1
- package/dist/cli.js +231 -21
- package/package.json +1 -1
package/dist/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.1.
|
|
1
|
+
0.1.9
|
package/dist/cli.js
CHANGED
|
@@ -45913,6 +45913,36 @@ function isKnownCommandWord(first) {
|
|
|
45913
45913
|
function nearestCommands(first) {
|
|
45914
45914
|
return CRUO_COMMANDS.filter((k) => k[0] === first[0]).slice(0, 3);
|
|
45915
45915
|
}
|
|
45916
|
+
function editDistance(a, b) {
|
|
45917
|
+
const row = Array.from({ length: b.length + 1 }, (_, j) => j);
|
|
45918
|
+
for (let i = 1; i <= a.length; i++) {
|
|
45919
|
+
let diagonal = row[0];
|
|
45920
|
+
row[0] = i;
|
|
45921
|
+
for (let j = 1; j <= b.length; j++) {
|
|
45922
|
+
const above = row[j];
|
|
45923
|
+
row[j] = Math.min(row[j] + 1, row[j - 1] + 1, diagonal + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
45924
|
+
diagonal = above;
|
|
45925
|
+
}
|
|
45926
|
+
}
|
|
45927
|
+
return row[b.length];
|
|
45928
|
+
}
|
|
45929
|
+
function unknownFlags(argv2, valued = [...SUPERVISOR_VALUED, ...CLI_VALUED], switches = SUPERVISOR_SWITCHES) {
|
|
45930
|
+
const known = [...valued, ...switches];
|
|
45931
|
+
const found = [];
|
|
45932
|
+
for (let i = 0; i < argv2.length; i++) {
|
|
45933
|
+
const arg = argv2[i];
|
|
45934
|
+
if (!arg.startsWith("-")) continue;
|
|
45935
|
+
const name = arg.replace(/^-+/, "");
|
|
45936
|
+
if (valued.includes(name)) {
|
|
45937
|
+
i++;
|
|
45938
|
+
continue;
|
|
45939
|
+
}
|
|
45940
|
+
if (switches.includes(name)) continue;
|
|
45941
|
+
const ranked = known.map((k) => ({ k, d: editDistance(name.split("=")[0], k) })).sort((x, y) => x.d - y.d)[0];
|
|
45942
|
+
found.push({ flag: arg, nearest: ranked && ranked.d <= 2 ? `--${ranked.k}` : null });
|
|
45943
|
+
}
|
|
45944
|
+
return found;
|
|
45945
|
+
}
|
|
45916
45946
|
function numericIn(argv2, name, spec = {}) {
|
|
45917
45947
|
const i = argv2.indexOf(`--${name}`);
|
|
45918
45948
|
if (i < 0) return spec.fallback;
|
|
@@ -45947,7 +45977,7 @@ function requiredNumericIn(argv2, name, fallback, spec = {}) {
|
|
|
45947
45977
|
function secondsIn(argv2, name, fallbackSeconds) {
|
|
45948
45978
|
return requiredNumericIn(argv2, name, fallbackSeconds, { unit: "seconds" }) * 1e3;
|
|
45949
45979
|
}
|
|
45950
|
-
var CRUO_COMMANDS, OptionError, flagIn, optIn;
|
|
45980
|
+
var CRUO_COMMANDS, SUPERVISOR_SWITCHES, SUPERVISOR_VALUED, CLI_VALUED, OptionError, flagIn, optIn;
|
|
45951
45981
|
var init_options = __esm({
|
|
45952
45982
|
"src/options.ts"() {
|
|
45953
45983
|
"use strict";
|
|
@@ -45963,8 +45993,32 @@ var init_options = __esm({
|
|
|
45963
45993
|
"stop",
|
|
45964
45994
|
"pause",
|
|
45965
45995
|
"resume",
|
|
45966
|
-
"logs"
|
|
45996
|
+
"logs",
|
|
45997
|
+
"run",
|
|
45998
|
+
"version",
|
|
45999
|
+
"?"
|
|
45967
46000
|
];
|
|
46001
|
+
SUPERVISOR_SWITCHES = ["once", "dry-run", "worktree", "keep-failed", "push", "usage"];
|
|
46002
|
+
SUPERVISOR_VALUED = [
|
|
46003
|
+
"allow",
|
|
46004
|
+
"base",
|
|
46005
|
+
"cwd",
|
|
46006
|
+
"function",
|
|
46007
|
+
"harness",
|
|
46008
|
+
"harness-timeout",
|
|
46009
|
+
"interval",
|
|
46010
|
+
"limit",
|
|
46011
|
+
"max-attempts",
|
|
46012
|
+
"max-interval",
|
|
46013
|
+
"model",
|
|
46014
|
+
"prepare",
|
|
46015
|
+
"prepare-timeout",
|
|
46016
|
+
"project",
|
|
46017
|
+
"push-remote",
|
|
46018
|
+
"repo",
|
|
46019
|
+
"worktree-root"
|
|
46020
|
+
];
|
|
46021
|
+
CLI_VALUED = ["as", "token"];
|
|
45968
46022
|
OptionError = class extends Error {
|
|
45969
46023
|
constructor(message) {
|
|
45970
46024
|
super(message);
|
|
@@ -46228,7 +46282,12 @@ predate cost recording (\`CRA-89\`, 2026-08-29).
|
|
|
46228
46282
|
cacheRead: 0,
|
|
46229
46283
|
cacheWrite: 0,
|
|
46230
46284
|
cost: 0,
|
|
46231
|
-
measured: 0
|
|
46285
|
+
measured: 0,
|
|
46286
|
+
opening: 0,
|
|
46287
|
+
openingMeasured: 0,
|
|
46288
|
+
sysChars: 0,
|
|
46289
|
+
userChars: 0,
|
|
46290
|
+
charsMeasured: 0
|
|
46232
46291
|
});
|
|
46233
46292
|
const fold = (a, r) => {
|
|
46234
46293
|
a.runs += 1;
|
|
@@ -46242,6 +46301,16 @@ predate cost recording (\`CRA-89\`, 2026-08-29).
|
|
|
46242
46301
|
a.cacheWrite += n(r.cache_write_tokens);
|
|
46243
46302
|
a.cost += n(r.cost_usd);
|
|
46244
46303
|
if (r.input_tokens !== null || r.cost_usd !== null) a.measured += 1;
|
|
46304
|
+
const openingKnown = r.opening_context_input_tokens !== null || r.opening_context_cache_read_tokens !== null || r.opening_context_cache_write_tokens !== null;
|
|
46305
|
+
if (openingKnown) {
|
|
46306
|
+
a.opening += n(r.opening_context_input_tokens) + n(r.opening_context_cache_read_tokens) + n(r.opening_context_cache_write_tokens);
|
|
46307
|
+
a.openingMeasured += 1;
|
|
46308
|
+
}
|
|
46309
|
+
if (r.system_prompt_chars !== null || r.user_prompt_chars !== null) {
|
|
46310
|
+
a.sysChars += n(r.system_prompt_chars);
|
|
46311
|
+
a.userChars += n(r.user_prompt_chars);
|
|
46312
|
+
a.charsMeasured += 1;
|
|
46313
|
+
}
|
|
46245
46314
|
};
|
|
46246
46315
|
const byAgent = /* @__PURE__ */ new Map();
|
|
46247
46316
|
const total = blank();
|
|
@@ -46253,11 +46322,12 @@ predate cost recording (\`CRA-89\`, 2026-08-29).
|
|
|
46253
46322
|
const w = Math.max(12, ...[...byAgent.keys()].map((id) => nameOf(id).length));
|
|
46254
46323
|
console.log(
|
|
46255
46324
|
`
|
|
46256
|
-
${pad("agent", w)} ${rpad("runs", 5)} ${rpad("useful", 7)} ${rpad("dead", 5)} ${rpad("time", 7)} ${rpad("in", 8)} ${rpad("out", 8)} ${rpad("cost", 9)}`
|
|
46325
|
+
${pad("agent", w)} ${rpad("runs", 5)} ${rpad("useful", 7)} ${rpad("dead", 5)} ${rpad("time", 7)} ${rpad("in", 8)} ${rpad("out", 8)} ${rpad("opening", 8)} ${rpad("cost", 9)}`
|
|
46257
46326
|
);
|
|
46258
46327
|
for (const [id, a] of [...byAgent].sort((x, y) => y[1].runs - x[1].runs)) {
|
|
46328
|
+
const openingAvg = a.openingMeasured > 0 ? compact(Math.round(a.opening / a.openingMeasured)) : "\u2014";
|
|
46259
46329
|
console.log(
|
|
46260
|
-
` ${pad(nameOf(id), w)} ${rpad(String(a.runs), 5)} ${rpad(String(a.productive), 7)} ${rpad(String(a.neverRan), 5)} ${rpad(duration3(a.ms), 7)} ${rpad(compact(a.input + a.cacheRead), 8)} ${rpad(compact(a.output), 8)} ${rpad(a.cost > 0 ? `$${a.cost.toFixed(2)}` : "\u2014", 9)}`
|
|
46330
|
+
` ${pad(nameOf(id), w)} ${rpad(String(a.runs), 5)} ${rpad(String(a.productive), 7)} ${rpad(String(a.neverRan), 5)} ${rpad(duration3(a.ms), 7)} ${rpad(compact(a.input + a.cacheRead), 8)} ${rpad(compact(a.output), 8)} ${rpad(openingAvg, 8)} ${rpad(a.cost > 0 ? `$${a.cost.toFixed(2)}` : "\u2014", 9)}`
|
|
46261
46331
|
);
|
|
46262
46332
|
}
|
|
46263
46333
|
if (!opts.issue) {
|
|
@@ -46290,8 +46360,12 @@ predate cost recording (\`CRA-89\`, 2026-08-29).
|
|
|
46290
46360
|
console.log(`
|
|
46291
46361
|
run by run`);
|
|
46292
46362
|
for (const r of rows) {
|
|
46363
|
+
const openingKnown = r.opening_context_input_tokens !== null || r.opening_context_cache_read_tokens !== null || r.opening_context_cache_write_tokens !== null;
|
|
46364
|
+
const opening = openingKnown ? compact(
|
|
46365
|
+
n(r.opening_context_input_tokens) + n(r.opening_context_cache_read_tokens) + n(r.opening_context_cache_write_tokens)
|
|
46366
|
+
) : "\u2014";
|
|
46293
46367
|
console.log(
|
|
46294
|
-
` ${r.started_at.slice(0, 16).replace("T", " ")} ${pad(r.outcome, 13)} ${rpad(duration3(r.duration_ms), 6)} ${rpad(compact(n(r.output_tokens)), 7)} out ${nameOf(r.agent_id)}`
|
|
46368
|
+
` ${r.started_at.slice(0, 16).replace("T", " ")} ${pad(r.outcome, 13)} ${rpad(duration3(r.duration_ms), 6)} ${rpad(compact(n(r.output_tokens)), 7)} out ${rpad(opening, 7)} opening ${nameOf(r.agent_id)}`
|
|
46295
46369
|
);
|
|
46296
46370
|
}
|
|
46297
46371
|
}
|
|
@@ -46318,6 +46392,35 @@ predate cost recording (\`CRA-89\`, 2026-08-29).
|
|
|
46318
46392
|
} else {
|
|
46319
46393
|
console.log("");
|
|
46320
46394
|
}
|
|
46395
|
+
if (total.openingMeasured === 0) {
|
|
46396
|
+
console.log(
|
|
46397
|
+
` No opening-context figure: needs --usage AND a harness that reports
|
|
46398
|
+
per-turn usage on its own events, which is stricter than reporting a
|
|
46399
|
+
final total \u2014 some harnesses do the second and not the first.
|
|
46400
|
+
`
|
|
46401
|
+
);
|
|
46402
|
+
} else {
|
|
46403
|
+
const avg = Math.round(total.opening / total.openingMeasured);
|
|
46404
|
+
console.log(
|
|
46405
|
+
` opening context \u2014 what was loaded before any work happened, not a slice of "in":
|
|
46406
|
+
avg ${compact(avg)} tokens over ${total.openingMeasured} of ${total.runs} run(s) that reported a first turn.`
|
|
46407
|
+
);
|
|
46408
|
+
if (total.charsMeasured > 0) {
|
|
46409
|
+
const sysAvg = Math.round(total.sysChars / total.charsMeasured);
|
|
46410
|
+
const userAvg = Math.round(total.userChars / total.charsMeasured);
|
|
46411
|
+
console.log(
|
|
46412
|
+
` Known by source: the system prompt averaged ${sysAvg} chars, the user prompt
|
|
46413
|
+
${userAvg} \u2014 CHARACTERS, not tokens, because no tokenizer runs here, so this is
|
|
46414
|
+
not subtracted from the ${compact(avg)}-token figure above. The rest of the
|
|
46415
|
+
opening context \u2014 CLAUDE.md, the docs it points at, the card and its comments,
|
|
46416
|
+
and the MCP tool schemas \u2014 is read by the harness itself, off a filesystem and
|
|
46417
|
+
a tool list the supervisor cannot see, and is NOT broken down any further.
|
|
46418
|
+
`
|
|
46419
|
+
);
|
|
46420
|
+
} else {
|
|
46421
|
+
console.log("");
|
|
46422
|
+
}
|
|
46423
|
+
}
|
|
46321
46424
|
}
|
|
46322
46425
|
var n, pad, rpad, duration3;
|
|
46323
46426
|
var init_usage = __esm({
|
|
@@ -46371,6 +46474,29 @@ function usageIn(text) {
|
|
|
46371
46474
|
const measured = Object.values(out).some((v) => v !== void 0);
|
|
46372
46475
|
return measured ? out : null;
|
|
46373
46476
|
}
|
|
46477
|
+
function turnUsageIn(line) {
|
|
46478
|
+
let event;
|
|
46479
|
+
try {
|
|
46480
|
+
event = JSON.parse(line);
|
|
46481
|
+
} catch {
|
|
46482
|
+
return null;
|
|
46483
|
+
}
|
|
46484
|
+
if (typeof event !== "object" || event === null) return null;
|
|
46485
|
+
const e = event;
|
|
46486
|
+
if (e.type !== "assistant") return null;
|
|
46487
|
+
const message = e.message;
|
|
46488
|
+
const usage = message?.usage;
|
|
46489
|
+
if (!usage || typeof usage !== "object") return null;
|
|
46490
|
+
const out = {
|
|
46491
|
+
model: typeof message?.model === "string" ? message.model : void 0,
|
|
46492
|
+
inputTokens: num(usage.input_tokens) ?? num(usage.inputTokens),
|
|
46493
|
+
outputTokens: num(usage.output_tokens) ?? num(usage.outputTokens),
|
|
46494
|
+
cacheReadTokens: num(usage.cache_read_input_tokens) ?? num(usage.cacheReadInputTokens),
|
|
46495
|
+
cacheWriteTokens: num(usage.cache_creation_input_tokens) ?? num(usage.cacheCreationInputTokens)
|
|
46496
|
+
};
|
|
46497
|
+
const measured = Object.values(out).some((v) => v !== void 0);
|
|
46498
|
+
return measured ? out : null;
|
|
46499
|
+
}
|
|
46374
46500
|
function renderEvent(line) {
|
|
46375
46501
|
let event;
|
|
46376
46502
|
try {
|
|
@@ -46488,6 +46614,17 @@ var init_pacing = __esm({
|
|
|
46488
46614
|
}
|
|
46489
46615
|
});
|
|
46490
46616
|
|
|
46617
|
+
// src/queries.ts
|
|
46618
|
+
function blocksAgentPickup(state) {
|
|
46619
|
+
return state.requires_human === true;
|
|
46620
|
+
}
|
|
46621
|
+
var init_queries = __esm({
|
|
46622
|
+
"src/queries.ts"() {
|
|
46623
|
+
"use strict";
|
|
46624
|
+
init_dist();
|
|
46625
|
+
}
|
|
46626
|
+
});
|
|
46627
|
+
|
|
46491
46628
|
// src/worktree.ts
|
|
46492
46629
|
import { execFile as execFile2 } from "node:child_process";
|
|
46493
46630
|
import { mkdir as mkdir2, readdir as readdir2, rm as rm2, stat } from "node:fs/promises";
|
|
@@ -46680,6 +46817,12 @@ async function pollAssigned(ctx) {
|
|
|
46680
46817
|
const project = byProject.get(issue2.project_id);
|
|
46681
46818
|
if (!state || !project) return [];
|
|
46682
46819
|
if (options.project && project.key !== options.project) return [];
|
|
46820
|
+
if (blocksAgentPickup(state)) {
|
|
46821
|
+
log(
|
|
46822
|
+
` ${project.key}-${issue2.number} is in ${state.name}, which requires a human \u2014 not starting`
|
|
46823
|
+
);
|
|
46824
|
+
return [];
|
|
46825
|
+
}
|
|
46683
46826
|
if (state.category === "completed" || state.category === "canceled") return [];
|
|
46684
46827
|
const said = lastSaid.get(issue2.id);
|
|
46685
46828
|
if (said && issue2.updated_at && said > issue2.updated_at) return [];
|
|
@@ -46714,6 +46857,12 @@ async function poll(ctx, identity) {
|
|
|
46714
46857
|
const state = byState.get(issue2.status_id);
|
|
46715
46858
|
if (!project || !state) return [];
|
|
46716
46859
|
if (options.project && project.key !== options.project) return [];
|
|
46860
|
+
if (blocksAgentPickup(state)) {
|
|
46861
|
+
log(
|
|
46862
|
+
` ${project.key}-${issue2.number} is in ${state.name}, which requires a human \u2014 not starting`
|
|
46863
|
+
);
|
|
46864
|
+
return [];
|
|
46865
|
+
}
|
|
46717
46866
|
return [
|
|
46718
46867
|
{
|
|
46719
46868
|
ref: `${project.key}-${issue2.number}`,
|
|
@@ -47005,9 +47154,11 @@ async function invokeHarness(ctx, identity, hit, worktree) {
|
|
|
47005
47154
|
options.allow.split(",").map((t) => t.trim()).filter((t) => t !== "" && !t.startsWith("mcp__")).map((t) => t.replace(/\(.*$/, ""))
|
|
47006
47155
|
)
|
|
47007
47156
|
].join(",");
|
|
47157
|
+
const userPromptText = userPrompt(hit);
|
|
47158
|
+
const systemPromptText = systemPrompt(ctx, identity, worktree);
|
|
47008
47159
|
const args = [
|
|
47009
47160
|
"-p",
|
|
47010
|
-
|
|
47161
|
+
userPromptText,
|
|
47011
47162
|
"--mcp-config",
|
|
47012
47163
|
mcpConfig,
|
|
47013
47164
|
// Both, always. See the note above: without `--restricted` the harness
|
|
@@ -47023,7 +47174,7 @@ async function invokeHarness(ctx, identity, hit, worktree) {
|
|
|
47023
47174
|
"--allowedTools",
|
|
47024
47175
|
options.allow,
|
|
47025
47176
|
"--system-prompt",
|
|
47026
|
-
|
|
47177
|
+
systemPromptText,
|
|
47027
47178
|
...options.model ? ["--model", options.model] : [],
|
|
47028
47179
|
// `--verbose` is not optional alongside stream-json: without it the harness
|
|
47029
47180
|
// emits only the final result and the live view is a blank terminal for the
|
|
@@ -47045,6 +47196,7 @@ async function invokeHarness(ctx, identity, hit, worktree) {
|
|
|
47045
47196
|
let tail = "";
|
|
47046
47197
|
let head2 = "";
|
|
47047
47198
|
let pending = "";
|
|
47199
|
+
let openingContext = null;
|
|
47048
47200
|
const addHead = (text) => {
|
|
47049
47201
|
if (head2.length < 2048) head2 += text.slice(0, 2048 - head2.length);
|
|
47050
47202
|
};
|
|
@@ -47063,6 +47215,7 @@ async function invokeHarness(ctx, identity, hit, worktree) {
|
|
|
47063
47215
|
for (const line of lines) {
|
|
47064
47216
|
if (line.trim() === "") continue;
|
|
47065
47217
|
tail = line;
|
|
47218
|
+
if (openingContext === null) openingContext = turnUsageIn(line);
|
|
47066
47219
|
const rendered = renderEvent(line);
|
|
47067
47220
|
if (rendered.text) addHead(rendered.text + "\n");
|
|
47068
47221
|
if (rendered.show) process.stdout.write(rendered.show + "\n");
|
|
@@ -47086,13 +47239,17 @@ async function invokeHarness(ctx, identity, hit, worktree) {
|
|
|
47086
47239
|
durationMs: Date.now() - startedAtMs,
|
|
47087
47240
|
usage: null,
|
|
47088
47241
|
killed,
|
|
47089
|
-
stdoutHead: headFor(head2)
|
|
47242
|
+
stdoutHead: headFor(head2),
|
|
47243
|
+
openingContext: null,
|
|
47244
|
+
systemPromptChars: systemPromptText.length,
|
|
47245
|
+
userPromptChars: userPromptText.length
|
|
47090
47246
|
});
|
|
47091
47247
|
});
|
|
47092
47248
|
child.on("close", (code) => {
|
|
47093
47249
|
clearTimeout(timer);
|
|
47094
47250
|
if (streaming && pending.trim() !== "") {
|
|
47095
47251
|
tail = pending;
|
|
47252
|
+
if (openingContext === null) openingContext = turnUsageIn(pending);
|
|
47096
47253
|
const rendered = renderEvent(pending);
|
|
47097
47254
|
if (rendered.text) addHead(rendered.text + "\n");
|
|
47098
47255
|
if (rendered.show) process.stdout.write(rendered.show + "\n");
|
|
@@ -47105,7 +47262,10 @@ async function invokeHarness(ctx, identity, hit, worktree) {
|
|
|
47105
47262
|
durationMs: Date.now() - startedAtMs,
|
|
47106
47263
|
usage: usageIn(tail),
|
|
47107
47264
|
killed,
|
|
47108
|
-
stdoutHead: headFor(head2)
|
|
47265
|
+
stdoutHead: headFor(head2),
|
|
47266
|
+
openingContext,
|
|
47267
|
+
systemPromptChars: systemPromptText.length,
|
|
47268
|
+
userPromptChars: userPromptText.length
|
|
47109
47269
|
});
|
|
47110
47270
|
});
|
|
47111
47271
|
});
|
|
@@ -47207,6 +47367,16 @@ function announce(status) {
|
|
|
47207
47367
|
}
|
|
47208
47368
|
})();
|
|
47209
47369
|
}
|
|
47370
|
+
function beatWhileBusy(ctx, deadTicks) {
|
|
47371
|
+
const timer = setInterval(() => {
|
|
47372
|
+
void beat(ctx, { holding: lastHolding, deadTicks, intervalMs: options.intervalMs }).catch(
|
|
47373
|
+
() => {
|
|
47374
|
+
}
|
|
47375
|
+
);
|
|
47376
|
+
}, options.intervalMs);
|
|
47377
|
+
timer.unref?.();
|
|
47378
|
+
return () => clearInterval(timer);
|
|
47379
|
+
}
|
|
47210
47380
|
async function recordRun(ctx, hit, run, outcome) {
|
|
47211
47381
|
const { error: error51 } = await ctx.client.from("harness_runs").insert({
|
|
47212
47382
|
agent_id: ctx.userId,
|
|
@@ -47223,7 +47393,12 @@ async function recordRun(ctx, hit, run, outcome) {
|
|
|
47223
47393
|
output_tokens: run.usage?.outputTokens ?? null,
|
|
47224
47394
|
cache_read_tokens: run.usage?.cacheReadTokens ?? null,
|
|
47225
47395
|
cache_write_tokens: run.usage?.cacheWriteTokens ?? null,
|
|
47226
|
-
cost_usd: run.usage?.costUsd ?? null
|
|
47396
|
+
cost_usd: run.usage?.costUsd ?? null,
|
|
47397
|
+
opening_context_input_tokens: run.openingContext?.inputTokens ?? null,
|
|
47398
|
+
opening_context_cache_read_tokens: run.openingContext?.cacheReadTokens ?? null,
|
|
47399
|
+
opening_context_cache_write_tokens: run.openingContext?.cacheWriteTokens ?? null,
|
|
47400
|
+
system_prompt_chars: run.systemPromptChars,
|
|
47401
|
+
user_prompt_chars: run.userPromptChars
|
|
47227
47402
|
});
|
|
47228
47403
|
if (error51 && !warnedAboutSpendTable) {
|
|
47229
47404
|
warnedAboutSpendTable = true;
|
|
@@ -47314,6 +47489,7 @@ async function tick(ctx, identity, deadTicks, allowance) {
|
|
|
47314
47489
|
let run;
|
|
47315
47490
|
let committed = 0;
|
|
47316
47491
|
let salvaged = null;
|
|
47492
|
+
const stopBusyBeat = beatWhileBusy(ctx, deadTicks);
|
|
47317
47493
|
try {
|
|
47318
47494
|
run = await invokeHarness(ctx, identity, hit, worktree);
|
|
47319
47495
|
if (worktree) committed = await worktree.commits();
|
|
@@ -47336,6 +47512,7 @@ async function tick(ctx, identity, deadTicks, allowance) {
|
|
|
47336
47512
|
);
|
|
47337
47513
|
}
|
|
47338
47514
|
} finally {
|
|
47515
|
+
stopBusyBeat();
|
|
47339
47516
|
await release(ctx, hit);
|
|
47340
47517
|
}
|
|
47341
47518
|
const code = run.code;
|
|
@@ -47571,6 +47748,7 @@ var init_supervisor = __esm({
|
|
|
47571
47748
|
init_harness_signal();
|
|
47572
47749
|
init_process();
|
|
47573
47750
|
init_pacing();
|
|
47751
|
+
init_queries();
|
|
47574
47752
|
init_worktree();
|
|
47575
47753
|
argv = process.argv.slice(2);
|
|
47576
47754
|
flag = (name) => flagIn(argv, name);
|
|
@@ -47705,6 +47883,12 @@ var init_supervisor = __esm({
|
|
|
47705
47883
|
});
|
|
47706
47884
|
options = (() => {
|
|
47707
47885
|
try {
|
|
47886
|
+
const [unknown2] = unknownFlags(argv, SUPERVISOR_VALUED);
|
|
47887
|
+
if (unknown2) {
|
|
47888
|
+
throw new OptionError(
|
|
47889
|
+
`${unknown2.flag} is not a flag the supervisor reads` + (unknown2.nearest ? ` \u2014 did you mean ${unknown2.nearest}?` : ".") + ` Nothing was started.`
|
|
47890
|
+
);
|
|
47891
|
+
}
|
|
47708
47892
|
return readOptions();
|
|
47709
47893
|
} catch (error51) {
|
|
47710
47894
|
if (error51 instanceof OptionError) {
|
|
@@ -47790,8 +47974,10 @@ var USAGE = `cruo \u2014 run a Cruo agent
|
|
|
47790
47974
|
cruo agents list what is remembered (never the tokens)
|
|
47791
47975
|
cruo usage [--days 7] what the agents have been spending
|
|
47792
47976
|
cruo logout [name] forget one, or --all
|
|
47793
|
-
cruo [options]
|
|
47794
|
-
cruo --as <name> \u2026 run a particular one
|
|
47977
|
+
cruo run [options] run the agent's supervisor, in this terminal
|
|
47978
|
+
cruo --as <name> \u2026 run a particular one (flags alone also run it)
|
|
47979
|
+
cruo version which build this is
|
|
47980
|
+
cruo help this list (also: cruo, cruo -h, cruo ?)
|
|
47795
47981
|
|
|
47796
47982
|
Running one in the background
|
|
47797
47983
|
cruo start [options] same, detached \u2014 survives closing the terminal
|
|
@@ -47903,7 +48089,7 @@ ${CONFIG_PATH} is readable only by you.
|
|
|
47903
48089
|
|
|
47904
48090
|
` + (config3.default === name ? `Run \`cruo --dry-run\` to see what it would pick up.
|
|
47905
48091
|
` : `Run \`cruo --as ${name} --dry-run\` to see what it would pick up.
|
|
47906
|
-
|
|
48092
|
+
\`cruo run\` still runs \`${config3.default}\`.
|
|
47907
48093
|
`)
|
|
47908
48094
|
);
|
|
47909
48095
|
}
|
|
@@ -47954,7 +48140,7 @@ Nothing stored for \`${which}\`. Stored: ${names.join(", ") || "(none)"}
|
|
|
47954
48140
|
await writeConfig(config3);
|
|
47955
48141
|
console.log(
|
|
47956
48142
|
`
|
|
47957
|
-
Forgot the token for \`${which}\`.` + (config3.default ? `
|
|
48143
|
+
Forgot the token for \`${which}\`.` + (config3.default ? ` \`cruo run\` now runs \`${config3.default}\`.
|
|
47958
48144
|
` : ` Nothing is stored now.
|
|
47959
48145
|
`)
|
|
47960
48146
|
);
|
|
@@ -47976,7 +48162,7 @@ No tokens stored. \`cruo login <token>\` to add one.
|
|
|
47976
48162
|
console.log(` ${mark} ${name}${who}`);
|
|
47977
48163
|
}
|
|
47978
48164
|
console.log(`
|
|
47979
|
-
* is what
|
|
48165
|
+
* is what \`cruo run\` runs. Use \`--as <name>\` for another.
|
|
47980
48166
|
`);
|
|
47981
48167
|
}
|
|
47982
48168
|
async function targetName(explicit, asName) {
|
|
@@ -48051,13 +48237,14 @@ Either \`cruo start ${stored[0]}\`, or add this one:
|
|
|
48051
48237
|
);
|
|
48052
48238
|
process.exit(2);
|
|
48053
48239
|
}
|
|
48240
|
+
refuseUnknownFlags(argv2.slice(positional ? 2 : 1).filter((a) => a !== "--all"));
|
|
48054
48241
|
await mkdir4(logDir(), { recursive: true });
|
|
48055
48242
|
const logPath = join4(logDir(), `${name}.log`);
|
|
48056
48243
|
const handle = await open(logPath, "a");
|
|
48057
48244
|
const rest = argv2.slice(positional ? 2 : 1).filter((a) => a !== "--all");
|
|
48058
48245
|
const chosen = storedKey ?? positional ?? asName;
|
|
48059
48246
|
const withoutAs = rest.filter((a, i, all) => a !== "--as" && all[i - 1] !== "--as");
|
|
48060
|
-
const forwarded = chosen ? ["--as", chosen, ...withoutAs]
|
|
48247
|
+
const forwarded = ["run", ...chosen ? ["--as", chosen] : [], ...withoutAs];
|
|
48061
48248
|
const child = spawn2(process.execPath, [process.argv[1], ...forwarded], {
|
|
48062
48249
|
detached: true,
|
|
48063
48250
|
stdio: ["ignore", handle.fd, handle.fd],
|
|
@@ -48161,6 +48348,26 @@ A detached run writes one; a foreground run prints to its terminal.
|
|
|
48161
48348
|
});
|
|
48162
48349
|
await new Promise((resolve2) => child.on("close", resolve2));
|
|
48163
48350
|
}
|
|
48351
|
+
async function printVersion() {
|
|
48352
|
+
try {
|
|
48353
|
+
const pkg = JSON.parse(await readFile3(new URL("../package.json", import.meta.url), "utf8"));
|
|
48354
|
+
console.log(`${pkg.name} ${pkg.version}`);
|
|
48355
|
+
} catch {
|
|
48356
|
+
console.log("unknown \u2014 no package.json beside this build");
|
|
48357
|
+
}
|
|
48358
|
+
}
|
|
48359
|
+
function refuseUnknownFlags(argv2) {
|
|
48360
|
+
const unknown2 = unknownFlags(argv2);
|
|
48361
|
+
if (unknown2.length === 0) return;
|
|
48362
|
+
console.error(
|
|
48363
|
+
`
|
|
48364
|
+
${unknown2.map((u) => `\`${u.flag}\` is not a cruo flag.` + (u.nearest ? ` Did you mean ${u.nearest}?` : "")).join("\n")}
|
|
48365
|
+
|
|
48366
|
+
Nothing was started. Everything it takes: cruo help
|
|
48367
|
+
`
|
|
48368
|
+
);
|
|
48369
|
+
process.exit(2);
|
|
48370
|
+
}
|
|
48164
48371
|
async function main2() {
|
|
48165
48372
|
const argv2 = process.argv.slice(2);
|
|
48166
48373
|
const [first] = argv2;
|
|
@@ -48197,10 +48404,11 @@ Usage: cruo login <token> [--as <name>]
|
|
|
48197
48404
|
}
|
|
48198
48405
|
if (first === "usage") {
|
|
48199
48406
|
}
|
|
48200
|
-
if (first === "help" || argv2.includes("--help") || argv2.includes("-h")) {
|
|
48407
|
+
if (first === void 0 || first === "help" || first === "?" || argv2.includes("--help") || argv2.includes("-h")) {
|
|
48201
48408
|
console.log(USAGE);
|
|
48202
48409
|
return;
|
|
48203
48410
|
}
|
|
48411
|
+
if (first === "version" || first === "--version" || first === "-v") return printVersion();
|
|
48204
48412
|
if (!isKnownCommandWord(first)) {
|
|
48205
48413
|
const near = nearestCommands(first);
|
|
48206
48414
|
console.error(
|
|
@@ -48209,13 +48417,15 @@ Usage: cruo login <token> [--as <name>]
|
|
|
48209
48417
|
|
|
48210
48418
|
` + (near.length > 0 ? `Did you mean: ${near.map((k) => `cruo ${k}`).join(" ")}
|
|
48211
48419
|
|
|
48212
|
-
` : "") + `To run the agent
|
|
48213
|
-
Everything it takes:
|
|
48420
|
+
` : "") + `To run the agent: cruo run [options]
|
|
48421
|
+
Everything it takes: cruo help
|
|
48214
48422
|
`
|
|
48215
48423
|
);
|
|
48216
48424
|
process.exit(2);
|
|
48217
48425
|
}
|
|
48218
48426
|
if (first === "start") return startDetached(argv2, flagValue("--as"));
|
|
48427
|
+
const runArgv = first === "run" ? argv2.slice(1) : argv2;
|
|
48428
|
+
if (first !== "usage") refuseUnknownFlags(runArgv);
|
|
48219
48429
|
const flagIndex = argv2.indexOf("--token");
|
|
48220
48430
|
const fromFlag = flagIndex >= 0 ? argv2[flagIndex + 1] : void 0;
|
|
48221
48431
|
if (fromFlag) {
|
|
@@ -48255,7 +48465,7 @@ Get one from Cruo \u2192 Settings \u2192 Members \u2192 Add an agent.
|
|
|
48255
48465
|
process.env.CRUO_IDENTITY = asName ?? config3.default ?? "";
|
|
48256
48466
|
}
|
|
48257
48467
|
process.env.CRUO_TOKEN = token;
|
|
48258
|
-
const passthrough = stripTokenFlag(
|
|
48468
|
+
const passthrough = stripTokenFlag(runArgv).filter((a, i, all) => a !== "--as" && all[i - 1] !== "--as");
|
|
48259
48469
|
process.argv = [process.argv[0], process.argv[1], ...passthrough];
|
|
48260
48470
|
if (first === "usage") {
|
|
48261
48471
|
const { reportUsage: reportUsage2 } = await Promise.resolve().then(() => (init_usage(), usage_exports));
|
package/package.json
CHANGED