cruo-agent 0.1.17 → 0.1.19
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 +77 -28
- package/dist/index.js +2 -2
- package/package.json +1 -1
package/dist/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.1.
|
|
1
|
+
0.1.19
|
package/dist/cli.js
CHANGED
|
@@ -15300,6 +15300,13 @@ var init_order = __esm({
|
|
|
15300
15300
|
}
|
|
15301
15301
|
});
|
|
15302
15302
|
|
|
15303
|
+
// ../../packages/core/dist/csv.js
|
|
15304
|
+
var init_csv = __esm({
|
|
15305
|
+
"../../packages/core/dist/csv.js"() {
|
|
15306
|
+
"use strict";
|
|
15307
|
+
}
|
|
15308
|
+
});
|
|
15309
|
+
|
|
15303
15310
|
// ../../packages/core/dist/index.js
|
|
15304
15311
|
var init_dist = __esm({
|
|
15305
15312
|
"../../packages/core/dist/index.js"() {
|
|
@@ -15315,6 +15322,7 @@ var init_dist = __esm({
|
|
|
15315
15322
|
init_tree();
|
|
15316
15323
|
init_place();
|
|
15317
15324
|
init_order();
|
|
15325
|
+
init_csv();
|
|
15318
15326
|
}
|
|
15319
15327
|
});
|
|
15320
15328
|
|
|
@@ -47659,6 +47667,14 @@ async function invokeHarness(ctx, identity, hit, worktree) {
|
|
|
47659
47667
|
"--strict-mcp-config",
|
|
47660
47668
|
"--allowedTools",
|
|
47661
47669
|
options.allow,
|
|
47670
|
+
// CRA-131. The local database is shared by every agent and person on the
|
|
47671
|
+
// machine, so no agent resets it. `pnpm supabase:reset` refuses inside a
|
|
47672
|
+
// run on its own (CRUO_AGENT_RUN, below); these are the spellings that
|
|
47673
|
+
// bypass that script. A deny rule matches a prefix, so it is a fence and
|
|
47674
|
+
// not a wall — `bash -c "…"` still gets round it — but it stops the
|
|
47675
|
+
// ordinary command an agent reaches for, which is how 2026-09-19 happened.
|
|
47676
|
+
"--disallowedTools",
|
|
47677
|
+
DB_RESET_DENY.join(","),
|
|
47662
47678
|
"--system-prompt",
|
|
47663
47679
|
systemPromptText,
|
|
47664
47680
|
...options.model ? ["--model", options.model] : [],
|
|
@@ -47675,7 +47691,9 @@ async function invokeHarness(ctx, identity, hit, worktree) {
|
|
|
47675
47691
|
// both are written straight through — this tees, it does not capture.
|
|
47676
47692
|
stdio: ["ignore", "pipe", "pipe"],
|
|
47677
47693
|
cwd,
|
|
47678
|
-
|
|
47694
|
+
// CRA-131: marks everything the harness runs as inside an agent run,
|
|
47695
|
+
// which is what makes `pnpm supabase:reset` refuse with no override.
|
|
47696
|
+
env: { ...harnessEnv(), CRUO_AGENT_RUN: hit.ref }
|
|
47679
47697
|
});
|
|
47680
47698
|
const startedAtMs = Date.now();
|
|
47681
47699
|
let stdoutBytes = 0;
|
|
@@ -47980,28 +47998,40 @@ async function recordRun(ctx, hit, run, outcome) {
|
|
|
47980
47998
|
}
|
|
47981
47999
|
}
|
|
47982
48000
|
async function tick(ctx, identity, deadTicks, allowance) {
|
|
47983
|
-
const
|
|
47984
|
-
|
|
47985
|
-
|
|
47986
|
-
|
|
47987
|
-
|
|
47988
|
-
|
|
47989
|
-
|
|
47990
|
-
|
|
47991
|
-
|
|
47992
|
-
|
|
47993
|
-
|
|
47994
|
-
|
|
47995
|
-
|
|
47996
|
-
|
|
47997
|
-
|
|
47998
|
-
|
|
47999
|
-
|
|
48000
|
-
|
|
48001
|
-
|
|
48002
|
-
|
|
48003
|
-
|
|
48004
|
-
|
|
48001
|
+
const readQueue = async (exclude, quiet2) => {
|
|
48002
|
+
const mentions = await pollMentions(ctx, identity);
|
|
48003
|
+
const [assigned, stateWork] = await Promise.all([pollAssigned(ctx, identity), poll(ctx, identity)]);
|
|
48004
|
+
const seen = /* @__PURE__ */ new Set();
|
|
48005
|
+
const hits = [...mentions, ...assigned, ...stateWork].filter((h) => {
|
|
48006
|
+
if (seen.has(h.ref)) return false;
|
|
48007
|
+
seen.add(h.ref);
|
|
48008
|
+
return true;
|
|
48009
|
+
});
|
|
48010
|
+
const heldByOthers2 = await claimedElsewhere(ctx, hits);
|
|
48011
|
+
const free2 = hits.filter((h) => !heldByOthers2.has(h.issue.id));
|
|
48012
|
+
if (heldByOthers2.size > 0 && !quiet2) {
|
|
48013
|
+
log(`${heldByOthers2.size} issue(s) already being worked by someone else`);
|
|
48014
|
+
}
|
|
48015
|
+
const attemptsByHit = await loadAttempts(ctx, free2);
|
|
48016
|
+
const attemptsFor2 = (h) => attemptsByHit.get(`${h.reason}:${h.issue.id}`) ?? 0;
|
|
48017
|
+
const spendByHit = await loadSpend(ctx, free2);
|
|
48018
|
+
const spendFor = (h) => spendByHit.get(h.issue.id) ?? 0;
|
|
48019
|
+
const overBudget = options.maxCostUsd !== void 0 ? free2.filter(
|
|
48020
|
+
(h) => !exclude.has(h.issue.id) && attemptsFor2(h) < options.maxAttempts && spendFor(h) >= options.maxCostUsd
|
|
48021
|
+
) : [];
|
|
48022
|
+
for (const hit of overBudget) {
|
|
48023
|
+
exclude.add(hit.issue.id);
|
|
48024
|
+
await handOffForCost(ctx, hit, spendFor(hit));
|
|
48025
|
+
}
|
|
48026
|
+
const actionable2 = free2.filter(
|
|
48027
|
+
(h) => !exclude.has(h.issue.id) && attemptsFor2(h) < options.maxAttempts && (options.maxCostUsd === void 0 || spendFor(h) < options.maxCostUsd)
|
|
48028
|
+
);
|
|
48029
|
+
return { free: free2, heldByOthers: heldByOthers2, actionable: actionable2, attemptsFor: attemptsFor2 };
|
|
48030
|
+
};
|
|
48031
|
+
const tried = /* @__PURE__ */ new Set();
|
|
48032
|
+
const queue = await readQueue(tried, false);
|
|
48033
|
+
const { free, heldByOthers } = queue;
|
|
48034
|
+
let { actionable, attemptsFor } = queue;
|
|
48005
48035
|
if (actionable.length === 0) {
|
|
48006
48036
|
if (free.length > 0) {
|
|
48007
48037
|
log(`${free.length} issue(s) waiting, all set aside`);
|
|
@@ -48039,13 +48069,25 @@ async function tick(ctx, identity, deadTicks, allowance) {
|
|
|
48039
48069
|
`${actionable.length} issue(s) for "${identity.jobFunction}"` + (mentionCount > 0 ? ` \u2014 ${mentionCount} from unread mentions` : "")
|
|
48040
48070
|
);
|
|
48041
48071
|
const cap = allowance === "probe" ? 1 : options.limit;
|
|
48042
|
-
|
|
48043
|
-
if (taking.length < actionable.length) {
|
|
48072
|
+
if (cap && cap < actionable.length) {
|
|
48044
48073
|
log(
|
|
48045
|
-
allowance === "probe" ? ` probing with ${
|
|
48074
|
+
allowance === "probe" ? ` probing with ${cap} of ${actionable.length} \u2014 one card is enough to learn whether the harness works again` : ` taking ${cap} this tick (--limit ${options.limit})`
|
|
48046
48075
|
);
|
|
48047
48076
|
}
|
|
48048
|
-
|
|
48077
|
+
const firstRead = new Set(actionable.map((h) => h.issue.id));
|
|
48078
|
+
let worked = 0;
|
|
48079
|
+
for (let first = true; ; first = false) {
|
|
48080
|
+
if (cap && worked >= cap) break;
|
|
48081
|
+
if (!first) {
|
|
48082
|
+
if (stopping || paused) break;
|
|
48083
|
+
({ actionable, attemptsFor } = await readQueue(tried, true));
|
|
48084
|
+
}
|
|
48085
|
+
const queued = actionable.find((h) => !tried.has(h.issue.id));
|
|
48086
|
+
if (!queued) break;
|
|
48087
|
+
tried.add(queued.issue.id);
|
|
48088
|
+
if (!firstRead.has(queued.issue.id)) {
|
|
48089
|
+
log(` ${queued.ref} arrived since this pass began \u2014 taking it next`);
|
|
48090
|
+
}
|
|
48049
48091
|
const rechecked = await recheckEligibility(ctx, queued, identity);
|
|
48050
48092
|
if (!rechecked.ok) {
|
|
48051
48093
|
log(` ${queued.ref} ${rechecked.why} \u2014 skipping`);
|
|
@@ -48054,6 +48096,7 @@ async function tick(ctx, identity, deadTicks, allowance) {
|
|
|
48054
48096
|
const hit = rechecked.hit;
|
|
48055
48097
|
const why = hit.reason === "mention" ? "mentioned" : hit.reason === "assigned" ? `assigned \xB7 ${hit.state.name}` : hit.state.name;
|
|
48056
48098
|
log(`\u2192 ${hit.ref} "${hit.issue.title}" (${why})`);
|
|
48099
|
+
worked += 1;
|
|
48057
48100
|
if (options.dryRun) {
|
|
48058
48101
|
log(` dry run \u2014 would invoke: ${options.harness} -p \u2026 --allowedTools ${options.allow}`);
|
|
48059
48102
|
continue;
|
|
@@ -48375,7 +48418,7 @@ to catch: a second supervisor nothing could see or stop.
|
|
|
48375
48418
|
if (stopping) return;
|
|
48376
48419
|
}
|
|
48377
48420
|
}
|
|
48378
|
-
var argv, flag, opt, num2, ms, readOptions, options, log, sessionRenewal, worktreeConfig, lastRefusal, CONFIG_DIR_PREFIX, CRUO_OWNED_ENV, HEAD_STORED, lastHolding, warnedAboutSpendTable, stopping, paused, stopRequestedAt, currentRun, pendingWait;
|
|
48421
|
+
var argv, flag, opt, num2, ms, readOptions, options, log, sessionRenewal, worktreeConfig, lastRefusal, CONFIG_DIR_PREFIX, CRUO_OWNED_ENV, DB_RESET_DENY, HEAD_STORED, lastHolding, warnedAboutSpendTable, stopping, paused, stopRequestedAt, currentRun, pendingWait;
|
|
48379
48422
|
var init_supervisor = __esm({
|
|
48380
48423
|
"src/supervisor.ts"() {
|
|
48381
48424
|
"use strict";
|
|
@@ -48603,6 +48646,12 @@ cruo-supervisor: ${error51.message}
|
|
|
48603
48646
|
// stands in for. Cheap to list, and wrong to discover the hard way.
|
|
48604
48647
|
"CRUO_SESSION"
|
|
48605
48648
|
];
|
|
48649
|
+
DB_RESET_DENY = [
|
|
48650
|
+
"Bash(npx supabase db reset:*)",
|
|
48651
|
+
"Bash(supabase db reset:*)",
|
|
48652
|
+
"Bash(pnpm exec supabase db reset:*)",
|
|
48653
|
+
"Bash(pnpm dlx supabase db reset:*)"
|
|
48654
|
+
];
|
|
48606
48655
|
HEAD_STORED = 200;
|
|
48607
48656
|
lastHolding = 0;
|
|
48608
48657
|
warnedAboutSpendTable = false;
|
package/dist/index.js
CHANGED
|
@@ -89353,7 +89353,7 @@ function registerTools(server, getContext2, options = {}) {
|
|
|
89353
89353
|
"delete_issue",
|
|
89354
89354
|
{
|
|
89355
89355
|
title: "Delete issue",
|
|
89356
|
-
description: "
|
|
89356
|
+
description: "Move an issue to the trash. It disappears from the board and every tool, with its comments, labels and activity; a person can restore it from Trash in the app for 30 days, after which it is deleted for good.",
|
|
89357
89357
|
inputSchema: { issue: external_exports.string().describe("Issue reference, e.g. CRU-14") }
|
|
89358
89358
|
},
|
|
89359
89359
|
async (args, ctx) => {
|
|
@@ -89361,7 +89361,7 @@ function registerTools(server, getContext2, options = {}) {
|
|
|
89361
89361
|
const ref = issueRef(project, issue2);
|
|
89362
89362
|
const { error: error52 } = await ctx.client.from("issues").delete().eq("id", issue2.id);
|
|
89363
89363
|
if (error52) throw new ToolError(error52.message);
|
|
89364
|
-
return `
|
|
89364
|
+
return `Moved ${ref} to the trash. It can be restored from Trash in the app for 30 days.`;
|
|
89365
89365
|
}
|
|
89366
89366
|
);
|
|
89367
89367
|
register(
|
package/package.json
CHANGED