agent-shim 9.12.0 → 9.12.1
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 +36 -11
- package/dist/index.cjs +36 -11
- package/dist/index.mjs +36 -11
- package/dist/types/index.d.ts +3 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -27866,6 +27866,10 @@ function realIsProcessZombie(pid) {
|
|
|
27866
27866
|
function realIsProcessRunning(pid) {
|
|
27867
27867
|
return realIsProcessAlive(pid) && !realIsProcessZombie(pid);
|
|
27868
27868
|
}
|
|
27869
|
+
function realIsFrontDoorSupervisor(pid) {
|
|
27870
|
+
const result = (0, import_node_child_process2.spawnSync)("ps", ["-o", "command=", "-p", String(pid)], { encoding: "utf8" });
|
|
27871
|
+
return result.status === 0 && result.stdout.split(/\s+/).includes(FRONT_DOOR_SUPERVISOR_SUBCOMMAND);
|
|
27872
|
+
}
|
|
27869
27873
|
function expandHome(filePath) {
|
|
27870
27874
|
return filePath.startsWith("~/") ? import_node_path8.default.join(import_node_os2.default.homedir(), filePath.slice(1)) : filePath;
|
|
27871
27875
|
}
|
|
@@ -28068,7 +28072,7 @@ function realResolveClaudeBinary(isOwnBinary) {
|
|
|
28068
28072
|
function realInstalledClaudeVersions() {
|
|
28069
28073
|
return installedVersions(listVersionsDir(defaultVersionsDir()));
|
|
28070
28074
|
}
|
|
28071
|
-
var import_node_child_process2, import_node_crypto4, import_node_fs3, import_node_os2, import_node_path8, import_node_sea, realFsPort, OWNER_ONLY_DIR_MODE, OWNER_ONLY_FILE_MODE, PERMISSION_BITS, realFarmFs, INT32_BYTE_LENGTH, realRunPort, MACOS_GUI_SESSION_MANAGER, realCredentialPort, SOCKET_PERMISSION_BITS, realHeadroomSocketTrust, realSpawnPort, realProcPort, realLogPort, EXECUTE_BITS_MASK, WINDOWS_DEFAULT_PATHEXT;
|
|
28075
|
+
var import_node_child_process2, import_node_crypto4, import_node_fs3, import_node_os2, import_node_path8, import_node_sea, realFsPort, OWNER_ONLY_DIR_MODE, OWNER_ONLY_FILE_MODE, PERMISSION_BITS, realFarmFs, INT32_BYTE_LENGTH, FRONT_DOOR_SUPERVISOR_SUBCOMMAND, realRunPort, MACOS_GUI_SESSION_MANAGER, realCredentialPort, SOCKET_PERMISSION_BITS, realHeadroomSocketTrust, realSpawnPort, realProcPort, realLogPort, EXECUTE_BITS_MASK, WINDOWS_DEFAULT_PATHEXT;
|
|
28072
28076
|
var init_realPorts = __esm({
|
|
28073
28077
|
"src/realPorts.ts"() {
|
|
28074
28078
|
"use strict";
|
|
@@ -28209,6 +28213,7 @@ var init_realPorts = __esm({
|
|
|
28209
28213
|
}
|
|
28210
28214
|
};
|
|
28211
28215
|
INT32_BYTE_LENGTH = 4;
|
|
28216
|
+
FRONT_DOOR_SUPERVISOR_SUBCOMMAND = "__frontdoor-supervisor";
|
|
28212
28217
|
realRunPort = {
|
|
28213
28218
|
run(command, args) {
|
|
28214
28219
|
const result = (0, import_node_child_process2.spawnSync)(command, [...args], { encoding: "utf8" });
|
|
@@ -33243,7 +33248,7 @@ var init_package = __esm({
|
|
|
33243
33248
|
"package.json"() {
|
|
33244
33249
|
package_default = {
|
|
33245
33250
|
name: "agent-shim",
|
|
33246
|
-
version: "9.12.
|
|
33251
|
+
version: "9.12.1",
|
|
33247
33252
|
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.",
|
|
33248
33253
|
license: "MIT",
|
|
33249
33254
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -61034,20 +61039,34 @@ function ensureFrontDoor(params) {
|
|
|
61034
61039
|
let replaced = false;
|
|
61035
61040
|
const distrusted = /* @__PURE__ */ new Set();
|
|
61036
61041
|
let lastRejection;
|
|
61042
|
+
const verifyWithRetry = (port) => {
|
|
61043
|
+
let verdict = ports.verifyListener(port);
|
|
61044
|
+
for (let attempt = 1; !verdict.ok && attempt < FRONTDOOR_PROBE_ATTEMPTS; attempt += 1) {
|
|
61045
|
+
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
61046
|
+
verdict = ports.verifyListener(port);
|
|
61047
|
+
}
|
|
61048
|
+
return verdict;
|
|
61049
|
+
};
|
|
61050
|
+
const stopAndAwaitExit = (supervisorPid, failure2) => {
|
|
61051
|
+
ports.stopSupervisor(supervisorPid);
|
|
61052
|
+
while (ports.isRunning(supervisorPid)) {
|
|
61053
|
+
if (ports.now() >= deadline) {
|
|
61054
|
+
throw new FrontDoorStartError(`${failure2}. Daemon log: ${paths.frontdoorLogPath}`);
|
|
61055
|
+
}
|
|
61056
|
+
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
61057
|
+
}
|
|
61058
|
+
};
|
|
61037
61059
|
for (; ; ) {
|
|
61038
61060
|
const state = readFrontDoorState(ports.fs, paths.frontdoorStateFile);
|
|
61039
61061
|
const supervisorPid = state?.supervisorPid;
|
|
61040
61062
|
if (supervisorPid !== void 0 && !distrusted.has(supervisorPid) && ports.isRunning(supervisorPid)) {
|
|
61041
61063
|
if (state?.port !== void 0 && state.connectPort !== void 0) {
|
|
61042
|
-
const verdict =
|
|
61064
|
+
const verdict = verifyWithRetry(state.port);
|
|
61043
61065
|
if (verdict.ok && !replaced && !spawned && (params.replace === true || (state.protocol ?? 0) < FRONT_DOOR_PROTOCOL)) {
|
|
61044
|
-
|
|
61045
|
-
|
|
61046
|
-
|
|
61047
|
-
|
|
61048
|
-
}
|
|
61049
|
-
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
61050
|
-
}
|
|
61066
|
+
stopAndAwaitExit(
|
|
61067
|
+
supervisorPid,
|
|
61068
|
+
`the front door (pid ${String(supervisorPid)}, protocol ${String(state.protocol ?? 0)}; this launcher speaks protocol ${String(FRONT_DOOR_PROTOCOL)}) was asked to be replaced and did not exit`
|
|
61069
|
+
);
|
|
61051
61070
|
replaced = true;
|
|
61052
61071
|
continue;
|
|
61053
61072
|
}
|
|
@@ -61060,6 +61079,10 @@ function ensureFrontDoor(params) {
|
|
|
61060
61079
|
if (spawned) {
|
|
61061
61080
|
throw new FrontDoorStartError(`${lastRejection}; refusing to send this session's credentials to it. Daemon log: ${paths.frontdoorLogPath}`);
|
|
61062
61081
|
}
|
|
61082
|
+
if (ports.isFrontDoorSupervisor(supervisorPid)) {
|
|
61083
|
+
stopAndAwaitExit(supervisorPid, `the front door (pid ${String(supervisorPid)}) stopped answering and did not exit when asked to`);
|
|
61084
|
+
continue;
|
|
61085
|
+
}
|
|
61063
61086
|
distrusted.add(supervisorPid);
|
|
61064
61087
|
continue;
|
|
61065
61088
|
}
|
|
@@ -61107,7 +61130,7 @@ function restartFrontDoor(params) {
|
|
|
61107
61130
|
}
|
|
61108
61131
|
return { action: "restarted", previousPid, pid };
|
|
61109
61132
|
}
|
|
61110
|
-
var import_node_crypto10, FRONTDOOR_START_TIMEOUT_MS, FRONTDOOR_LAUNCHER_POLL_MS, FrontDoorStartError;
|
|
61133
|
+
var import_node_crypto10, FRONTDOOR_START_TIMEOUT_MS, FRONTDOOR_LAUNCHER_POLL_MS, FRONTDOOR_PROBE_ATTEMPTS, FrontDoorStartError;
|
|
61111
61134
|
var init_ensure2 = __esm({
|
|
61112
61135
|
"src/frontdoor/ensure.ts"() {
|
|
61113
61136
|
"use strict";
|
|
@@ -61117,6 +61140,7 @@ var init_ensure2 = __esm({
|
|
|
61117
61140
|
init_state2();
|
|
61118
61141
|
FRONTDOOR_START_TIMEOUT_MS = 3e4;
|
|
61119
61142
|
FRONTDOOR_LAUNCHER_POLL_MS = 100;
|
|
61143
|
+
FRONTDOOR_PROBE_ATTEMPTS = 3;
|
|
61120
61144
|
FrontDoorStartError = class extends CliError {
|
|
61121
61145
|
constructor(message) {
|
|
61122
61146
|
super(message);
|
|
@@ -61242,6 +61266,7 @@ function realEnsurePorts(paths, spawnDaemon) {
|
|
|
61242
61266
|
now: () => Date.now(),
|
|
61243
61267
|
sleep: realSleepSync,
|
|
61244
61268
|
spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
|
|
61269
|
+
isFrontDoorSupervisor: realIsFrontDoorSupervisor,
|
|
61245
61270
|
stopSupervisor: (pid) => {
|
|
61246
61271
|
process.kill(pid, "SIGTERM");
|
|
61247
61272
|
},
|
package/dist/index.cjs
CHANGED
|
@@ -2663,7 +2663,7 @@ var init_package = __esm({
|
|
|
2663
2663
|
"package.json"() {
|
|
2664
2664
|
package_default = {
|
|
2665
2665
|
name: "agent-shim",
|
|
2666
|
-
version: "9.12.
|
|
2666
|
+
version: "9.12.1",
|
|
2667
2667
|
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.",
|
|
2668
2668
|
license: "MIT",
|
|
2669
2669
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -3427,6 +3427,10 @@ function realIsProcessZombie(pid) {
|
|
|
3427
3427
|
function realIsProcessRunning(pid) {
|
|
3428
3428
|
return realIsProcessAlive(pid) && !realIsProcessZombie(pid);
|
|
3429
3429
|
}
|
|
3430
|
+
function realIsFrontDoorSupervisor(pid) {
|
|
3431
|
+
const result = (0, import_node_child_process2.spawnSync)("ps", ["-o", "command=", "-p", String(pid)], { encoding: "utf8" });
|
|
3432
|
+
return result.status === 0 && result.stdout.split(/\s+/).includes(FRONT_DOOR_SUPERVISOR_SUBCOMMAND);
|
|
3433
|
+
}
|
|
3430
3434
|
function expandHome2(filePath) {
|
|
3431
3435
|
return filePath.startsWith("~/") ? import_node_path13.default.join(import_node_os2.default.homedir(), filePath.slice(1)) : filePath;
|
|
3432
3436
|
}
|
|
@@ -3624,7 +3628,7 @@ function realResolveClaudeBinary(isOwnBinary) {
|
|
|
3624
3628
|
function realInstalledClaudeVersions() {
|
|
3625
3629
|
return installedVersions(listVersionsDir(defaultVersionsDir()));
|
|
3626
3630
|
}
|
|
3627
|
-
var import_node_child_process2, import_node_crypto8, import_node_fs2, import_node_os2, import_node_path13, import_node_sea, realFsPort, OWNER_ONLY_DIR_MODE, OWNER_ONLY_FILE_MODE, PERMISSION_BITS, realFarmFs, INT32_BYTE_LENGTH, realRunPort, MACOS_GUI_SESSION_MANAGER, realCredentialPort, SOCKET_PERMISSION_BITS, realHeadroomSocketTrust, realSpawnPort, realProcPort, EXECUTE_BITS_MASK, WINDOWS_DEFAULT_PATHEXT;
|
|
3631
|
+
var import_node_child_process2, import_node_crypto8, import_node_fs2, import_node_os2, import_node_path13, import_node_sea, realFsPort, OWNER_ONLY_DIR_MODE, OWNER_ONLY_FILE_MODE, PERMISSION_BITS, realFarmFs, INT32_BYTE_LENGTH, FRONT_DOOR_SUPERVISOR_SUBCOMMAND, realRunPort, MACOS_GUI_SESSION_MANAGER, realCredentialPort, SOCKET_PERMISSION_BITS, realHeadroomSocketTrust, realSpawnPort, realProcPort, EXECUTE_BITS_MASK, WINDOWS_DEFAULT_PATHEXT;
|
|
3628
3632
|
var init_realPorts = __esm({
|
|
3629
3633
|
"src/realPorts.ts"() {
|
|
3630
3634
|
"use strict";
|
|
@@ -3765,6 +3769,7 @@ var init_realPorts = __esm({
|
|
|
3765
3769
|
}
|
|
3766
3770
|
};
|
|
3767
3771
|
INT32_BYTE_LENGTH = 4;
|
|
3772
|
+
FRONT_DOOR_SUPERVISOR_SUBCOMMAND = "__frontdoor-supervisor";
|
|
3768
3773
|
realRunPort = {
|
|
3769
3774
|
run(command, args) {
|
|
3770
3775
|
const result = (0, import_node_child_process2.spawnSync)(command, [...args], { encoding: "utf8" });
|
|
@@ -6166,20 +6171,34 @@ function ensureFrontDoor(params) {
|
|
|
6166
6171
|
let replaced = false;
|
|
6167
6172
|
const distrusted = /* @__PURE__ */ new Set();
|
|
6168
6173
|
let lastRejection;
|
|
6174
|
+
const verifyWithRetry = (port) => {
|
|
6175
|
+
let verdict = ports.verifyListener(port);
|
|
6176
|
+
for (let attempt = 1; !verdict.ok && attempt < FRONTDOOR_PROBE_ATTEMPTS; attempt += 1) {
|
|
6177
|
+
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
6178
|
+
verdict = ports.verifyListener(port);
|
|
6179
|
+
}
|
|
6180
|
+
return verdict;
|
|
6181
|
+
};
|
|
6182
|
+
const stopAndAwaitExit = (supervisorPid, failure) => {
|
|
6183
|
+
ports.stopSupervisor(supervisorPid);
|
|
6184
|
+
while (ports.isRunning(supervisorPid)) {
|
|
6185
|
+
if (ports.now() >= deadline) {
|
|
6186
|
+
throw new FrontDoorStartError(`${failure}. Daemon log: ${paths.frontdoorLogPath}`);
|
|
6187
|
+
}
|
|
6188
|
+
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
6189
|
+
}
|
|
6190
|
+
};
|
|
6169
6191
|
for (; ; ) {
|
|
6170
6192
|
const state = readFrontDoorState(ports.fs, paths.frontdoorStateFile);
|
|
6171
6193
|
const supervisorPid = state?.supervisorPid;
|
|
6172
6194
|
if (supervisorPid !== void 0 && !distrusted.has(supervisorPid) && ports.isRunning(supervisorPid)) {
|
|
6173
6195
|
if (state?.port !== void 0 && state.connectPort !== void 0) {
|
|
6174
|
-
const verdict =
|
|
6196
|
+
const verdict = verifyWithRetry(state.port);
|
|
6175
6197
|
if (verdict.ok && !replaced && !spawned && (params.replace === true || (state.protocol ?? 0) < FRONT_DOOR_PROTOCOL)) {
|
|
6176
|
-
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
|
|
6180
|
-
}
|
|
6181
|
-
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
6182
|
-
}
|
|
6198
|
+
stopAndAwaitExit(
|
|
6199
|
+
supervisorPid,
|
|
6200
|
+
`the front door (pid ${String(supervisorPid)}, protocol ${String(state.protocol ?? 0)}; this launcher speaks protocol ${String(FRONT_DOOR_PROTOCOL)}) was asked to be replaced and did not exit`
|
|
6201
|
+
);
|
|
6183
6202
|
replaced = true;
|
|
6184
6203
|
continue;
|
|
6185
6204
|
}
|
|
@@ -6192,6 +6211,10 @@ function ensureFrontDoor(params) {
|
|
|
6192
6211
|
if (spawned) {
|
|
6193
6212
|
throw new FrontDoorStartError(`${lastRejection}; refusing to send this session's credentials to it. Daemon log: ${paths.frontdoorLogPath}`);
|
|
6194
6213
|
}
|
|
6214
|
+
if (ports.isFrontDoorSupervisor(supervisorPid)) {
|
|
6215
|
+
stopAndAwaitExit(supervisorPid, `the front door (pid ${String(supervisorPid)}) stopped answering and did not exit when asked to`);
|
|
6216
|
+
continue;
|
|
6217
|
+
}
|
|
6195
6218
|
distrusted.add(supervisorPid);
|
|
6196
6219
|
continue;
|
|
6197
6220
|
}
|
|
@@ -6222,7 +6245,7 @@ function ensureFrontDoor(params) {
|
|
|
6222
6245
|
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
6223
6246
|
}
|
|
6224
6247
|
}
|
|
6225
|
-
var import_node_crypto9, FRONTDOOR_START_TIMEOUT_MS, FRONTDOOR_LAUNCHER_POLL_MS, FrontDoorStartError;
|
|
6248
|
+
var import_node_crypto9, FRONTDOOR_START_TIMEOUT_MS, FRONTDOOR_LAUNCHER_POLL_MS, FRONTDOOR_PROBE_ATTEMPTS, FrontDoorStartError;
|
|
6226
6249
|
var init_ensure2 = __esm({
|
|
6227
6250
|
"src/frontdoor/ensure.ts"() {
|
|
6228
6251
|
"use strict";
|
|
@@ -6232,6 +6255,7 @@ var init_ensure2 = __esm({
|
|
|
6232
6255
|
init_state();
|
|
6233
6256
|
FRONTDOOR_START_TIMEOUT_MS = 3e4;
|
|
6234
6257
|
FRONTDOOR_LAUNCHER_POLL_MS = 100;
|
|
6258
|
+
FRONTDOOR_PROBE_ATTEMPTS = 3;
|
|
6235
6259
|
FrontDoorStartError = class extends CliError {
|
|
6236
6260
|
constructor(message) {
|
|
6237
6261
|
super(message);
|
|
@@ -7418,6 +7442,7 @@ function realEnsurePorts(paths, spawnDaemon) {
|
|
|
7418
7442
|
now: () => Date.now(),
|
|
7419
7443
|
sleep: realSleepSync,
|
|
7420
7444
|
spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
|
|
7445
|
+
isFrontDoorSupervisor: realIsFrontDoorSupervisor,
|
|
7421
7446
|
stopSupervisor: (pid) => {
|
|
7422
7447
|
process.kill(pid, "SIGTERM");
|
|
7423
7448
|
},
|
package/dist/index.mjs
CHANGED
|
@@ -2639,7 +2639,7 @@ var init_package = __esm({
|
|
|
2639
2639
|
"package.json"() {
|
|
2640
2640
|
package_default = {
|
|
2641
2641
|
name: "agent-shim",
|
|
2642
|
-
version: "9.12.
|
|
2642
|
+
version: "9.12.1",
|
|
2643
2643
|
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.",
|
|
2644
2644
|
license: "MIT",
|
|
2645
2645
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -3408,6 +3408,10 @@ function realIsProcessZombie(pid) {
|
|
|
3408
3408
|
function realIsProcessRunning(pid) {
|
|
3409
3409
|
return realIsProcessAlive(pid) && !realIsProcessZombie(pid);
|
|
3410
3410
|
}
|
|
3411
|
+
function realIsFrontDoorSupervisor(pid) {
|
|
3412
|
+
const result = spawnSync("ps", ["-o", "command=", "-p", String(pid)], { encoding: "utf8" });
|
|
3413
|
+
return result.status === 0 && result.stdout.split(/\s+/).includes(FRONT_DOOR_SUPERVISOR_SUBCOMMAND);
|
|
3414
|
+
}
|
|
3411
3415
|
function expandHome2(filePath) {
|
|
3412
3416
|
return filePath.startsWith("~/") ? path13.join(os3.homedir(), filePath.slice(1)) : filePath;
|
|
3413
3417
|
}
|
|
@@ -3605,7 +3609,7 @@ function realResolveClaudeBinary(isOwnBinary) {
|
|
|
3605
3609
|
function realInstalledClaudeVersions() {
|
|
3606
3610
|
return installedVersions(listVersionsDir(defaultVersionsDir()));
|
|
3607
3611
|
}
|
|
3608
|
-
var realFsPort, OWNER_ONLY_DIR_MODE, OWNER_ONLY_FILE_MODE, PERMISSION_BITS, realFarmFs, INT32_BYTE_LENGTH, realRunPort, MACOS_GUI_SESSION_MANAGER, realCredentialPort, SOCKET_PERMISSION_BITS, realHeadroomSocketTrust, realSpawnPort, realProcPort, EXECUTE_BITS_MASK, WINDOWS_DEFAULT_PATHEXT;
|
|
3612
|
+
var realFsPort, OWNER_ONLY_DIR_MODE, OWNER_ONLY_FILE_MODE, PERMISSION_BITS, realFarmFs, INT32_BYTE_LENGTH, FRONT_DOOR_SUPERVISOR_SUBCOMMAND, realRunPort, MACOS_GUI_SESSION_MANAGER, realCredentialPort, SOCKET_PERMISSION_BITS, realHeadroomSocketTrust, realSpawnPort, realProcPort, EXECUTE_BITS_MASK, WINDOWS_DEFAULT_PATHEXT;
|
|
3609
3613
|
var init_realPorts = __esm({
|
|
3610
3614
|
"src/realPorts.ts"() {
|
|
3611
3615
|
"use strict";
|
|
@@ -3740,6 +3744,7 @@ var init_realPorts = __esm({
|
|
|
3740
3744
|
}
|
|
3741
3745
|
};
|
|
3742
3746
|
INT32_BYTE_LENGTH = 4;
|
|
3747
|
+
FRONT_DOOR_SUPERVISOR_SUBCOMMAND = "__frontdoor-supervisor";
|
|
3743
3748
|
realRunPort = {
|
|
3744
3749
|
run(command, args) {
|
|
3745
3750
|
const result = spawnSync(command, [...args], { encoding: "utf8" });
|
|
@@ -6140,20 +6145,34 @@ function ensureFrontDoor(params) {
|
|
|
6140
6145
|
let replaced = false;
|
|
6141
6146
|
const distrusted = /* @__PURE__ */ new Set();
|
|
6142
6147
|
let lastRejection;
|
|
6148
|
+
const verifyWithRetry = (port) => {
|
|
6149
|
+
let verdict = ports.verifyListener(port);
|
|
6150
|
+
for (let attempt = 1; !verdict.ok && attempt < FRONTDOOR_PROBE_ATTEMPTS; attempt += 1) {
|
|
6151
|
+
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
6152
|
+
verdict = ports.verifyListener(port);
|
|
6153
|
+
}
|
|
6154
|
+
return verdict;
|
|
6155
|
+
};
|
|
6156
|
+
const stopAndAwaitExit = (supervisorPid, failure) => {
|
|
6157
|
+
ports.stopSupervisor(supervisorPid);
|
|
6158
|
+
while (ports.isRunning(supervisorPid)) {
|
|
6159
|
+
if (ports.now() >= deadline) {
|
|
6160
|
+
throw new FrontDoorStartError(`${failure}. Daemon log: ${paths.frontdoorLogPath}`);
|
|
6161
|
+
}
|
|
6162
|
+
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
6163
|
+
}
|
|
6164
|
+
};
|
|
6143
6165
|
for (; ; ) {
|
|
6144
6166
|
const state = readFrontDoorState(ports.fs, paths.frontdoorStateFile);
|
|
6145
6167
|
const supervisorPid = state?.supervisorPid;
|
|
6146
6168
|
if (supervisorPid !== void 0 && !distrusted.has(supervisorPid) && ports.isRunning(supervisorPid)) {
|
|
6147
6169
|
if (state?.port !== void 0 && state.connectPort !== void 0) {
|
|
6148
|
-
const verdict =
|
|
6170
|
+
const verdict = verifyWithRetry(state.port);
|
|
6149
6171
|
if (verdict.ok && !replaced && !spawned && (params.replace === true || (state.protocol ?? 0) < FRONT_DOOR_PROTOCOL)) {
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
}
|
|
6155
|
-
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
6156
|
-
}
|
|
6172
|
+
stopAndAwaitExit(
|
|
6173
|
+
supervisorPid,
|
|
6174
|
+
`the front door (pid ${String(supervisorPid)}, protocol ${String(state.protocol ?? 0)}; this launcher speaks protocol ${String(FRONT_DOOR_PROTOCOL)}) was asked to be replaced and did not exit`
|
|
6175
|
+
);
|
|
6157
6176
|
replaced = true;
|
|
6158
6177
|
continue;
|
|
6159
6178
|
}
|
|
@@ -6166,6 +6185,10 @@ function ensureFrontDoor(params) {
|
|
|
6166
6185
|
if (spawned) {
|
|
6167
6186
|
throw new FrontDoorStartError(`${lastRejection}; refusing to send this session's credentials to it. Daemon log: ${paths.frontdoorLogPath}`);
|
|
6168
6187
|
}
|
|
6188
|
+
if (ports.isFrontDoorSupervisor(supervisorPid)) {
|
|
6189
|
+
stopAndAwaitExit(supervisorPid, `the front door (pid ${String(supervisorPid)}) stopped answering and did not exit when asked to`);
|
|
6190
|
+
continue;
|
|
6191
|
+
}
|
|
6169
6192
|
distrusted.add(supervisorPid);
|
|
6170
6193
|
continue;
|
|
6171
6194
|
}
|
|
@@ -6196,7 +6219,7 @@ function ensureFrontDoor(params) {
|
|
|
6196
6219
|
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
6197
6220
|
}
|
|
6198
6221
|
}
|
|
6199
|
-
var FRONTDOOR_START_TIMEOUT_MS, FRONTDOOR_LAUNCHER_POLL_MS, FrontDoorStartError;
|
|
6222
|
+
var FRONTDOOR_START_TIMEOUT_MS, FRONTDOOR_LAUNCHER_POLL_MS, FRONTDOOR_PROBE_ATTEMPTS, FrontDoorStartError;
|
|
6200
6223
|
var init_ensure2 = __esm({
|
|
6201
6224
|
"src/frontdoor/ensure.ts"() {
|
|
6202
6225
|
"use strict";
|
|
@@ -6205,6 +6228,7 @@ var init_ensure2 = __esm({
|
|
|
6205
6228
|
init_state();
|
|
6206
6229
|
FRONTDOOR_START_TIMEOUT_MS = 3e4;
|
|
6207
6230
|
FRONTDOOR_LAUNCHER_POLL_MS = 100;
|
|
6231
|
+
FRONTDOOR_PROBE_ATTEMPTS = 3;
|
|
6208
6232
|
FrontDoorStartError = class extends CliError {
|
|
6209
6233
|
constructor(message) {
|
|
6210
6234
|
super(message);
|
|
@@ -7391,6 +7415,7 @@ function realEnsurePorts(paths, spawnDaemon) {
|
|
|
7391
7415
|
now: () => Date.now(),
|
|
7392
7416
|
sleep: realSleepSync,
|
|
7393
7417
|
spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
|
|
7418
|
+
isFrontDoorSupervisor: realIsFrontDoorSupervisor,
|
|
7394
7419
|
stopSupervisor: (pid) => {
|
|
7395
7420
|
process.kill(pid, "SIGTERM");
|
|
7396
7421
|
},
|
package/dist/types/index.d.ts
CHANGED
|
@@ -11662,8 +11662,10 @@ interface EnsureFrontDoorPorts {
|
|
|
11662
11662
|
readonly spawnSupervisor: (paths: LayoutPaths) => number;
|
|
11663
11663
|
/** Authenticates the provider listener on `port`: a TLS handshake chaining to agent-shim's CA and a healthy answer, with no capability sent (see `probeFrontDoorSync`). */
|
|
11664
11664
|
readonly verifyListener: (port: number) => ListenerVerdict;
|
|
11665
|
-
/** Asks a running front-door supervisor to exit, without waiting for it to: the caller polls `isRunning`. Only ever called for a pid whose recorded listener has just authenticated as agent-shim's own. */
|
|
11665
|
+
/** Asks a running front-door supervisor to exit, without waiting for it to: the caller polls `isRunning`. Only ever called for a pid whose recorded listener has just authenticated as agent-shim's own, or whose process is agent-shim's front-door supervisor (`isFrontDoorSupervisor`). */
|
|
11666
11666
|
readonly stopSupervisor: (pid: number) => void;
|
|
11667
|
+
/** Whether `pid` is a live agent-shim front-door supervisor process, read from the process's own command line. This is what separates a wedged door of this tool, which a replacement must retire so the two never coexist, from an unrelated process that reuses the recorded pid, which must never be signalled. */
|
|
11668
|
+
readonly isFrontDoorSupervisor: (pid: number) => boolean;
|
|
11667
11669
|
}
|
|
11668
11670
|
/**
|
|
11669
11671
|
* Brings the front door up for this launch, or finds it serving, and registers this launcher pid in its session registry: the fact that keeps the door from idling out while this session lives, and the record that holds this launch's capability token. The same lock-and-poll coordination as headroom's and the old codex daemon's ensure: the exclusive-create start lock decides which of several concurrent launches spawns the one supervisor, everyone waits on state.json, and a lock whose holder died is removed and retried. Ready means state names a live supervisor and both listeners' ports, which the supervisor writes only after both have bound (and the provider listener has answered its own health probe).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-shim",
|
|
3
|
-
"version": "9.12.
|
|
3
|
+
"version": "9.12.1",
|
|
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>",
|