agent-shim 8.12.0 → 8.14.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
@@ -61710,7 +61710,7 @@ function registerIdentityCommand(program2, deps) {
61710
61710
  // package.json
61711
61711
  var package_default = {
61712
61712
  name: "agent-shim",
61713
- version: "8.12.0",
61713
+ version: "8.14.0",
61714
61714
  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.",
61715
61715
  license: "MIT",
61716
61716
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -71793,31 +71793,54 @@ function credentialOfJson(parsed) {
71793
71793
  anthropicClientPlatform: typeof anthropicClientPlatform === "string" ? anthropicClientPlatform : void 0
71794
71794
  };
71795
71795
  }
71796
+ function sequenceNumOfJson(value2) {
71797
+ return typeof value2 === "number" && Number.isInteger(value2) && value2 >= 0 ? value2 : void 0;
71798
+ }
71796
71799
  function createRcCredentialStore(fs19, dir) {
71797
71800
  fs19.mkdirPrivate(dir);
71798
71801
  const fileFor = (sessionId) => import_node_path32.default.join(dir, `${sessionId}.json`);
71802
+ const readParsed = (sessionId) => {
71803
+ const raw = fs19.readFileUtf8(fileFor(sessionId));
71804
+ if (raw === void 0) {
71805
+ return void 0;
71806
+ }
71807
+ let parsed;
71808
+ try {
71809
+ parsed = JSON.parse(raw);
71810
+ } catch {
71811
+ return void 0;
71812
+ }
71813
+ return isRecord4(parsed) ? parsed : void 0;
71814
+ };
71799
71815
  return {
71800
71816
  read: (sessionId) => {
71801
71817
  if (!isSafeSessionId(sessionId)) {
71802
71818
  return void 0;
71803
71819
  }
71804
- const raw = fs19.readFileUtf8(fileFor(sessionId));
71805
- if (raw === void 0) {
71806
- return void 0;
71820
+ return credentialOfJson(readParsed(sessionId));
71821
+ },
71822
+ write: (sessionId, credential) => {
71823
+ if (!isSafeSessionId(sessionId)) {
71824
+ return;
71807
71825
  }
71808
- let parsed;
71809
- try {
71810
- parsed = JSON.parse(raw);
71811
- } catch {
71826
+ const cursor3 = sequenceNumOfJson(readParsed(sessionId)?.highestSequenceNum);
71827
+ const record2 = { ...credential, ...cursor3 === void 0 ? {} : { highestSequenceNum: cursor3 } };
71828
+ fs19.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record2, null, 2)}
71829
+ `);
71830
+ },
71831
+ readCursor: (sessionId) => {
71832
+ if (!isSafeSessionId(sessionId)) {
71812
71833
  return void 0;
71813
71834
  }
71814
- return credentialOfJson(parsed);
71835
+ return sequenceNumOfJson(readParsed(sessionId)?.highestSequenceNum);
71815
71836
  },
71816
- write: (sessionId, credential) => {
71837
+ writeCursor: (sessionId, highestSequenceNum) => {
71817
71838
  if (!isSafeSessionId(sessionId)) {
71818
71839
  return;
71819
71840
  }
71820
- fs19.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(credential, null, 2)}
71841
+ const credential = credentialOfJson(readParsed(sessionId));
71842
+ const record2 = credential === void 0 ? { highestSequenceNum } : { ...credential, highestSequenceNum };
71843
+ fs19.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record2, null, 2)}
71821
71844
  `);
71822
71845
  },
71823
71846
  remove: (sessionId) => {
@@ -72643,6 +72666,18 @@ function createRcEventFanout() {
72643
72666
  }
72644
72667
  function createRcStreamHub(deps) {
72645
72668
  const attachments = /* @__PURE__ */ new Map();
72669
+ const lastSavedSequenceNums = /* @__PURE__ */ new Map();
72670
+ const persistCursor = (sessionId) => {
72671
+ if (deps.saveSequenceNum === void 0) {
72672
+ return;
72673
+ }
72674
+ const cursor3 = deps.sequenceNumOf(sessionId);
72675
+ if (cursor3 === void 0 || cursor3 === lastSavedSequenceNums.get(sessionId)) {
72676
+ return;
72677
+ }
72678
+ deps.saveSequenceNum(sessionId, cursor3);
72679
+ lastSavedSequenceNums.set(sessionId, cursor3);
72680
+ };
72646
72681
  const birth = (sessionId) => {
72647
72682
  const controller = new AbortController();
72648
72683
  let stopped = false;
@@ -72679,7 +72714,7 @@ function createRcStreamHub(deps) {
72679
72714
  if (!isSuccessful3(presence.status)) {
72680
72715
  throw new Error(`the presence call answered HTTP ${String(presence.status)}: ${presence.body}`);
72681
72716
  }
72682
- const cursor3 = deps.sequenceNumOf(attachment.sessionId);
72717
+ const cursor3 = deps.sequenceNumOf(attachment.sessionId) ?? deps.storedSequenceNumOf?.(attachment.sessionId);
72683
72718
  const resume = cursor3 === void 0 ? void 0 : { fromSequenceNum: cursor3 };
72684
72719
  const answer = await deps.dial.openStream(attachment.sessionId, headers, resume, attachment.controller.signal);
72685
72720
  if (answer.status === HTTP_STATUS.unauthorized) {
@@ -72713,6 +72748,7 @@ function createRcStreamHub(deps) {
72713
72748
  const credential = deps.credentialOf(attachment.sessionId);
72714
72749
  if (!live || credential?.authorization === void 0) {
72715
72750
  deps.log?.(`rc stream ${attachment.sessionId}: the attachment ended (${live ? "the session's client credential is no longer known" : "the tracker gave up on the session"})`);
72751
+ persistCursor(attachment.sessionId);
72716
72752
  if (attachments.get(attachment.sessionId) === attachment) {
72717
72753
  attachments.delete(attachment.sessionId);
72718
72754
  }
@@ -72722,6 +72758,7 @@ function createRcStreamHub(deps) {
72722
72758
  try {
72723
72759
  outcome = await attempt(attachment, credential);
72724
72760
  } catch (error62) {
72761
+ persistCursor(attachment.sessionId);
72725
72762
  if (attachment.isStopped()) {
72726
72763
  return;
72727
72764
  }
@@ -72734,6 +72771,7 @@ function createRcStreamHub(deps) {
72734
72771
  return;
72735
72772
  }
72736
72773
  if (outcome === "dropped") {
72774
+ persistCursor(attachment.sessionId);
72737
72775
  deps.log?.(`rc stream ${attachment.sessionId}: the stream ended of its own accord, reconnecting`);
72738
72776
  retriedUnauthorized = false;
72739
72777
  continue;
@@ -72772,6 +72810,7 @@ function createRcStreamHub(deps) {
72772
72810
  },
72773
72811
  close: () => {
72774
72812
  for (const attachment of attachments.values()) {
72813
+ persistCursor(attachment.sessionId);
72775
72814
  attachment.stop();
72776
72815
  }
72777
72816
  attachments.clear();
@@ -73107,7 +73146,8 @@ function realFrontDoorSupervisorPorts(paths) {
73107
73146
  credentialRecord: () => readRcSelfHostRecord(realFarmFs, paths.frontdoorDir),
73108
73147
  log
73109
73148
  }) : void 0;
73110
- const rcTracker = createRcSessionTracker({ now: () => Date.now(), idleMs: RC_IDLE_EXPIRY_MS, credentialStore: createRcCredentialStore(realFarmFs, paths.frontdoorRcCredentialsDir) });
73149
+ const rcCredentialStore = createRcCredentialStore(realFarmFs, paths.frontdoorRcCredentialsDir);
73150
+ const rcTracker = createRcSessionTracker({ now: () => Date.now(), idleMs: RC_IDLE_EXPIRY_MS, credentialStore: rcCredentialStore });
73111
73151
  const rcFanout = createRcEventFanout();
73112
73152
  const rcHub = createRcStreamHub({
73113
73153
  now: () => Date.now(),
@@ -73115,6 +73155,8 @@ function realFrontDoorSupervisorPorts(paths) {
73115
73155
  trackedSessions: () => rcTracker.list().map((session) => session.id),
73116
73156
  fileStreamEvent: rcTracker.fileStreamEvent,
73117
73157
  sequenceNumOf: rcTracker.sequenceNumOf,
73158
+ storedSequenceNumOf: rcCredentialStore.readCursor,
73159
+ saveSequenceNum: rcCredentialStore.writeCursor,
73118
73160
  dial: rcSelfHost ? lateRcStreamDial(rcSelfHostDialTarget) : realRcStreamDial(),
73119
73161
  fanout: rcFanout,
73120
73162
  newClientId: import_node_crypto12.randomUUID,
package/dist/index.cjs CHANGED
@@ -203,6 +203,7 @@ __export(index_exports, {
203
203
  runCheck: () => runCheck,
204
204
  runDoctor: () => runDoctor,
205
205
  runFrontDoorSupervisor: () => runFrontDoorSupervisor,
206
+ runLauncher: () => runLauncher,
206
207
  runSupervisor: () => runSupervisor,
207
208
  servedByPipeline: () => servedByPipeline,
208
209
  setAllowAmbientCredential: () => setAllowAmbientCredential,
@@ -217,6 +218,7 @@ __export(index_exports, {
217
218
  setRcSessionModel: () => setRcSessionModel,
218
219
  setRcSessionPermissionMode: () => setRcSessionPermissionMode,
219
220
  snapshotPath: () => snapshotPath,
221
+ spawnClaude: () => spawnClaude,
220
222
  startConnectServer: () => startConnectServer,
221
223
  topLevelNames: () => topLevelNames,
222
224
  updateDirectoryRule: () => updateDirectoryRule,
@@ -4939,31 +4941,54 @@ function credentialOfJson(parsed) {
4939
4941
  anthropicClientPlatform: typeof anthropicClientPlatform === "string" ? anthropicClientPlatform : void 0
4940
4942
  };
4941
4943
  }
4944
+ function sequenceNumOfJson(value) {
4945
+ return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
4946
+ }
4942
4947
  function createRcCredentialStore(fs12, dir) {
4943
4948
  fs12.mkdirPrivate(dir);
4944
4949
  const fileFor = (sessionId) => import_node_path9.default.join(dir, `${sessionId}.json`);
4950
+ const readParsed = (sessionId) => {
4951
+ const raw = fs12.readFileUtf8(fileFor(sessionId));
4952
+ if (raw === void 0) {
4953
+ return void 0;
4954
+ }
4955
+ let parsed;
4956
+ try {
4957
+ parsed = JSON.parse(raw);
4958
+ } catch {
4959
+ return void 0;
4960
+ }
4961
+ return isRecord3(parsed) ? parsed : void 0;
4962
+ };
4945
4963
  return {
4946
4964
  read: (sessionId) => {
4947
4965
  if (!isSafeSessionId(sessionId)) {
4948
4966
  return void 0;
4949
4967
  }
4950
- const raw = fs12.readFileUtf8(fileFor(sessionId));
4951
- if (raw === void 0) {
4952
- return void 0;
4968
+ return credentialOfJson(readParsed(sessionId));
4969
+ },
4970
+ write: (sessionId, credential) => {
4971
+ if (!isSafeSessionId(sessionId)) {
4972
+ return;
4953
4973
  }
4954
- let parsed;
4955
- try {
4956
- parsed = JSON.parse(raw);
4957
- } catch {
4974
+ const cursor = sequenceNumOfJson(readParsed(sessionId)?.highestSequenceNum);
4975
+ const record = { ...credential, ...cursor === void 0 ? {} : { highestSequenceNum: cursor } };
4976
+ fs12.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
4977
+ `);
4978
+ },
4979
+ readCursor: (sessionId) => {
4980
+ if (!isSafeSessionId(sessionId)) {
4958
4981
  return void 0;
4959
4982
  }
4960
- return credentialOfJson(parsed);
4983
+ return sequenceNumOfJson(readParsed(sessionId)?.highestSequenceNum);
4961
4984
  },
4962
- write: (sessionId, credential) => {
4985
+ writeCursor: (sessionId, highestSequenceNum) => {
4963
4986
  if (!isSafeSessionId(sessionId)) {
4964
4987
  return;
4965
4988
  }
4966
- fs12.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(credential, null, 2)}
4989
+ const credential = credentialOfJson(readParsed(sessionId));
4990
+ const record = credential === void 0 ? { highestSequenceNum } : { ...credential, highestSequenceNum };
4991
+ fs12.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
4967
4992
  `);
4968
4993
  },
4969
4994
  remove: (sessionId) => {
@@ -5298,6 +5323,18 @@ function createRcEventFanout() {
5298
5323
  }
5299
5324
  function createRcStreamHub(deps) {
5300
5325
  const attachments = /* @__PURE__ */ new Map();
5326
+ const lastSavedSequenceNums = /* @__PURE__ */ new Map();
5327
+ const persistCursor = (sessionId) => {
5328
+ if (deps.saveSequenceNum === void 0) {
5329
+ return;
5330
+ }
5331
+ const cursor = deps.sequenceNumOf(sessionId);
5332
+ if (cursor === void 0 || cursor === lastSavedSequenceNums.get(sessionId)) {
5333
+ return;
5334
+ }
5335
+ deps.saveSequenceNum(sessionId, cursor);
5336
+ lastSavedSequenceNums.set(sessionId, cursor);
5337
+ };
5301
5338
  const birth = (sessionId) => {
5302
5339
  const controller = new AbortController();
5303
5340
  let stopped = false;
@@ -5334,7 +5371,7 @@ function createRcStreamHub(deps) {
5334
5371
  if (!isSuccessful3(presence.status)) {
5335
5372
  throw new Error(`the presence call answered HTTP ${String(presence.status)}: ${presence.body}`);
5336
5373
  }
5337
- const cursor = deps.sequenceNumOf(attachment.sessionId);
5374
+ const cursor = deps.sequenceNumOf(attachment.sessionId) ?? deps.storedSequenceNumOf?.(attachment.sessionId);
5338
5375
  const resume = cursor === void 0 ? void 0 : { fromSequenceNum: cursor };
5339
5376
  const answer = await deps.dial.openStream(attachment.sessionId, headers, resume, attachment.controller.signal);
5340
5377
  if (answer.status === HTTP_STATUS.unauthorized) {
@@ -5368,6 +5405,7 @@ function createRcStreamHub(deps) {
5368
5405
  const credential = deps.credentialOf(attachment.sessionId);
5369
5406
  if (!live || credential?.authorization === void 0) {
5370
5407
  deps.log?.(`rc stream ${attachment.sessionId}: the attachment ended (${live ? "the session's client credential is no longer known" : "the tracker gave up on the session"})`);
5408
+ persistCursor(attachment.sessionId);
5371
5409
  if (attachments.get(attachment.sessionId) === attachment) {
5372
5410
  attachments.delete(attachment.sessionId);
5373
5411
  }
@@ -5377,6 +5415,7 @@ function createRcStreamHub(deps) {
5377
5415
  try {
5378
5416
  outcome = await attempt(attachment, credential);
5379
5417
  } catch (error) {
5418
+ persistCursor(attachment.sessionId);
5380
5419
  if (attachment.isStopped()) {
5381
5420
  return;
5382
5421
  }
@@ -5389,6 +5428,7 @@ function createRcStreamHub(deps) {
5389
5428
  return;
5390
5429
  }
5391
5430
  if (outcome === "dropped") {
5431
+ persistCursor(attachment.sessionId);
5392
5432
  deps.log?.(`rc stream ${attachment.sessionId}: the stream ended of its own accord, reconnecting`);
5393
5433
  retriedUnauthorized = false;
5394
5434
  continue;
@@ -5427,6 +5467,7 @@ function createRcStreamHub(deps) {
5427
5467
  },
5428
5468
  close: () => {
5429
5469
  for (const attachment of attachments.values()) {
5470
+ persistCursor(attachment.sessionId);
5430
5471
  attachment.stop();
5431
5472
  }
5432
5473
  attachments.clear();
@@ -10642,6 +10683,29 @@ function splitExtraFlags(value) {
10642
10683
  return trimmed.split(/\s+/);
10643
10684
  }
10644
10685
 
10686
+ // src/launcher/spawn.ts
10687
+ var import_node_os5 = __toESM(require("node:os"), 1);
10688
+ var SIGNAL_EXIT_CODE_OFFSET = 128;
10689
+ function exitCodeFor(result) {
10690
+ if (result.status !== null) {
10691
+ return result.status;
10692
+ }
10693
+ if (result.signal !== null) {
10694
+ return SIGNAL_EXIT_CODE_OFFSET + import_node_os5.default.constants.signals[result.signal];
10695
+ }
10696
+ return 1;
10697
+ }
10698
+ function spawnClaude(params) {
10699
+ const result = params.spawn.spawnSync(params.bin, params.args, { stdio: "inherit", env: params.env });
10700
+ if (result.error !== void 0) {
10701
+ throw result.error;
10702
+ }
10703
+ if (params.beforeExit !== void 0) {
10704
+ params.beforeExit();
10705
+ }
10706
+ return params.proc.exit(exitCodeFor(result));
10707
+ }
10708
+
10645
10709
  // src/launcher.ts
10646
10710
  function resolveIdentityCredential(identity, credential, env, port) {
10647
10711
  if (port === void 0) {
@@ -10918,9 +10982,17 @@ function prepareLaunch(params) {
10918
10982
  };
10919
10983
  return { bin: discovered.path, args: finalArgv, env: finalEnv, release };
10920
10984
  }
10985
+ function runLauncher(params) {
10986
+ const plan = prepareLaunch(params);
10987
+ try {
10988
+ spawnClaude({ bin: plan.bin, args: plan.args, env: plan.env, spawn: params.spawn, proc: params.proc, beforeExit: plan.release });
10989
+ } finally {
10990
+ plan.release();
10991
+ }
10992
+ }
10921
10993
 
10922
10994
  // src/launchWiring.ts
10923
- var import_node_os5 = __toESM(require("node:os"), 1);
10995
+ var import_node_os6 = __toESM(require("node:os"), 1);
10924
10996
  var import_node_crypto12 = require("node:crypto");
10925
10997
 
10926
10998
  // src/frontdoor/realFrontDoorPort.ts
@@ -11069,7 +11141,7 @@ function realFrontDoorPort(paths, spawnDaemon) {
11069
11141
 
11070
11142
  // src/launchWiring.ts
11071
11143
  function buildFarmRuntime(paths, cwd) {
11072
- const home = import_node_os5.default.homedir();
11144
+ const home = import_node_os6.default.homedir();
11073
11145
  const read = cosmiconfigReader();
11074
11146
  const classification = loadClassification(paths);
11075
11147
  const loaded = loadCascadeInput({ paths, home, cwd, read });
@@ -11330,6 +11402,7 @@ function prepareClaudeLaunch(options) {
11330
11402
  runCheck,
11331
11403
  runDoctor,
11332
11404
  runFrontDoorSupervisor,
11405
+ runLauncher,
11333
11406
  runSupervisor,
11334
11407
  servedByPipeline,
11335
11408
  setAllowAmbientCredential,
@@ -11344,6 +11417,7 @@ function prepareClaudeLaunch(options) {
11344
11417
  setRcSessionModel,
11345
11418
  setRcSessionPermissionMode,
11346
11419
  snapshotPath,
11420
+ spawnClaude,
11347
11421
  startConnectServer,
11348
11422
  topLevelNames,
11349
11423
  updateDirectoryRule,
package/dist/index.mjs CHANGED
@@ -4711,31 +4711,54 @@ function credentialOfJson(parsed) {
4711
4711
  anthropicClientPlatform: typeof anthropicClientPlatform === "string" ? anthropicClientPlatform : void 0
4712
4712
  };
4713
4713
  }
4714
+ function sequenceNumOfJson(value) {
4715
+ return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
4716
+ }
4714
4717
  function createRcCredentialStore(fs12, dir) {
4715
4718
  fs12.mkdirPrivate(dir);
4716
4719
  const fileFor = (sessionId) => path9.join(dir, `${sessionId}.json`);
4720
+ const readParsed = (sessionId) => {
4721
+ const raw = fs12.readFileUtf8(fileFor(sessionId));
4722
+ if (raw === void 0) {
4723
+ return void 0;
4724
+ }
4725
+ let parsed;
4726
+ try {
4727
+ parsed = JSON.parse(raw);
4728
+ } catch {
4729
+ return void 0;
4730
+ }
4731
+ return isRecord3(parsed) ? parsed : void 0;
4732
+ };
4717
4733
  return {
4718
4734
  read: (sessionId) => {
4719
4735
  if (!isSafeSessionId(sessionId)) {
4720
4736
  return void 0;
4721
4737
  }
4722
- const raw = fs12.readFileUtf8(fileFor(sessionId));
4723
- if (raw === void 0) {
4724
- return void 0;
4738
+ return credentialOfJson(readParsed(sessionId));
4739
+ },
4740
+ write: (sessionId, credential) => {
4741
+ if (!isSafeSessionId(sessionId)) {
4742
+ return;
4725
4743
  }
4726
- let parsed;
4727
- try {
4728
- parsed = JSON.parse(raw);
4729
- } catch {
4744
+ const cursor = sequenceNumOfJson(readParsed(sessionId)?.highestSequenceNum);
4745
+ const record = { ...credential, ...cursor === void 0 ? {} : { highestSequenceNum: cursor } };
4746
+ fs12.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
4747
+ `);
4748
+ },
4749
+ readCursor: (sessionId) => {
4750
+ if (!isSafeSessionId(sessionId)) {
4730
4751
  return void 0;
4731
4752
  }
4732
- return credentialOfJson(parsed);
4753
+ return sequenceNumOfJson(readParsed(sessionId)?.highestSequenceNum);
4733
4754
  },
4734
- write: (sessionId, credential) => {
4755
+ writeCursor: (sessionId, highestSequenceNum) => {
4735
4756
  if (!isSafeSessionId(sessionId)) {
4736
4757
  return;
4737
4758
  }
4738
- fs12.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(credential, null, 2)}
4759
+ const credential = credentialOfJson(readParsed(sessionId));
4760
+ const record = credential === void 0 ? { highestSequenceNum } : { ...credential, highestSequenceNum };
4761
+ fs12.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
4739
4762
  `);
4740
4763
  },
4741
4764
  remove: (sessionId) => {
@@ -5070,6 +5093,18 @@ function createRcEventFanout() {
5070
5093
  }
5071
5094
  function createRcStreamHub(deps) {
5072
5095
  const attachments = /* @__PURE__ */ new Map();
5096
+ const lastSavedSequenceNums = /* @__PURE__ */ new Map();
5097
+ const persistCursor = (sessionId) => {
5098
+ if (deps.saveSequenceNum === void 0) {
5099
+ return;
5100
+ }
5101
+ const cursor = deps.sequenceNumOf(sessionId);
5102
+ if (cursor === void 0 || cursor === lastSavedSequenceNums.get(sessionId)) {
5103
+ return;
5104
+ }
5105
+ deps.saveSequenceNum(sessionId, cursor);
5106
+ lastSavedSequenceNums.set(sessionId, cursor);
5107
+ };
5073
5108
  const birth = (sessionId) => {
5074
5109
  const controller = new AbortController();
5075
5110
  let stopped = false;
@@ -5106,7 +5141,7 @@ function createRcStreamHub(deps) {
5106
5141
  if (!isSuccessful3(presence.status)) {
5107
5142
  throw new Error(`the presence call answered HTTP ${String(presence.status)}: ${presence.body}`);
5108
5143
  }
5109
- const cursor = deps.sequenceNumOf(attachment.sessionId);
5144
+ const cursor = deps.sequenceNumOf(attachment.sessionId) ?? deps.storedSequenceNumOf?.(attachment.sessionId);
5110
5145
  const resume = cursor === void 0 ? void 0 : { fromSequenceNum: cursor };
5111
5146
  const answer = await deps.dial.openStream(attachment.sessionId, headers, resume, attachment.controller.signal);
5112
5147
  if (answer.status === HTTP_STATUS.unauthorized) {
@@ -5140,6 +5175,7 @@ function createRcStreamHub(deps) {
5140
5175
  const credential = deps.credentialOf(attachment.sessionId);
5141
5176
  if (!live || credential?.authorization === void 0) {
5142
5177
  deps.log?.(`rc stream ${attachment.sessionId}: the attachment ended (${live ? "the session's client credential is no longer known" : "the tracker gave up on the session"})`);
5178
+ persistCursor(attachment.sessionId);
5143
5179
  if (attachments.get(attachment.sessionId) === attachment) {
5144
5180
  attachments.delete(attachment.sessionId);
5145
5181
  }
@@ -5149,6 +5185,7 @@ function createRcStreamHub(deps) {
5149
5185
  try {
5150
5186
  outcome = await attempt(attachment, credential);
5151
5187
  } catch (error) {
5188
+ persistCursor(attachment.sessionId);
5152
5189
  if (attachment.isStopped()) {
5153
5190
  return;
5154
5191
  }
@@ -5161,6 +5198,7 @@ function createRcStreamHub(deps) {
5161
5198
  return;
5162
5199
  }
5163
5200
  if (outcome === "dropped") {
5201
+ persistCursor(attachment.sessionId);
5164
5202
  deps.log?.(`rc stream ${attachment.sessionId}: the stream ended of its own accord, reconnecting`);
5165
5203
  retriedUnauthorized = false;
5166
5204
  continue;
@@ -5199,6 +5237,7 @@ function createRcStreamHub(deps) {
5199
5237
  },
5200
5238
  close: () => {
5201
5239
  for (const attachment of attachments.values()) {
5240
+ persistCursor(attachment.sessionId);
5202
5241
  attachment.stop();
5203
5242
  }
5204
5243
  attachments.clear();
@@ -10414,6 +10453,29 @@ function splitExtraFlags(value) {
10414
10453
  return trimmed.split(/\s+/);
10415
10454
  }
10416
10455
 
10456
+ // src/launcher/spawn.ts
10457
+ import os6 from "node:os";
10458
+ var SIGNAL_EXIT_CODE_OFFSET = 128;
10459
+ function exitCodeFor(result) {
10460
+ if (result.status !== null) {
10461
+ return result.status;
10462
+ }
10463
+ if (result.signal !== null) {
10464
+ return SIGNAL_EXIT_CODE_OFFSET + os6.constants.signals[result.signal];
10465
+ }
10466
+ return 1;
10467
+ }
10468
+ function spawnClaude(params) {
10469
+ const result = params.spawn.spawnSync(params.bin, params.args, { stdio: "inherit", env: params.env });
10470
+ if (result.error !== void 0) {
10471
+ throw result.error;
10472
+ }
10473
+ if (params.beforeExit !== void 0) {
10474
+ params.beforeExit();
10475
+ }
10476
+ return params.proc.exit(exitCodeFor(result));
10477
+ }
10478
+
10417
10479
  // src/launcher.ts
10418
10480
  function resolveIdentityCredential(identity, credential, env, port) {
10419
10481
  if (port === void 0) {
@@ -10690,9 +10752,17 @@ function prepareLaunch(params) {
10690
10752
  };
10691
10753
  return { bin: discovered.path, args: finalArgv, env: finalEnv, release };
10692
10754
  }
10755
+ function runLauncher(params) {
10756
+ const plan = prepareLaunch(params);
10757
+ try {
10758
+ spawnClaude({ bin: plan.bin, args: plan.args, env: plan.env, spawn: params.spawn, proc: params.proc, beforeExit: plan.release });
10759
+ } finally {
10760
+ plan.release();
10761
+ }
10762
+ }
10693
10763
 
10694
10764
  // src/launchWiring.ts
10695
- import os6 from "node:os";
10765
+ import os7 from "node:os";
10696
10766
  import { randomUUID as randomUUID5 } from "node:crypto";
10697
10767
 
10698
10768
  // src/frontdoor/realFrontDoorPort.ts
@@ -10841,7 +10911,7 @@ function realFrontDoorPort(paths, spawnDaemon) {
10841
10911
 
10842
10912
  // src/launchWiring.ts
10843
10913
  function buildFarmRuntime(paths, cwd) {
10844
- const home = os6.homedir();
10914
+ const home = os7.homedir();
10845
10915
  const read = cosmiconfigReader();
10846
10916
  const classification = loadClassification(paths);
10847
10917
  const loaded = loadCascadeInput({ paths, home, cwd, read });
@@ -11101,6 +11171,7 @@ export {
11101
11171
  runCheck,
11102
11172
  runDoctor,
11103
11173
  runFrontDoorSupervisor,
11174
+ runLauncher,
11104
11175
  runSupervisor,
11105
11176
  servedByPipeline,
11106
11177
  setAllowAmbientCredential,
@@ -11115,6 +11186,7 @@ export {
11115
11186
  setRcSessionModel,
11116
11187
  setRcSessionPermissionMode,
11117
11188
  snapshotPath,
11189
+ spawnClaude,
11118
11190
  startConnectServer,
11119
11191
  topLevelNames,
11120
11192
  updateDirectoryRule,
@@ -1149,6 +1149,22 @@ interface FarmFs {
1149
1149
  /** A stable content hash of one file, or undefined when it is missing or is not a regular file. Used only to recognise farm data that has already been adopted into the canonical tree. */
1150
1150
  readonly hashFile: (path: string) => string | undefined;
1151
1151
  }
1152
+ /** The outcome of one `spawnSync` call, mirroring Node's own `SpawnSyncReturns` shape narrowly to what the launcher actually reads. */
1153
+ interface SpawnResult {
1154
+ /** The child's exit code, or null when it was terminated by a signal instead of exiting normally. */
1155
+ readonly status: number | null;
1156
+ /** The signal that terminated the child, or null when it exited normally. */
1157
+ readonly signal: NodeJS.Signals | null;
1158
+ /** Set when the child process could not even be spawned (e.g. the binary does not exist). */
1159
+ readonly error?: Error;
1160
+ }
1161
+ /** Runs the real `claude` binary synchronously, injected so no test ever spawns a real process. The Node equivalent of the legacy bash tool's `exec` is `spawnSync` with `stdio: "inherit"` followed by propagating the child's own exit code — see `src/launcher/spawn.ts`. */
1162
+ interface SpawnPort {
1163
+ readonly spawnSync: (command: string, args: readonly string[], options: {
1164
+ readonly stdio: "inherit";
1165
+ readonly env: Readonly<Record<string, string | undefined>>;
1166
+ }) => SpawnResult;
1167
+ }
1152
1168
  /** The outcome of one synchronous external-command run (distinct from `SpawnPort`, which is specifically for replacing this process with the real `claude` binary — `RunPort` is for auxiliary commands like `git rev-parse` for branch detection, or `security find-generic-password` for the macOS Keychain diagnostic in `check.ts`, whose output this process needs to keep running and read). */
1153
1169
  interface RunResult {
1154
1170
  readonly status: number | null;
@@ -1632,18 +1648,22 @@ declare function realConnectCertStore(paths: {
1632
1648
  }): ConnectCertStore;
1633
1649
 
1634
1650
  /**
1635
- * The persisted half of the tracker's client credential: the OAuth-kind bearer and protocol headers a Remote Control session's client-half calls were last observed with, written per session id so a later door generation can still attach to a session whose create crossed an earlier one.
1651
+ * The persisted half of the tracker's client credential and of its sequence cursor: the OAuth-kind bearer and protocol headers a Remote Control session's client-half calls were last observed with, and the highest sequence number the door's stream attachment had confirmed when its last attachment boundary passed, written per session id so a later door generation can still attach to a session whose create crossed an earlier one and resume its read stream from where the last generation left off.
1636
1652
  *
1637
- * The tracker holds the credential in memory only, and the worker's recurring calls carry the worker JWT rather than the OAuth bearer, so a door that starts after the session's create (an idle shutdown and restart, a release upgrade, a reboot) would never learn it: nothing the door can observe re-states it until some client-half call happens to cross. Since the session outlives any one door process, the credential must outlive the process too. It is the same secret the identity's own store already holds on the same machine, so persisting it adds a second copy inside the same trust boundary, at the same owner-only protection: one JSON file per session, mode 0600, under the door's own front-door directory.
1653
+ * The tracker holds both in memory only, and the worker's recurring calls carry the worker JWT rather than the OAuth bearer, so a door that starts after the session's create (an idle shutdown and restart, a release upgrade, a reboot) would never learn the credential: nothing the door can observe re-states it until some client-half call happens to cross. Since the session outlives any one door process, the credential must outlive the process too, and so must the cursor, or every restarted generation would re-read the stream from its head. The credential is the same secret the identity's own store already holds on the same machine, so persisting it adds a second copy inside the same trust boundary, at the same owner-only protection: one JSON file per session, mode 0600, under the door's own front-door directory, with the cursor (no secret, but the same file and the same lifecycle) beside it. The native client does exactly this: its `bridge-session` transcript entry carries `lastSequenceNum` beside the session id.
1638
1654
  *
1639
- * A file is removed when the tracker observes the session closing (the conflict header, or an accepted archive). Nothing else removes it: the tracker's idle sweep is not a close (a quiet session is not a dead one, and a resumed session must re-attach), and the credential's own expiry is the protocol's to judge, as a 401 on the dial the hub already retries and backs off from. A session that ends without an observable close leaves its file behind, overwritten only if the same id is ever observed again.
1655
+ * Each half is written at its own boundaries (the credential whenever an OAuth-kind bearer is observed, the cursor when the stream hub's attachment reaches a boundary), so each write preserves the other half, and neither is written per stream event. A file is removed when the tracker observes the session closing (the conflict header, or an accepted archive). Nothing else removes it: the tracker's idle sweep is not a close (a quiet session is not a dead one, and a resumed session must re-attach), and the credential's own expiry is the protocol's to judge, as a 401 on the dial the hub already retries and backs off from. A session that ends without an observable close leaves its file behind, overwritten only if the same id is ever observed again.
1640
1656
  */
1641
1657
  interface RcCredentialStore {
1642
1658
  /** The session's last observed client credential, or undefined when none was ever persisted for it (or what was persisted does not parse). */
1643
1659
  readonly read: (sessionId: string) => RcObservedCredential | undefined;
1644
- /** Persists the session's client credential, replacing whatever was held for it. */
1660
+ /** Persists the session's client credential, replacing whatever was held for it and keeping the session's persisted cursor. */
1645
1661
  readonly write: (sessionId: string, credential: RcObservedCredential) => void;
1646
- /** Forgets the session's persisted credential, succeeding silently when none was held. */
1662
+ /** The session's persisted sequence cursor, or undefined when none was ever persisted for it (or what was persisted is not a usable number). */
1663
+ readonly readCursor: (sessionId: string) => number | undefined;
1664
+ /** Persists the session's sequence cursor, keeping whatever credential the same file holds. */
1665
+ readonly writeCursor: (sessionId: string, highestSequenceNum: number) => void;
1666
+ /** Forgets the session's persisted record, credential and cursor together, succeeding silently when none was held. */
1647
1667
  readonly remove: (sessionId: string) => void;
1648
1668
  }
1649
1669
  /** Creates the credential store over one directory: one owner-only JSON file per session id. */
@@ -2045,6 +2065,10 @@ interface RcStreamHubDeps {
2045
2065
  readonly fileStreamEvent: (sessionId: string, event: RcStreamEnvelope) => void;
2046
2066
  /** Reads the session's sequence cursor: the highest number the door has seen, from the stream or from its own confirmed writes. */
2047
2067
  readonly sequenceNumOf: (sessionId: string) => number | undefined;
2068
+ /** Reads the session's persisted sequence cursor, consulted only when the tracker's in-memory cursor is undefined at attach time (a door generation that started after the session's traffic, the same fresh-generation case the persisted credential solves for attaching at all), so that generation's first stream resumes where the last one left off instead of at the stream's head. */
2069
+ readonly storedSequenceNumOf?: (sessionId: string) => number | undefined;
2070
+ /** Persists the session's sequence cursor at an attachment boundary (a stream drop, a failed attempt, the attachment's end), never per stream event: the native client persists its own cursor at bridge-session boundaries, and so does this. */
2071
+ readonly saveSequenceNum?: (sessionId: string, sequenceNum: number) => void;
2048
2072
  readonly dial: RcStreamDial;
2049
2073
  readonly fanout: RcEventFanout;
2050
2074
  /** Mints the stable client id one session's attachment announces: a v4 UUID or better in production. Stable means it survives reconnects, so the host sees one client, not a new one per drop. */
@@ -3886,6 +3910,10 @@ interface PrepareLaunchParams {
3886
3910
  /** True when the user was asked on a terminal whether to create the selected configuration profile and chose to launch without it. Without that explicit choice, a selected profile with no file is refused rather than silently skipped. */
3887
3911
  readonly allowMissingConfigProfile?: boolean;
3888
3912
  }
3913
+ /** Inputs to `runLauncher`: a launch's inputs plus the port that spawns the child. */
3914
+ interface RunLauncherParams extends PrepareLaunchParams {
3915
+ readonly spawn: SpawnPort;
3916
+ }
3889
3917
  /**
3890
3918
  * What one launch resolved to, once every effect its child depends on is in place (the identity's farm resynced, the front door and headroom up and this launch registered with them): the real binary, its arguments and its environment.
3891
3919
  */
@@ -3906,6 +3934,32 @@ interface LaunchPlan {
3906
3934
  * The farm resync is skipped when `CLAUDE_CONFIG_DIR` was already set (the escape hatch means the user has named a configuration directory explicitly, and agent-shim manages neither its contents nor its lifetime) and when no identity resolved at all (a bare launch against plain `~/.claude`, matching the legacy tool's own behaviour). In both cases there is no agent-shim-managed farm for a resync to act on.
3907
3935
  */
3908
3936
  declare function prepareLaunch(params: PrepareLaunchParams): LaunchPlan;
3937
+ /**
3938
+ * Runs one `claude` launch: `prepareLaunch`, then the child under `params.spawn`, whose exit code becomes this process's.
3939
+ *
3940
+ * The session registrations are released twice by design: `beforeExit` covers the real success path (where `process.exit` never unwinds a `finally`), and the `finally` below covers a thrown spawn error, where it does.
3941
+ */
3942
+ declare function runLauncher(params: RunLauncherParams): void;
3943
+
3944
+ /** Inputs to `spawnClaude`. */
3945
+ interface SpawnClaudeParams {
3946
+ /** Full path to the real `claude` binary to run, as discovered by `src/versionDiscovery.ts`. */
3947
+ readonly bin: string;
3948
+ readonly args: readonly string[];
3949
+ readonly env: Readonly<Record<string, string | undefined>>;
3950
+ readonly spawn: SpawnPort;
3951
+ readonly proc: ProcPort;
3952
+ /**
3953
+ * Runs immediately before the child's exit code propagates. The real `process.exit` never unwinds a `finally` block, so a caller with cleanup to do on the success path (releasing a headroom session registration, say) cannot rely on one; it passes the cleanup here instead.
3954
+ */
3955
+ readonly beforeExit?: () => void;
3956
+ }
3957
+ /**
3958
+ * Runs the real `claude` binary and propagates its exit code faithfully, the Node equivalent of the legacy bash tool's `exec` (process replacement): `spawnSync(bin, args, { stdio: "inherit" })` followed by `process.exit(status)`.
3959
+ *
3960
+ * Throws when the child could not even be spawned (e.g. `bin` does not exist) rather than silently exiting — a spawn failure is a real problem, not a clean exit code to propagate.
3961
+ */
3962
+ declare function spawnClaude(params: SpawnClaudeParams): never;
3909
3963
 
3910
3964
  /** Raised by `prepareClaudeLaunch` when the launch is refused: no identity, a missing profile, an ambient credential, an unresolvable credential and the like. `message` is what the launcher logged; `exitCode` is the status the command line would have exited with. */
3911
3965
  declare class LaunchRefusedError extends CliError {
@@ -3932,5 +3986,5 @@ interface PrepareClaudeLaunchOptions {
3932
3986
  */
3933
3987
  declare function prepareClaudeLaunch(options: PrepareClaudeLaunchOptions): LaunchPlan;
3934
3988
 
3935
- export { AMBIENT_CREDENTIAL_VARS, CONNECT_INTERCEPT_HOST, CONNECT_INTERCEPT_HOSTS, CONNECT_LIMITS, CONTROL_PATH_PREFIX, CategoryClassificationOverlaySchema, CategoryClassificationSchema, CategoryMapSchema, CliError, ConfigProfileSchema, CredentialCacheSchema, CredentialSchema, CredentialSourceSchema, DirectoryRuleAlreadyExistsError, DirectoryRuleMissingTargetError, DirectoryRuleNotFoundError, DirectoryRuleSchema, DirectoryRulesSchema, EXIT_FAILURE, EXIT_USAGE, EntryValueSchema, FARM_MANIFEST_FILENAME, FrontDoorStartError, GlobalConfigSchema, HeadroomStartError, IdentityAlreadyExistsError, IdentityNotFoundError, IdentitySchema, InvalidCategoryNameError, InvalidIdentityNameError, InvalidProviderNameError, LaunchRefusedError, LegacyProviderFileError, PROMPT_CACHE_TTL_MS, PlanClassSchema, PoolNameSchema, PoolNotFoundError, PoolPickReportSchema, PoolSchema, PortableConfigSchema, ProfileAlreadyExistsError, ProfileNotFoundError, ProviderAlreadyExistsError, ProviderKindMismatchError, ProviderNotFoundError, ProviderSchema, RC_IDLE_EXPIRY_MS, RC_ORPC_PATH_PREFIX, RC_PENDING_DEADLINE_MS, RC_PERMISSION_MODES, RC_REQUEST_PARSE_CAP_BYTES, RC_SELF_HOST_ENV, RC_SELF_HOST_KEEPALIVE_MS, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE, RC_SELF_HOST_RETENTION_MS, RC_SELF_HOST_SCOPE_LIST, RC_SELF_HOST_WORKER_JWT_TTL_SECONDS, RC_SESSIONS_PATH_PREFIX, RC_STREAM_BACKOFF_MS, ROUTED_PATH_PREFIX, RcPermissionModeSchema, RcStreamEnvelopeSchema, RcStreamEventSchema, UsageError, UsageSnapshotError, UsageSnapshotSchema, WhenSchema, addDirectoryRule, addIdentity, addPool, addProvider, answerRcControlRequest, buildEntryFacts, buildLayoutPaths, buildRcControlResponsePayload, buildRcEventWriteBody, buildRcInterruptPayload, buildRcSetModelPayload, buildRcSetPermissionModePayload, buildRcUserMessagePayload, carryOver, checkReportHasWarnings, checkReportToJson, collectCheckReport, collectDoctorReport, collectPoolPick, createLeafCache, createProfile, createRcApiNodeHandler, createRcApiRouter, createRcControlHandler, createRcCredentialStore, createRcEventFanout, createRcSelfHostSurface, createRcSessionTracker, createRcStreamHub, createSseParser, describeProviderEndpoint, detectAmbientCredential, effectiveWindow, ensureCa, ensureFrontDoor, ensureHeadroom, evaluateAmbientCredentialGuard, evaluateWhen, formatAmbientCredentialGuardMessage, formatCheckReport, formatDoctorReport, forwardableHeaders, frontDoorRcApiClient, frontDoorRcControl, generateCa, identityExists, injectRcUserMessage, interruptRcSession, isIdentityDirectoryName, isInterceptedHost, isRcPermissionMode, lateRcEventDial, lateRcStreamDial, listDirectoryRules, listIdentities, listProfiles, listProviders, listUsageSnapshots, matchBranch, mintLeaf, mintRcSelfHostCredential, observingRoutedRoute, parseConnectTarget, parseRcStreamEnvelope, planOf, prepareClaudeLaunch, prepareLaunch, profileExists, providerExists, rankPool, rcEventWriteResultFromAnswer, rcObserverAsPassthrough, rcSelfHostFromEnv, readActiveIdentity, readDirectoryRules, readFarmManifest, readGlobalConfig, readIdentity, readPools, readProfile, readProvider, readRcSelfHostRecord, readUsageSnapshot, realConnectCertStore, realConnectEffects, realRcControlTransport, realRcEventDial, realRcStreamDial, recoverFarm, recoveryDiagnostics, removeDirectoryRule, removeIdentity, removePool, removeProfile, removeProvider, requirePool, resolveAgentShimHome, resolveClaudeHome, resolveDecisions, resolveLayoutPaths, resolveSupervisorConfig, resyncFarm, runCheck, runDoctor, runFrontDoorSupervisor, runSupervisor, servedByPipeline, setAllowAmbientCredential, setDefaultConfigProfile, setGlobalDefaultProfile, setIdentityCredential, setPool, setProfileCategories, setProfileEntries, setProfileLaunchFlags, setProfileMetadata, setRcSessionModel, setRcSessionPermissionMode, snapshotPath, startConnectServer, topLevelNames, updateDirectoryRule, updateProvider, useIdentity, writeDirectoryRules };
3936
- export type { AddDirectoryRuleOptions, AddProviderInput, AmbientCredentialDetection, AmbientCredentialGuardResult, AmbientCredentialVar, BuildEntryFactsParams, CaMaterial, Candidate, CarryOverParams, CarryOverResult, CategoryMap, CheckReport, CollectCheckReportParams, CollectDoctorReportParams, CompiledRule, ConditionContext, ConfigProfile, ConnectCertStore, ConnectEffects, ConnectLimits, ConnectLocalSurface, ConnectServerConfig, ConnectServerHandle, ConnectTarget, Credential, CredentialSource, Decision, Diagnostic, DirectoryRule, DirectoryRules, DoctorReport, EffectiveWindow, EliminatedRule, EnsureFrontDoorPorts, EnsureHeadroomPorts, EntryFact, EntryFacts, EntryValue, EvaluateAmbientCredentialGuardParams, FlattenedCascade, FrontDoorRcControl, FrontDoorSupervisorPorts, GlobalConfig, HeadroomSupervisorConfig, Identity, IdentityCredentialChange, IdentityListEntry, IdentityListing, InjectedCredential, LaunchPlan, Layer, LayerId, LayoutPaths, LeafCert, PlanClass, Pool, PoolMember, PoolPickReport, PoolRanking, PortableConfig, PrepareClaudeLaunchOptions, PrepareLaunchParams, ProfileListEntry, Provider, ProviderListEntry, RankPoolInput, RcAnswerDecision, RcAnswerDeps, RcApiClient, RcApiDeps, RcApiRouter, RcControlAnswer, RcControlHandlerDeps, RcControlRequestDeps, RcControlTransport, RcCredentialStore, RcDialAnswer, RcDialTarget, RcEventDial, RcEventFanout, RcEventWriteResult, RcExchangeObserver, RcInjectDeps, RcObservedCredential, RcObservedRequest, RcPendingRequestSummary, RcPermissionMode, RcPresenceAnswer, RcSelfHostCredentialRecord, RcSelfHostDeps, RcSelfHostMintResult, RcSelfHostSurface, RcSessionStatus, RcSessionSummary, RcSessionTracker, RcSessionTrackerDeps, RcStreamAnswer, RcStreamDial, RcStreamEnvelope, RcStreamEvent, RcStreamHub, RcStreamHubDeps, RcWorkerFact, RcWriteHeaders, RecoverFarmParams, RecoveryResult, ResolveDecisionsInput, ResolvedState, ResyncFarmParams, ResyncFarmResult, RunCheckParams, RunDoctorParams, RunFrontDoorSupervisorOptions, RunSupervisorOptions, SseParsedEvent, StickyPick, SupervisorPorts, UnreadableIdentityListEntry, UpdateDirectoryRuleOptions, UpdateProviderInput, UsageReadFs, UsageSnapshot, WhenCondition, WhenEvaluation };
3989
+ export { AMBIENT_CREDENTIAL_VARS, CONNECT_INTERCEPT_HOST, CONNECT_INTERCEPT_HOSTS, CONNECT_LIMITS, CONTROL_PATH_PREFIX, CategoryClassificationOverlaySchema, CategoryClassificationSchema, CategoryMapSchema, CliError, ConfigProfileSchema, CredentialCacheSchema, CredentialSchema, CredentialSourceSchema, DirectoryRuleAlreadyExistsError, DirectoryRuleMissingTargetError, DirectoryRuleNotFoundError, DirectoryRuleSchema, DirectoryRulesSchema, EXIT_FAILURE, EXIT_USAGE, EntryValueSchema, FARM_MANIFEST_FILENAME, FrontDoorStartError, GlobalConfigSchema, HeadroomStartError, IdentityAlreadyExistsError, IdentityNotFoundError, IdentitySchema, InvalidCategoryNameError, InvalidIdentityNameError, InvalidProviderNameError, LaunchRefusedError, LegacyProviderFileError, PROMPT_CACHE_TTL_MS, PlanClassSchema, PoolNameSchema, PoolNotFoundError, PoolPickReportSchema, PoolSchema, PortableConfigSchema, ProfileAlreadyExistsError, ProfileNotFoundError, ProviderAlreadyExistsError, ProviderKindMismatchError, ProviderNotFoundError, ProviderSchema, RC_IDLE_EXPIRY_MS, RC_ORPC_PATH_PREFIX, RC_PENDING_DEADLINE_MS, RC_PERMISSION_MODES, RC_REQUEST_PARSE_CAP_BYTES, RC_SELF_HOST_ENV, RC_SELF_HOST_KEEPALIVE_MS, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE, RC_SELF_HOST_RETENTION_MS, RC_SELF_HOST_SCOPE_LIST, RC_SELF_HOST_WORKER_JWT_TTL_SECONDS, RC_SESSIONS_PATH_PREFIX, RC_STREAM_BACKOFF_MS, ROUTED_PATH_PREFIX, RcPermissionModeSchema, RcStreamEnvelopeSchema, RcStreamEventSchema, UsageError, UsageSnapshotError, UsageSnapshotSchema, WhenSchema, addDirectoryRule, addIdentity, addPool, addProvider, answerRcControlRequest, buildEntryFacts, buildLayoutPaths, buildRcControlResponsePayload, buildRcEventWriteBody, buildRcInterruptPayload, buildRcSetModelPayload, buildRcSetPermissionModePayload, buildRcUserMessagePayload, carryOver, checkReportHasWarnings, checkReportToJson, collectCheckReport, collectDoctorReport, collectPoolPick, createLeafCache, createProfile, createRcApiNodeHandler, createRcApiRouter, createRcControlHandler, createRcCredentialStore, createRcEventFanout, createRcSelfHostSurface, createRcSessionTracker, createRcStreamHub, createSseParser, describeProviderEndpoint, detectAmbientCredential, effectiveWindow, ensureCa, ensureFrontDoor, ensureHeadroom, evaluateAmbientCredentialGuard, evaluateWhen, formatAmbientCredentialGuardMessage, formatCheckReport, formatDoctorReport, forwardableHeaders, frontDoorRcApiClient, frontDoorRcControl, generateCa, identityExists, injectRcUserMessage, interruptRcSession, isIdentityDirectoryName, isInterceptedHost, isRcPermissionMode, lateRcEventDial, lateRcStreamDial, listDirectoryRules, listIdentities, listProfiles, listProviders, listUsageSnapshots, matchBranch, mintLeaf, mintRcSelfHostCredential, observingRoutedRoute, parseConnectTarget, parseRcStreamEnvelope, planOf, prepareClaudeLaunch, prepareLaunch, profileExists, providerExists, rankPool, rcEventWriteResultFromAnswer, rcObserverAsPassthrough, rcSelfHostFromEnv, readActiveIdentity, readDirectoryRules, readFarmManifest, readGlobalConfig, readIdentity, readPools, readProfile, readProvider, readRcSelfHostRecord, readUsageSnapshot, realConnectCertStore, realConnectEffects, realRcControlTransport, realRcEventDial, realRcStreamDial, recoverFarm, recoveryDiagnostics, removeDirectoryRule, removeIdentity, removePool, removeProfile, removeProvider, requirePool, resolveAgentShimHome, resolveClaudeHome, resolveDecisions, resolveLayoutPaths, resolveSupervisorConfig, resyncFarm, runCheck, runDoctor, runFrontDoorSupervisor, runLauncher, runSupervisor, servedByPipeline, setAllowAmbientCredential, setDefaultConfigProfile, setGlobalDefaultProfile, setIdentityCredential, setPool, setProfileCategories, setProfileEntries, setProfileLaunchFlags, setProfileMetadata, setRcSessionModel, setRcSessionPermissionMode, snapshotPath, spawnClaude, startConnectServer, topLevelNames, updateDirectoryRule, updateProvider, useIdentity, writeDirectoryRules };
3990
+ export type { AddDirectoryRuleOptions, AddProviderInput, AmbientCredentialDetection, AmbientCredentialGuardResult, AmbientCredentialVar, BuildEntryFactsParams, CaMaterial, Candidate, CarryOverParams, CarryOverResult, CategoryMap, CheckReport, CollectCheckReportParams, CollectDoctorReportParams, CompiledRule, ConditionContext, ConfigProfile, ConnectCertStore, ConnectEffects, ConnectLimits, ConnectLocalSurface, ConnectServerConfig, ConnectServerHandle, ConnectTarget, Credential, CredentialSource, Decision, Diagnostic, DirectoryRule, DirectoryRules, DoctorReport, EffectiveWindow, EliminatedRule, EnsureFrontDoorPorts, EnsureHeadroomPorts, EntryFact, EntryFacts, EntryValue, EvaluateAmbientCredentialGuardParams, FlattenedCascade, FrontDoorRcControl, FrontDoorSupervisorPorts, GlobalConfig, HeadroomSupervisorConfig, Identity, IdentityCredentialChange, IdentityListEntry, IdentityListing, InjectedCredential, LaunchPlan, Layer, LayerId, LayoutPaths, LeafCert, PlanClass, Pool, PoolMember, PoolPickReport, PoolRanking, PortableConfig, PrepareClaudeLaunchOptions, PrepareLaunchParams, ProfileListEntry, Provider, ProviderListEntry, RankPoolInput, RcAnswerDecision, RcAnswerDeps, RcApiClient, RcApiDeps, RcApiRouter, RcControlAnswer, RcControlHandlerDeps, RcControlRequestDeps, RcControlTransport, RcCredentialStore, RcDialAnswer, RcDialTarget, RcEventDial, RcEventFanout, RcEventWriteResult, RcExchangeObserver, RcInjectDeps, RcObservedCredential, RcObservedRequest, RcPendingRequestSummary, RcPermissionMode, RcPresenceAnswer, RcSelfHostCredentialRecord, RcSelfHostDeps, RcSelfHostMintResult, RcSelfHostSurface, RcSessionStatus, RcSessionSummary, RcSessionTracker, RcSessionTrackerDeps, RcStreamAnswer, RcStreamDial, RcStreamEnvelope, RcStreamEvent, RcStreamHub, RcStreamHubDeps, RcWorkerFact, RcWriteHeaders, RecoverFarmParams, RecoveryResult, ResolveDecisionsInput, ResolvedState, ResyncFarmParams, ResyncFarmResult, RunCheckParams, RunDoctorParams, RunFrontDoorSupervisorOptions, RunLauncherParams, RunSupervisorOptions, SpawnClaudeParams, SseParsedEvent, StickyPick, SupervisorPorts, UnreadableIdentityListEntry, UpdateDirectoryRuleOptions, UpdateProviderInput, UsageReadFs, UsageSnapshot, WhenCondition, WhenEvaluation };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-shim",
3
- "version": "8.12.0",
3
+ "version": "8.14.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>",