agent-shim 10.0.1 → 10.1.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
@@ -27535,6 +27535,8 @@ var init_state2 = __esm({
27535
27535
  settingsHash: external_exports.string().optional(),
27536
27536
  /** The install spec the running install was last installed from, so a `source` config change is detected as drift. */
27537
27537
  installedSource: external_exports.string().optional(),
27538
+ /** The install spec the supervisor is installing right now, present only while `uv tool install` runs, so a launcher that finds a live supervisor with no daemon yet keeps waiting for the install instead of counting it against its start bound. Cleared by the write that follows the install, whatever its outcome. */
27539
+ installing: external_exports.string().optional(),
27538
27540
  /** The last fatal error, kept across shutdowns so `headroom status` can explain a daemon that is not running. */
27539
27541
  lastError: external_exports.string().optional()
27540
27542
  });
@@ -27634,7 +27636,7 @@ function daemonAdmits(fs22, allowlistFile, recordedHash, required2) {
27634
27636
  }
27635
27637
  function ensureHeadroom(params) {
27636
27638
  const { paths, ports } = params;
27637
- const deadline = ports.now() + HEADROOM_START_TIMEOUT_MS;
27639
+ let deadline = ports.now() + HEADROOM_START_TIMEOUT_MS;
27638
27640
  let spawnedSupervisor = false;
27639
27641
  migrateHeadroomState(ports.fs, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning);
27640
27642
  const commandLines = /* @__PURE__ */ new Map();
@@ -27648,6 +27650,9 @@ function ensureHeadroom(params) {
27648
27650
  let awaiting;
27649
27651
  const state = resolveServingHeadroomState(ports.fs, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning)?.state;
27650
27652
  if (state?.supervisorPid !== void 0 && ports.isRunning(state.supervisorPid)) {
27653
+ if (state.installing !== void 0) {
27654
+ deadline = ports.now() + HEADROOM_START_TIMEOUT_MS;
27655
+ }
27651
27656
  const daemonUp = state.socketPath !== void 0 && state.headroomPid !== void 0 && ports.isRunning(state.headroomPid);
27652
27657
  if (daemonUp && state.socketPath !== void 0 && state.headroomPid !== void 0) {
27653
27658
  const required2 = params.requiredUpstreams?.();
@@ -28249,15 +28254,16 @@ async function runSupervisor(initialConfig, ports, options = {}) {
28249
28254
  const commitOk = pinned === void 0 || ports.installedCommit() === pinned;
28250
28255
  if (versionOk && commitOk && (installedSource === void 0 || installedSource === config2.source)) {
28251
28256
  installedSource = config2.source;
28252
- return true;
28257
+ return void 0;
28253
28258
  }
28254
28259
  ports.log(`agent-shim headroom supervisor: installing headroom from ${config2.source}`);
28260
+ writeOwnState({ supervisorPid: ports.ownPid, installedSource, installing: config2.source });
28255
28261
  const result = ports.install(config2.source);
28256
28262
  if (!result.ok) {
28257
- return false;
28263
+ return `could not install headroom from ${config2.source}: ${result.error ?? "install failed"}`;
28258
28264
  }
28259
28265
  installedSource = config2.source;
28260
- return true;
28266
+ return void 0;
28261
28267
  };
28262
28268
  const socket = prepareHeadroomSocket(fs22, ports.socketTrust, paths, ports.ownPid);
28263
28269
  if (socket.refused !== void 0) {
@@ -28266,8 +28272,9 @@ async function runSupervisor(initialConfig, ports, options = {}) {
28266
28272
  const { socketPath } = socket;
28267
28273
  pruneStaleHeadroomSockets(fs22, paths, ports.isRunning);
28268
28274
  pruneStaleAllowlistTemporaries(fs22, paths.headroomAllowlistFile, ports.isRunning);
28269
- if (!ensureInstalled()) {
28270
- return fail(`could not install headroom from ${config2.source}: install failed (is uv installed and on PATH?)`);
28275
+ const installFailure = ensureInstalled();
28276
+ if (installFailure !== void 0) {
28277
+ return fail(installFailure);
28271
28278
  }
28272
28279
  const version2 = ports.headroomVersion() ?? "unknown";
28273
28280
  writeOwnState({ supervisorPid: ports.ownPid, version: version2, installedSource });
@@ -28342,8 +28349,9 @@ async function runSupervisor(initialConfig, ports, options = {}) {
28342
28349
  `headroom failed to become ready ${String(consecutiveFailures)} times in a row; giving up` + (lastExitOutput === void 0 ? "" : `; the last attempt exited before it was ready, and its log ends: ${lastExitOutput}`)
28343
28350
  );
28344
28351
  }
28345
- if (installedSource !== config2.source && !ensureInstalled()) {
28346
- return fail(`could not install headroom from ${config2.source}: install failed (is uv installed and on PATH?)`);
28352
+ const restartInstallFailure = installedSource !== config2.source ? ensureInstalled() : void 0;
28353
+ if (restartInstallFailure !== void 0) {
28354
+ return fail(restartInstallFailure);
28347
28355
  }
28348
28356
  const logOffset = ports.daemonLogSize();
28349
28357
  const pid = ports.spawnHeadroom(socketPath, paths.headroomAllowlistFile, config2.settings);
@@ -33355,6 +33363,8 @@ var init_schema2 = __esm({
33355
33363
  sessionId: external_exports.string().optional(),
33356
33364
  /** The project the launch ran in (its git repository root), when the launch sent one: headroom launches do. */
33357
33365
  project: external_exports.string().optional(),
33366
+ /** Whether the request crossed headroom on its way upstream. Absent on a record written before the door recorded it, and false when the request went direct. */
33367
+ viaHeadroom: external_exports.boolean().optional(),
33358
33368
  /** The front-door route that served the request. */
33359
33369
  route: external_exports.string(),
33360
33370
  method: external_exports.string(),
@@ -33959,7 +33969,7 @@ var init_package = __esm({
33959
33969
  "package.json"() {
33960
33970
  package_default = {
33961
33971
  name: "agent-shim",
33962
- version: "10.0.1",
33972
+ version: "10.1.0",
33963
33973
  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.",
33964
33974
  license: "MIT",
33965
33975
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -34578,6 +34588,7 @@ function buildRecord(event, context) {
34578
34588
  provider,
34579
34589
  ...sessionId === void 0 ? {} : { sessionId },
34580
34590
  ...projectId === void 0 ? {} : { project: projectId },
34591
+ viaHeadroom: event.viaHeadroom,
34581
34592
  route: event.route,
34582
34593
  method: event.method,
34583
34594
  endpoint,
@@ -126375,7 +126386,7 @@ function createRoutedResponse(response, context) {
126375
126386
  start: (status, headers) => {
126376
126387
  for (const observe of deps.responseObservers) {
126377
126388
  try {
126378
- const body = observe({ session, route, method: request7.method, path: request7.path, receivedAt: request7.receivedAt, status, headers });
126389
+ const body = observe({ session, route, method: request7.method, path: request7.path, receivedAt: request7.receivedAt, viaHeadroom: request7.viaHeadroom, status, headers });
126379
126390
  if (body !== void 0) {
126380
126391
  bodyObservers.push(body);
126381
126392
  }
@@ -126416,7 +126427,7 @@ function createRoutedResponse(response, context) {
126416
126427
  };
126417
126428
  }
126418
126429
  async function serveRouted(request7, deps) {
126419
- const observed = { method: request7.method, path: pathOf(request7.url), receivedAt: deps.now() };
126430
+ const observed = { method: request7.method, path: pathOf(request7.url), receivedAt: deps.now(), viaHeadroom: false };
126420
126431
  const identified = identifyRequest(request7.headers);
126421
126432
  const admission = deps.admit({ url: request7.url, headers: request7.headers, forwardable: identified.forwardableHeaders });
126422
126433
  if (!admission.ok) {
@@ -126442,9 +126453,10 @@ async function serveRouted(request7, deps) {
126442
126453
  response2.end();
126443
126454
  return;
126444
126455
  }
126445
- const response = createRoutedResponse(request7.response, { deps, session: identified.session, route: resolution.route.name, request: observed });
126456
+ const viaHeadroom = identified.session.headroom && resolution.route.headroomEligible && deps.headroom !== void 0;
126457
+ const response = createRoutedResponse(request7.response, { deps, session: identified.session, route: resolution.route.name, request: { ...observed, viaHeadroom } });
126446
126458
  try {
126447
- if (identified.session.headroom && resolution.route.headroomEligible && deps.headroom !== void 0) {
126459
+ if (viaHeadroom) {
126448
126460
  await applyHeadroomHop(routed, response, resolution.route.headroomUpstream, deps.headroom);
126449
126461
  } else {
126450
126462
  await resolution.route.serve(routed, response);
@@ -141247,6 +141259,7 @@ function formatHeadroomStatus(status) {
141247
141259
  }
141248
141260
  var ownedHeadroom = /* @__PURE__ */ new Map();
141249
141261
  var exitedHeadroom = /* @__PURE__ */ new Set();
141262
+ var HEADROOM_INSTALL_TIMEOUT_MS = 6e5;
141250
141263
  var READY_FETCH_TIMEOUT_MS = 2e3;
141251
141264
  function headroomPidRunning(pid) {
141252
141265
  return !exitedHeadroom.has(pid) && realIsProcessRunning(pid);
@@ -141375,9 +141388,13 @@ function realSupervisorPorts(paths) {
141375
141388
  },
141376
141389
  ready: readyOverSocket,
141377
141390
  install: (spec) => {
141378
- const result = (0, import_node_child_process7.spawnSync)("uv", ["tool", "install", spec], { encoding: "utf8" });
141391
+ const result = (0, import_node_child_process7.spawnSync)("uv", ["tool", "install", spec], { encoding: "utf8", timeout: HEADROOM_INSTALL_TIMEOUT_MS });
141379
141392
  if (result.error !== void 0) {
141380
- return { ok: false, error: `uv is not installed or not on PATH (${result.error.message})` };
141393
+ const timedOut = "code" in result.error && result.error.code === "ETIMEDOUT";
141394
+ return {
141395
+ ok: false,
141396
+ error: timedOut ? `uv tool install did not finish within ${String(HEADROOM_INSTALL_TIMEOUT_MS)}ms and was stopped` : `uv is not installed or not on PATH (${result.error.message})`
141397
+ };
141381
141398
  }
141382
141399
  if (result.stdout !== "") {
141383
141400
  import_node_fs20.default.appendFileSync(paths.headroomLogPath, result.stdout);
package/dist/index.cjs CHANGED
@@ -2758,7 +2758,7 @@ var init_package = __esm({
2758
2758
  "package.json"() {
2759
2759
  package_default = {
2760
2760
  name: "agent-shim",
2761
- version: "10.0.1",
2761
+ version: "10.1.0",
2762
2762
  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.",
2763
2763
  license: "MIT",
2764
2764
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -3134,6 +3134,8 @@ var init_state2 = __esm({
3134
3134
  settingsHash: import_zod8.z.string().optional(),
3135
3135
  /** The install spec the running install was last installed from, so a `source` config change is detected as drift. */
3136
3136
  installedSource: import_zod8.z.string().optional(),
3137
+ /** The install spec the supervisor is installing right now, present only while `uv tool install` runs, so a launcher that finds a live supervisor with no daemon yet keeps waiting for the install instead of counting it against its start bound. Cleared by the write that follows the install, whatever its outcome. */
3138
+ installing: import_zod8.z.string().optional(),
3137
3139
  /** The last fatal error, kept across shutdowns so `headroom status` can explain a daemon that is not running. */
3138
3140
  lastError: import_zod8.z.string().optional()
3139
3141
  });
@@ -3233,7 +3235,7 @@ function daemonAdmits(fs12, allowlistFile, recordedHash, required) {
3233
3235
  }
3234
3236
  function ensureHeadroom(params) {
3235
3237
  const { paths, ports } = params;
3236
- const deadline = ports.now() + HEADROOM_START_TIMEOUT_MS;
3238
+ let deadline = ports.now() + HEADROOM_START_TIMEOUT_MS;
3237
3239
  let spawnedSupervisor = false;
3238
3240
  migrateHeadroomState(ports.fs, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning);
3239
3241
  const commandLines = /* @__PURE__ */ new Map();
@@ -3247,6 +3249,9 @@ function ensureHeadroom(params) {
3247
3249
  let awaiting;
3248
3250
  const state = resolveServingHeadroomState(ports.fs, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning)?.state;
3249
3251
  if (state?.supervisorPid !== void 0 && ports.isRunning(state.supervisorPid)) {
3252
+ if (state.installing !== void 0) {
3253
+ deadline = ports.now() + HEADROOM_START_TIMEOUT_MS;
3254
+ }
3250
3255
  const daemonUp = state.socketPath !== void 0 && state.headroomPid !== void 0 && ports.isRunning(state.headroomPid);
3251
3256
  if (daemonUp && state.socketPath !== void 0 && state.headroomPid !== void 0) {
3252
3257
  const required = params.requiredUpstreams?.();
@@ -3686,15 +3691,16 @@ async function runSupervisor(initialConfig, ports, options = {}) {
3686
3691
  const commitOk = pinned === void 0 || ports.installedCommit() === pinned;
3687
3692
  if (versionOk && commitOk && (installedSource === void 0 || installedSource === config.source)) {
3688
3693
  installedSource = config.source;
3689
- return true;
3694
+ return void 0;
3690
3695
  }
3691
3696
  ports.log(`agent-shim headroom supervisor: installing headroom from ${config.source}`);
3697
+ writeOwnState({ supervisorPid: ports.ownPid, installedSource, installing: config.source });
3692
3698
  const result = ports.install(config.source);
3693
3699
  if (!result.ok) {
3694
- return false;
3700
+ return `could not install headroom from ${config.source}: ${result.error ?? "install failed"}`;
3695
3701
  }
3696
3702
  installedSource = config.source;
3697
- return true;
3703
+ return void 0;
3698
3704
  };
3699
3705
  const socket = prepareHeadroomSocket(fs12, ports.socketTrust, paths, ports.ownPid);
3700
3706
  if (socket.refused !== void 0) {
@@ -3703,8 +3709,9 @@ async function runSupervisor(initialConfig, ports, options = {}) {
3703
3709
  const { socketPath } = socket;
3704
3710
  pruneStaleHeadroomSockets(fs12, paths, ports.isRunning);
3705
3711
  pruneStaleAllowlistTemporaries(fs12, paths.headroomAllowlistFile, ports.isRunning);
3706
- if (!ensureInstalled()) {
3707
- return fail(`could not install headroom from ${config.source}: install failed (is uv installed and on PATH?)`);
3712
+ const installFailure = ensureInstalled();
3713
+ if (installFailure !== void 0) {
3714
+ return fail(installFailure);
3708
3715
  }
3709
3716
  const version = ports.headroomVersion() ?? "unknown";
3710
3717
  writeOwnState({ supervisorPid: ports.ownPid, version, installedSource });
@@ -3779,8 +3786,9 @@ async function runSupervisor(initialConfig, ports, options = {}) {
3779
3786
  `headroom failed to become ready ${String(consecutiveFailures)} times in a row; giving up` + (lastExitOutput === void 0 ? "" : `; the last attempt exited before it was ready, and its log ends: ${lastExitOutput}`)
3780
3787
  );
3781
3788
  }
3782
- if (installedSource !== config.source && !ensureInstalled()) {
3783
- return fail(`could not install headroom from ${config.source}: install failed (is uv installed and on PATH?)`);
3789
+ const restartInstallFailure = installedSource !== config.source ? ensureInstalled() : void 0;
3790
+ if (restartInstallFailure !== void 0) {
3791
+ return fail(restartInstallFailure);
3784
3792
  }
3785
3793
  const logOffset = ports.daemonLogSize();
3786
3794
  const pid = ports.spawnHeadroom(socketPath, paths.headroomAllowlistFile, config.settings);
@@ -4616,6 +4624,8 @@ var init_schema2 = __esm({
4616
4624
  sessionId: import_zod10.z.string().optional(),
4617
4625
  /** The project the launch ran in (its git repository root), when the launch sent one: headroom launches do. */
4618
4626
  project: import_zod10.z.string().optional(),
4627
+ /** Whether the request crossed headroom on its way upstream. Absent on a record written before the door recorded it, and false when the request went direct. */
4628
+ viaHeadroom: import_zod10.z.boolean().optional(),
4619
4629
  /** The front-door route that served the request. */
4620
4630
  route: import_zod10.z.string(),
4621
4631
  method: import_zod10.z.string(),
package/dist/index.mjs CHANGED
@@ -2734,7 +2734,7 @@ var init_package = __esm({
2734
2734
  "package.json"() {
2735
2735
  package_default = {
2736
2736
  name: "agent-shim",
2737
- version: "10.0.1",
2737
+ version: "10.1.0",
2738
2738
  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.",
2739
2739
  license: "MIT",
2740
2740
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -3110,6 +3110,8 @@ var init_state2 = __esm({
3110
3110
  settingsHash: z8.string().optional(),
3111
3111
  /** The install spec the running install was last installed from, so a `source` config change is detected as drift. */
3112
3112
  installedSource: z8.string().optional(),
3113
+ /** The install spec the supervisor is installing right now, present only while `uv tool install` runs, so a launcher that finds a live supervisor with no daemon yet keeps waiting for the install instead of counting it against its start bound. Cleared by the write that follows the install, whatever its outcome. */
3114
+ installing: z8.string().optional(),
3113
3115
  /** The last fatal error, kept across shutdowns so `headroom status` can explain a daemon that is not running. */
3114
3116
  lastError: z8.string().optional()
3115
3117
  });
@@ -3209,7 +3211,7 @@ function daemonAdmits(fs12, allowlistFile, recordedHash, required) {
3209
3211
  }
3210
3212
  function ensureHeadroom(params) {
3211
3213
  const { paths, ports } = params;
3212
- const deadline = ports.now() + HEADROOM_START_TIMEOUT_MS;
3214
+ let deadline = ports.now() + HEADROOM_START_TIMEOUT_MS;
3213
3215
  let spawnedSupervisor = false;
3214
3216
  migrateHeadroomState(ports.fs, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning);
3215
3217
  const commandLines = /* @__PURE__ */ new Map();
@@ -3223,6 +3225,9 @@ function ensureHeadroom(params) {
3223
3225
  let awaiting;
3224
3226
  const state = resolveServingHeadroomState(ports.fs, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning)?.state;
3225
3227
  if (state?.supervisorPid !== void 0 && ports.isRunning(state.supervisorPid)) {
3228
+ if (state.installing !== void 0) {
3229
+ deadline = ports.now() + HEADROOM_START_TIMEOUT_MS;
3230
+ }
3226
3231
  const daemonUp = state.socketPath !== void 0 && state.headroomPid !== void 0 && ports.isRunning(state.headroomPid);
3227
3232
  if (daemonUp && state.socketPath !== void 0 && state.headroomPid !== void 0) {
3228
3233
  const required = params.requiredUpstreams?.();
@@ -3662,15 +3667,16 @@ async function runSupervisor(initialConfig, ports, options = {}) {
3662
3667
  const commitOk = pinned === void 0 || ports.installedCommit() === pinned;
3663
3668
  if (versionOk && commitOk && (installedSource === void 0 || installedSource === config.source)) {
3664
3669
  installedSource = config.source;
3665
- return true;
3670
+ return void 0;
3666
3671
  }
3667
3672
  ports.log(`agent-shim headroom supervisor: installing headroom from ${config.source}`);
3673
+ writeOwnState({ supervisorPid: ports.ownPid, installedSource, installing: config.source });
3668
3674
  const result = ports.install(config.source);
3669
3675
  if (!result.ok) {
3670
- return false;
3676
+ return `could not install headroom from ${config.source}: ${result.error ?? "install failed"}`;
3671
3677
  }
3672
3678
  installedSource = config.source;
3673
- return true;
3679
+ return void 0;
3674
3680
  };
3675
3681
  const socket = prepareHeadroomSocket(fs12, ports.socketTrust, paths, ports.ownPid);
3676
3682
  if (socket.refused !== void 0) {
@@ -3679,8 +3685,9 @@ async function runSupervisor(initialConfig, ports, options = {}) {
3679
3685
  const { socketPath } = socket;
3680
3686
  pruneStaleHeadroomSockets(fs12, paths, ports.isRunning);
3681
3687
  pruneStaleAllowlistTemporaries(fs12, paths.headroomAllowlistFile, ports.isRunning);
3682
- if (!ensureInstalled()) {
3683
- return fail(`could not install headroom from ${config.source}: install failed (is uv installed and on PATH?)`);
3688
+ const installFailure = ensureInstalled();
3689
+ if (installFailure !== void 0) {
3690
+ return fail(installFailure);
3684
3691
  }
3685
3692
  const version = ports.headroomVersion() ?? "unknown";
3686
3693
  writeOwnState({ supervisorPid: ports.ownPid, version, installedSource });
@@ -3755,8 +3762,9 @@ async function runSupervisor(initialConfig, ports, options = {}) {
3755
3762
  `headroom failed to become ready ${String(consecutiveFailures)} times in a row; giving up` + (lastExitOutput === void 0 ? "" : `; the last attempt exited before it was ready, and its log ends: ${lastExitOutput}`)
3756
3763
  );
3757
3764
  }
3758
- if (installedSource !== config.source && !ensureInstalled()) {
3759
- return fail(`could not install headroom from ${config.source}: install failed (is uv installed and on PATH?)`);
3765
+ const restartInstallFailure = installedSource !== config.source ? ensureInstalled() : void 0;
3766
+ if (restartInstallFailure !== void 0) {
3767
+ return fail(restartInstallFailure);
3760
3768
  }
3761
3769
  const logOffset = ports.daemonLogSize();
3762
3770
  const pid = ports.spawnHeadroom(socketPath, paths.headroomAllowlistFile, config.settings);
@@ -4590,6 +4598,8 @@ var init_schema2 = __esm({
4590
4598
  sessionId: z10.string().optional(),
4591
4599
  /** The project the launch ran in (its git repository root), when the launch sent one: headroom launches do. */
4592
4600
  project: z10.string().optional(),
4601
+ /** Whether the request crossed headroom on its way upstream. Absent on a record written before the door recorded it, and false when the request went direct. */
4602
+ viaHeadroom: z10.boolean().optional(),
4593
4603
  /** The front-door route that served the request. */
4594
4604
  route: z10.string(),
4595
4605
  method: z10.string(),
@@ -5206,6 +5206,7 @@ declare const UsageRecordSchema: z.ZodObject<{
5206
5206
  provider: z.ZodString;
5207
5207
  sessionId: z.ZodOptional<z.ZodString>;
5208
5208
  project: z.ZodOptional<z.ZodString>;
5209
+ viaHeadroom: z.ZodOptional<z.ZodBoolean>;
5209
5210
  route: z.ZodString;
5210
5211
  method: z.ZodString;
5211
5212
  endpoint: z.ZodString;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-shim",
3
- "version": "10.0.1",
3
+ "version": "10.1.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>",