agent-shim 11.21.0 → 11.22.0

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.cjs CHANGED
@@ -34181,7 +34181,7 @@ var init_package = __esm({
34181
34181
  "package.json"() {
34182
34182
  package_default = {
34183
34183
  name: "agent-shim",
34184
- version: "11.21.0",
34184
+ version: "11.22.0",
34185
34185
  description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
34186
34186
  license: "MIT",
34187
34187
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -114729,11 +114729,12 @@ function watchedInstallEntry(resolvedOwnExecutablePath, siblingExists) {
114729
114729
  return siblingExists(sibling) ? sibling : resolvedOwnExecutablePath;
114730
114730
  }
114731
114731
  var AWAIT_PID_POLL_MS = 50;
114732
- async function awaitPidExit(pid, boundMs, ports) {
114733
- const deadline = ports.now() + boundMs;
114734
- while (ports.isRunning(pid) && ports.now() < deadline) {
114732
+ async function awaitPidExit(pid, ports) {
114733
+ const startedAt = ports.now();
114734
+ while (ports.isRunning(pid)) {
114735
114735
  await ports.sleep(AWAIT_PID_POLL_MS);
114736
114736
  }
114737
+ return ports.now() - startedAt;
114737
114738
  }
114738
114739
  var FRONTDOOR_SUPERVISOR_STILL_RUNNING = -1;
114739
114740
  var FRONTDOOR_POLL_MS = 1e3;
@@ -132915,6 +132916,8 @@ var DOOR_WATCHDOG_CHECK_MS = PROBE_TIMEOUT_MS / CHECKS_PER_PROBE_DEADLINE;
132915
132916
  var WATCHDOG_SOURCE = `
132916
132917
  const { workerData, parentPort } = require("node:worker_threads");
132917
132918
  const fs = require("node:fs");
132919
+ const os = require("node:os");
132920
+ const inspector = require("node:inspector");
132918
132921
  const { shared, boundMs, checkEveryMs, stateFile, ownPid, action, logFile, respawn, respawnAfterServingMs, awaitPidEnv } = workerData;
132919
132922
  const startedAt = Date.now();
132920
132923
  const counter = new Int32Array(shared);
@@ -132941,6 +132944,45 @@ const log = (line) => {
132941
132944
  // Nowhere left to report a failed log write to; the process still has to end.
132942
132945
  }
132943
132946
  };
132947
+ // Enough of the stack to read the caller chain from the timer or socket callback down to the call that held the loop.
132948
+ const STACK_FRAMES_LOGGED = 12;
132949
+ // Asks the main thread where it is, through the inspector: a pause request interrupts JavaScript that is running (a loop, or a synchronous call that can be interrupted), so the top frames name what held the loop. A main thread that cannot be paused within the wait is not at such a point (it is idle in the event loop, which means it was not scheduled, or blocked inside a native call), and the answer says so rather than guessing. \`resume\` lets a thread that is not about to be killed run on again.
132950
+ const describeMainThread = (waitMs, resume) => new Promise((resolve) => {
132951
+ let session;
132952
+ let settled = false;
132953
+ const finish = (text) => {
132954
+ if (settled) return;
132955
+ settled = true;
132956
+ clearTimeout(timeout);
132957
+ try {
132958
+ session.disconnect();
132959
+ } catch (error) {
132960
+ // Never connected; there is nothing to release.
132961
+ }
132962
+ resolve(text);
132963
+ };
132964
+ const timeout = setTimeout(() => finish("the main thread could not be paused within " + String(waitMs) + "ms, so it was idle in the event loop or blocked inside a native call"), waitMs);
132965
+ try {
132966
+ session = new inspector.Session();
132967
+ session.connectToMainThread();
132968
+ session.on("Debugger.paused", (event) => {
132969
+ if (settled) return;
132970
+ const frames = event.params.callFrames.slice(0, STACK_FRAMES_LOGGED).map((frame) => (frame.functionName === "" ? "(anonymous)" : frame.functionName) + " " + frame.url + ":" + String(frame.location.lineNumber + 1));
132971
+ const text = "the main thread was in " + frames.join(" <- ");
132972
+ if (resume) {
132973
+ session.post("Debugger.resume", () => finish(text));
132974
+ } else {
132975
+ finish(text);
132976
+ }
132977
+ });
132978
+ session.post("Debugger.enable", () => {
132979
+ // The wait may have run out while the main thread was too stalled to answer the enable; the session is gone then.
132980
+ if (!settled) session.post("Debugger.pause");
132981
+ });
132982
+ } catch (error) {
132983
+ finish("the main thread could not be inspected: " + (error instanceof Error ? error.message : String(error)));
132984
+ }
132985
+ });
132944
132986
  const spawnReplacement = () => {
132945
132987
  if (respawn === undefined || logFile === undefined) return;
132946
132988
  const servedMs = Date.now() - startedAt;
@@ -132971,16 +133013,21 @@ const timer = setInterval(() => {
132971
133013
  }
132972
133014
  if (now - lastChangeAt >= boundMs) {
132973
133015
  const message = "the front door's event loop did not run for " + String(now - lastChangeAt) + "ms; its watchdog ended the process so the next launch starts a fresh door on the same ports";
133016
+ stopped = true;
133017
+ clearInterval(timer);
132974
133018
  record(message);
132975
133019
  log(message);
133020
+ const [oneMinute, fiveMinutes, fifteenMinutes] = os.loadavg();
133021
+ log("machine load at the stall: " + oneMinute.toFixed(1) + " (1m), " + fiveMinutes.toFixed(1) + " (5m), " + fifteenMinutes.toFixed(1) + " (15m) across " + String(os.cpus().length) + " cpus");
132976
133022
  spawnReplacement();
132977
- stopped = true;
132978
- clearInterval(timer);
132979
- if (action === "kill-process") {
132980
- process.kill(ownPid, "SIGKILL");
132981
- } else {
132982
- parentPort.postMessage({ stalled: true, message });
132983
- }
133023
+ describeMainThread(checkEveryMs, action !== "kill-process").then((where) => {
133024
+ log(where);
133025
+ if (action === "kill-process") {
133026
+ process.kill(ownPid, "SIGKILL");
133027
+ } else {
133028
+ parentPort.postMessage({ stalled: true, message });
133029
+ }
133030
+ });
132984
133031
  }
132985
133032
  }, checkEveryMs);
132986
133033
  parentPort.on("message", (message) => {
@@ -133592,7 +133639,8 @@ function registerFrontDoorCommand(program2, deps) {
133592
133639
  const awaited = Number(process.env[DOOR_AWAIT_PID_ENV]);
133593
133640
  Reflect.deleteProperty(process.env, DOOR_AWAIT_PID_ENV);
133594
133641
  if (Number.isInteger(awaited) && awaited > 0) {
133595
- await awaitPidExit(awaited, DOOR_STALL_BOUND_MS, supervisorPorts);
133642
+ const waitedMs = await awaitPidExit(awaited, supervisorPorts);
133643
+ supervisorPorts.log(`frontdoor ${String(ownPid)}: stalled door ${String(awaited)} released the sticky ports after ${String(waitedMs)}ms`);
133596
133644
  }
133597
133645
  declareThisProcessTheFrontDoor();
133598
133646
  deps.exit(await runFrontDoorSupervisor(idleShutdownMinutes, supervisorPorts));
package/dist/index.cjs CHANGED
@@ -2928,7 +2928,7 @@ var init_package = __esm({
2928
2928
  "package.json"() {
2929
2929
  package_default = {
2930
2930
  name: "agent-shim",
2931
- version: "11.21.0",
2931
+ version: "11.22.0",
2932
2932
  description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
2933
2933
  license: "MIT",
2934
2934
  author: "Joseph Mearman <joseph@mearman.co.uk>",
package/dist/index.mjs CHANGED
@@ -2904,7 +2904,7 @@ var init_package = __esm({
2904
2904
  "package.json"() {
2905
2905
  package_default = {
2906
2906
  name: "agent-shim",
2907
- version: "11.21.0",
2907
+ version: "11.22.0",
2908
2908
  description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
2909
2909
  license: "MIT",
2910
2910
  author: "Joseph Mearman <joseph@mearman.co.uk>",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-shim",
3
- "version": "11.21.0",
3
+ "version": "11.22.0",
4
4
  "description": "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
5
5
  "license": "MIT",
6
6
  "author": "Joseph Mearman <joseph@mearman.co.uk>",