@mu-crew/mu 3.6.0 → 3.6.2

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 CHANGED
@@ -5188,6 +5188,7 @@ function mapMurmurState(token, since) {
5188
5188
  break;
5189
5189
  case "idle":
5190
5190
  case "done":
5191
+ case "error":
5191
5192
  case "crashed":
5192
5193
  state = "needs_input";
5193
5194
  break;
@@ -5241,7 +5242,7 @@ function remoteReading(agent, panes) {
5241
5242
  (entry) => typeof entry === "object" && entry !== null && "kind" in entry && typeof entry.kind === "string" ? [entry.kind] : []
5242
5243
  )
5243
5244
  ) : /* @__PURE__ */ new Set();
5244
- const state = kinds.has("crashed") ? "needs_input" : kinds.has("blocked") ? "needs_permission" : kinds.has("done") ? "needs_input" : row2.activity === "running" ? "busy" : "needs_input";
5245
+ const state = kinds.has("crashed") || kinds.has("error") ? "needs_input" : kinds.has("blocked") ? "needs_permission" : kinds.has("done") ? "needs_input" : row2.activity === "running" ? "busy" : "needs_input";
5245
5246
  return {
5246
5247
  state,
5247
5248
  source: "murmur",
@@ -5299,7 +5300,8 @@ async function readAgentStates(agents, opts = {}) {
5299
5300
  source: "ctl",
5300
5301
  since: probe.status.since,
5301
5302
  alive: true,
5302
- ctl: "ok"
5303
+ ctl: "ok",
5304
+ pending: probe.status.pending
5303
5305
  });
5304
5306
  } else {
5305
5307
  failed.set(agentKey(agent), probe?.kind === "missing" ? "missing" : "refused");
@@ -7346,6 +7348,7 @@ async function waitForTasks(db, input, opts) {
7346
7348
  const timeoutMs = opts.timeoutMs ?? 6e5;
7347
7349
  const pollMs = opts.pollMs ?? 1e3;
7348
7350
  const stuckAfterMs = opts.stuckAfterMs ?? DEFAULT_STUCK_AFTER_MS;
7351
+ const ctlStuckAfterMs = opts.ctlStuckAfterMs ?? DEFAULT_CTL_STUCK_AFTER_MS;
7349
7352
  const onStall = opts.onStall ?? "warn";
7350
7353
  const deadline = timeoutMs > 0 ? Date.now() + timeoutMs : Number.POSITIVE_INFINITY;
7351
7354
  for (const ref of refs) {
@@ -7373,8 +7376,10 @@ async function waitForTasks(db, input, opts) {
7373
7376
  ctlBrokenSince.delete(ownerKey);
7374
7377
  stuckLabel.delete(ownerKey);
7375
7378
  if (reading?.state !== "needs_input" || reading.since === null) return null;
7379
+ const viaCtl = reading.source === "ctl" && reading.ctl === "ok";
7380
+ if (viaCtl && reading.pending === true) return null;
7376
7381
  const ageMs2 = Date.now() - reading.since;
7377
- return ageMs2 >= stuckAfterMs ? ageMs2 : null;
7382
+ return ageMs2 >= (viaCtl ? ctlStuckAfterMs : stuckAfterMs) ? ageMs2 : null;
7378
7383
  };
7379
7384
  const snapshot2 = async () => {
7380
7385
  const refStates = [];
@@ -7450,7 +7455,7 @@ async function waitForTasks(db, input, opts) {
7450
7455
  if (isDone(snap)) return snap;
7451
7456
  }
7452
7457
  }
7453
- var currentWaitSleep, pollCount, DEFAULT_STUCK_AFTER_MS, defaultStuckWarn, currentStuckWarn;
7458
+ var currentWaitSleep, pollCount, DEFAULT_STUCK_AFTER_MS, DEFAULT_CTL_STUCK_AFTER_MS, defaultStuckWarn, currentStuckWarn;
7454
7459
  var init_wait = __esm({
7455
7460
  "src/tasks/wait.ts"() {
7456
7461
  "use strict";
@@ -7461,6 +7466,7 @@ var init_wait = __esm({
7461
7466
  currentWaitSleep = (ms) => new Promise((resolve9) => setTimeout(resolve9, ms));
7462
7467
  pollCount = 0;
7463
7468
  DEFAULT_STUCK_AFTER_MS = 12e4;
7469
+ DEFAULT_CTL_STUCK_AFTER_MS = 5e3;
7464
7470
  defaultStuckWarn = (msg) => {
7465
7471
  process.stderr.write(msg);
7466
7472
  };
@@ -19418,6 +19424,7 @@ async function cmdTaskWait(db, ids, opts) {
19418
19424
  const timeoutMs = opts.timeout !== void 0 ? opts.timeout * 1e3 : 6e5;
19419
19425
  const stuckAfterMs = opts.stuckAfter !== void 0 ? opts.stuckAfter * 1e3 : DEFAULT_STUCK_AFTER_MS;
19420
19426
  const sdkOpts = { timeoutMs, stuckAfterMs };
19427
+ if (opts.stuckAfter !== void 0) sdkOpts.ctlStuckAfterMs = stuckAfterMs;
19421
19428
  if (statusOpt !== void 0) sdkOpts.status = statusOpt;
19422
19429
  if (wantAny) sdkOpts.any = true;
19423
19430
  let ownerReadings = /* @__PURE__ */ new Map();
@@ -20183,7 +20190,7 @@ function wireTaskCommands(program) {
20183
20190
  "alias for --any that ALSO prints the firing ref's qualified id to stdout and populates `firing` in --json (which --any leaves null). Use to drive a single-shot dispatch loop: `closed=$(mu task wait a b --first --json | jq -r .firing.qualifiedId)`."
20184
20191
  ).option("--timeout <seconds>", "max seconds to wait (0 = forever, default 600)", parseLines).option(
20185
20192
  "--stuck-after <seconds>",
20186
- "the TRIGGER: mark an IN_PROGRESS task as needing attention when its owner has been in needs_input for >= N seconds since their last status change (0 = disable, default 120). needs_input has several causes \u2014 the worker may have finished without closing, be waiting on an answer, or be sitting at a prompt \u2014 so the warning names the observation and points at `mu agent read <owner>`, which is the next move in every case. The default ACTION is `exit` (exit 7); see --on-stall warn to keep polling instead.",
20193
+ "the TRIGGER: mark an IN_PROGRESS task as needing attention when its owner has been in needs_input for >= N seconds since their last status change (0 = disable; default 120, or 5 for a pi owner read over its control socket, whose idle is exact and comes after the close nudge; an explicit value applies to every owner). needs_input has several causes \u2014 the worker may have finished without closing, be waiting on an answer, or be sitting at a prompt \u2014 so the warning names the observation and points at `mu agent read <owner>`, which is the next move in every case. The default ACTION is `exit` (exit 7); see --on-stall warn to keep polling instead.",
20187
20194
  parseLines
20188
20195
  ).option(
20189
20196
  "--on-stall <action>",