@archme/cli 0.14.7 → 0.14.8
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/cli.js +72 -18
- package/package.json +1 -1
- package/sandbox-image.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -19366,6 +19366,31 @@ var init_imageManifest = __esm({
|
|
|
19366
19366
|
}
|
|
19367
19367
|
});
|
|
19368
19368
|
|
|
19369
|
+
// src/daemon/claimStance.ts
|
|
19370
|
+
function claimStance(configured, gate) {
|
|
19371
|
+
if (!gate || gate.allowsClaims()) return { kind: "claim", mode: configured };
|
|
19372
|
+
if (gate.isFailing?.()) return { kind: "presence_only", mode: "required_unavailable" };
|
|
19373
|
+
return { kind: "hold" };
|
|
19374
|
+
}
|
|
19375
|
+
function claimRpcParams(a2) {
|
|
19376
|
+
return {
|
|
19377
|
+
p_device_id: a2.deviceId,
|
|
19378
|
+
p_worker_id: a2.workerId,
|
|
19379
|
+
p_lease_seconds: a2.leaseSeconds,
|
|
19380
|
+
// Stamps presence + gates against daemon_min_version (migration 067);
|
|
19381
|
+
// NULL (read failure) is below any floor server-side.
|
|
19382
|
+
p_daemon_version: a2.daemonVersion,
|
|
19383
|
+
// Recorded on presence only; never gates (R3 §3.4).
|
|
19384
|
+
p_claude_version: a2.claudeVersion,
|
|
19385
|
+
p_sandbox_mode: a2.sandboxMode
|
|
19386
|
+
};
|
|
19387
|
+
}
|
|
19388
|
+
var init_claimStance = __esm({
|
|
19389
|
+
"src/daemon/claimStance.ts"() {
|
|
19390
|
+
"use strict";
|
|
19391
|
+
}
|
|
19392
|
+
});
|
|
19393
|
+
|
|
19369
19394
|
// src/daemon/sandboxJob/result.ts
|
|
19370
19395
|
import { readFile as readFile13 } from "node:fs/promises";
|
|
19371
19396
|
function isValidNonce(nonce) {
|
|
@@ -19666,6 +19691,10 @@ var init_confinement = __esm({
|
|
|
19666
19691
|
allowsClaims() {
|
|
19667
19692
|
return this.opts.mode !== "required" || !this.failing && !this.probing;
|
|
19668
19693
|
}
|
|
19694
|
+
/** A probe has failed and no re-probe has passed since (re-probes included). */
|
|
19695
|
+
isFailing() {
|
|
19696
|
+
return this.failing;
|
|
19697
|
+
}
|
|
19669
19698
|
schedule(ms) {
|
|
19670
19699
|
if (this.stopped) return;
|
|
19671
19700
|
if (this.handle !== null) this.timers.clearTimeout(this.handle);
|
|
@@ -21841,18 +21870,18 @@ The sub-agent returns its findings; **you then apply** the fixes yourself \u2014
|
|
|
21841
21870
|
${patchSection}
|
|
21842
21871
|
${DIFF_RULES}`;
|
|
21843
21872
|
}
|
|
21844
|
-
async function rpcClaim(ctx, deviceId) {
|
|
21873
|
+
async function rpcClaim(ctx, deviceId, mode) {
|
|
21874
|
+
const claudeVersion = await claudeCodeVersion();
|
|
21845
21875
|
const { data, error } = await withAuthRetry(
|
|
21846
21876
|
"claim",
|
|
21847
|
-
() => ctx.supabase.rpc("claim_archme_job", {
|
|
21848
|
-
|
|
21849
|
-
|
|
21850
|
-
|
|
21851
|
-
|
|
21852
|
-
|
|
21853
|
-
|
|
21854
|
-
|
|
21855
|
-
}),
|
|
21877
|
+
() => ctx.supabase.rpc("claim_archme_job", claimRpcParams({
|
|
21878
|
+
deviceId,
|
|
21879
|
+
workerId: ctx.workerId,
|
|
21880
|
+
leaseSeconds: ctx.leaseSeconds,
|
|
21881
|
+
daemonVersion,
|
|
21882
|
+
claudeVersion,
|
|
21883
|
+
sandboxMode: mode
|
|
21884
|
+
})),
|
|
21856
21885
|
ctx.reLogin
|
|
21857
21886
|
);
|
|
21858
21887
|
if (error) {
|
|
@@ -21984,11 +22013,14 @@ async function rpcDefer(ctx, jobId, deviceId, reason, detail) {
|
|
|
21984
22013
|
}
|
|
21985
22014
|
return data != null;
|
|
21986
22015
|
}
|
|
21987
|
-
async function rpcFail(ctx, jobId, deviceId, message2, metrics, logs) {
|
|
22016
|
+
async function rpcFail(ctx, jobId, deviceId, message2, metrics, logs, opts = {}) {
|
|
21988
22017
|
const result = await callJobCompletionEndpoint(ctx, "fail", jobId, deviceId, {
|
|
21989
22018
|
error: message2.slice(0, 4e3),
|
|
21990
22019
|
metrics,
|
|
21991
|
-
logs
|
|
22020
|
+
logs,
|
|
22021
|
+
// retry:false fails the job for good now (migration 141); absent, it
|
|
22022
|
+
// requeues while attempts remain.
|
|
22023
|
+
...opts
|
|
21992
22024
|
});
|
|
21993
22025
|
if (!result.ok) console.error(`[${jobId}] fail error:`, result.error);
|
|
21994
22026
|
}
|
|
@@ -22797,7 +22829,7 @@ ${logs.stderr}`, sentPrompt);
|
|
|
22797
22829
|
);
|
|
22798
22830
|
if (route2.kind === "terminal") {
|
|
22799
22831
|
console.log(`[${job.id}] failed (sandbox request cap, not deferred): ${route2.message}`);
|
|
22800
|
-
await rpcFail(ctx, job.id, deviceId, route2.message, metrics, logs);
|
|
22832
|
+
await rpcFail(ctx, job.id, deviceId, route2.message, metrics, logs, { retry: false });
|
|
22801
22833
|
return;
|
|
22802
22834
|
}
|
|
22803
22835
|
const plan = route2.kind === "defer" ? route2.plan : null;
|
|
@@ -22865,7 +22897,18 @@ async function dispatch(sched) {
|
|
|
22865
22897
|
}
|
|
22866
22898
|
pauseUntilMs = null;
|
|
22867
22899
|
}
|
|
22868
|
-
|
|
22900
|
+
const stance = claimStance(sandboxMode, confinementGate);
|
|
22901
|
+
if (stance.kind === "hold") return;
|
|
22902
|
+
if (stance.kind === "presence_only") {
|
|
22903
|
+
sched.dispatching = true;
|
|
22904
|
+
try {
|
|
22905
|
+
for (const { ctx, deviceId } of claimUnits(sched)) await sched.claim(ctx, deviceId, stance.mode);
|
|
22906
|
+
} finally {
|
|
22907
|
+
sched.dispatching = false;
|
|
22908
|
+
}
|
|
22909
|
+
return;
|
|
22910
|
+
}
|
|
22911
|
+
const mode = stance.mode;
|
|
22869
22912
|
sched.dispatching = true;
|
|
22870
22913
|
try {
|
|
22871
22914
|
let atCap = false;
|
|
@@ -22877,7 +22920,7 @@ async function dispatch(sched) {
|
|
|
22877
22920
|
atCap = true;
|
|
22878
22921
|
break;
|
|
22879
22922
|
}
|
|
22880
|
-
const claimed = await claimRoundRobin(sched);
|
|
22923
|
+
const claimed = await claimRoundRobin(sched, mode);
|
|
22881
22924
|
if (!claimed) {
|
|
22882
22925
|
slot();
|
|
22883
22926
|
break;
|
|
@@ -22898,16 +22941,20 @@ async function dispatch(sched) {
|
|
|
22898
22941
|
sched.dispatching = false;
|
|
22899
22942
|
}
|
|
22900
22943
|
}
|
|
22901
|
-
|
|
22944
|
+
function claimUnits(sched) {
|
|
22902
22945
|
const units = [];
|
|
22903
22946
|
for (const ctx of sched.sessions) {
|
|
22904
22947
|
if (ctx.auth && ctx.auth.getRefreshToken() === null && ctx.auth.getAccessToken() === null) continue;
|
|
22905
22948
|
for (const d of ctx.devices) units.push({ ctx, deviceId: d.deviceId });
|
|
22906
22949
|
}
|
|
22950
|
+
return units;
|
|
22951
|
+
}
|
|
22952
|
+
async function claimRoundRobin(sched, mode) {
|
|
22953
|
+
const units = claimUnits(sched);
|
|
22907
22954
|
const n2 = units.length;
|
|
22908
22955
|
for (let i2 = 0; i2 < n2; i2++) {
|
|
22909
22956
|
const u2 = units[(sched.rrIndex + i2) % n2];
|
|
22910
|
-
const job = await sched.claim(u2.ctx, u2.deviceId);
|
|
22957
|
+
const job = await sched.claim(u2.ctx, u2.deviceId, mode);
|
|
22911
22958
|
if (job && job.id) {
|
|
22912
22959
|
sched.rrIndex = (sched.rrIndex + i2 + 1) % n2;
|
|
22913
22960
|
return { job, ctx: u2.ctx, deviceId: u2.deviceId };
|
|
@@ -23056,6 +23103,7 @@ async function runDaemon() {
|
|
|
23056
23103
|
}
|
|
23057
23104
|
exitDaemon(1);
|
|
23058
23105
|
}
|
|
23106
|
+
sandboxMode = sandboxSettings.mode;
|
|
23059
23107
|
if (process.env.ARCHME_SANDBOX_SLOTS !== void 0) {
|
|
23060
23108
|
console.log(" ARCHME_SANDBOX_SLOTS is no longer read; sandbox slots follow MAX_CONCURRENT_JOBS");
|
|
23061
23109
|
}
|
|
@@ -23322,7 +23370,7 @@ ${signal} received, shutting down`);
|
|
|
23322
23370
|
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
23323
23371
|
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
23324
23372
|
}
|
|
23325
|
-
var HEARTBEAT_INTERVAL_MS, CLAUDE_TIMEOUT_MS, CLAUDE_LARGE_DIFF_TIMEOUT_MS, SAFETY_SWEEP_MS, LOG_STDOUT_CAP_BYTES, LOG_STDERR_CAP_BYTES, FAILURE_DETAIL_MAX, AUTH_PAUSE_MS, ClaudeRunError, PRE_SPAWN_TOKEN_MIN_LIFETIME_MS, SUPABASE_URL, SUPABASE_ANON_KEY, ARCHME_DAEMON_CLIENT_ID, ARCHME_MCP_BASE_URL, CLONE_BASE_DIR, DAEMON_ID, LEASE_SECONDS, inFlight, cancelled, killReasons, activeCleanups, cloneMutex, shuttingDown, daemonVersion, pauseUntilMs, resumeTimer, currentSched, MAX_CONCURRENT_JOBS, ctxByJob, deviceByJob, sandboxHost, confinementGate, boxedJobs, leaseLost, prefetchOverride, DEFAULT_CLONE_BASE_DIR, JOB_TOKEN_PREFIX, INLINE_PATCH_BYTE_CAP, GIT_SHA_RE, CURATOR_PREAMBLE, CORE_PRINCIPLES, STORY_COVERAGE_GATE, NEW_STORY_GUIDANCE, STORY_DESCRIPTION_EDIT_RULE, PHASE_GUIDANCE, BASE_RULES, DIFF_RULES, finite, channelSeq, MultipleAccountsError, __testDispatch;
|
|
23373
|
+
var HEARTBEAT_INTERVAL_MS, CLAUDE_TIMEOUT_MS, CLAUDE_LARGE_DIFF_TIMEOUT_MS, SAFETY_SWEEP_MS, LOG_STDOUT_CAP_BYTES, LOG_STDERR_CAP_BYTES, FAILURE_DETAIL_MAX, AUTH_PAUSE_MS, ClaudeRunError, PRE_SPAWN_TOKEN_MIN_LIFETIME_MS, SUPABASE_URL, SUPABASE_ANON_KEY, ARCHME_DAEMON_CLIENT_ID, ARCHME_MCP_BASE_URL, CLONE_BASE_DIR, DAEMON_ID, LEASE_SECONDS, inFlight, cancelled, killReasons, activeCleanups, cloneMutex, shuttingDown, daemonVersion, pauseUntilMs, resumeTimer, currentSched, MAX_CONCURRENT_JOBS, ctxByJob, deviceByJob, sandboxHost, confinementGate, sandboxMode, boxedJobs, leaseLost, prefetchOverride, DEFAULT_CLONE_BASE_DIR, JOB_TOKEN_PREFIX, INLINE_PATCH_BYTE_CAP, GIT_SHA_RE, CURATOR_PREAMBLE, CORE_PRINCIPLES, STORY_COVERAGE_GATE, NEW_STORY_GUIDANCE, STORY_DESCRIPTION_EDIT_RULE, PHASE_GUIDANCE, BASE_RULES, DIFF_RULES, finite, channelSeq, MultipleAccountsError, __testDispatch;
|
|
23326
23374
|
var init_run = __esm({
|
|
23327
23375
|
"src/daemon/run.ts"() {
|
|
23328
23376
|
"use strict";
|
|
@@ -23366,6 +23414,8 @@ var init_run = __esm({
|
|
|
23366
23414
|
init_localPoller();
|
|
23367
23415
|
init_setting();
|
|
23368
23416
|
init_imageManifest();
|
|
23417
|
+
init_claimStance();
|
|
23418
|
+
init_claudeVersion();
|
|
23369
23419
|
init_host();
|
|
23370
23420
|
init_runSandboxedJob();
|
|
23371
23421
|
init_inputDir();
|
|
@@ -23403,6 +23453,7 @@ var init_run = __esm({
|
|
|
23403
23453
|
deviceByJob = /* @__PURE__ */ new Map();
|
|
23404
23454
|
sandboxHost = null;
|
|
23405
23455
|
confinementGate = null;
|
|
23456
|
+
sandboxMode = "off";
|
|
23406
23457
|
boxedJobs = /* @__PURE__ */ new Set();
|
|
23407
23458
|
leaseLost = /* @__PURE__ */ new Set();
|
|
23408
23459
|
prefetchOverride = null;
|
|
@@ -23586,6 +23637,9 @@ ${ANCHOR_VERIFICATION}`;
|
|
|
23586
23637
|
setConfinementGate(gate) {
|
|
23587
23638
|
confinementGate = gate;
|
|
23588
23639
|
},
|
|
23640
|
+
setSandboxMode(mode) {
|
|
23641
|
+
sandboxMode = mode;
|
|
23642
|
+
},
|
|
23589
23643
|
// Daemon-version hooks for tests / introspection. The real value is
|
|
23590
23644
|
// populated at runDaemon boot from package.json; tests can stub.
|
|
23591
23645
|
setDaemonVersion(v) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@archme/cli",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.8",
|
|
4
4
|
"description": "Map your codebase into a living architecture diagram: run `archme init` in a repo to scan it, `archme daemon start` to keep it current on every commit.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
package/sandbox-image.json
CHANGED