claude-use 11.62.3 → 11.64.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 +2215 -1051
- package/dist/index.cjs +134 -47
- package/dist/index.mjs +134 -47
- package/dist/types/index.d.ts +1395 -39
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -306,7 +306,7 @@ var init_statusline = __esm({
|
|
|
306
306
|
init_graphemes();
|
|
307
307
|
init_languages();
|
|
308
308
|
STATUSLINE_HEADER_SEGMENTS = ["model", "provider", "route", "account", "identity", "headroom", "project", "vcs", "effort", "advisor", "version", "outputStyle", "cost", "dailyCost", "sessionName", "duration", "speed"];
|
|
309
|
-
STATUSLINE_ROWS = ["context", "quota", "addedDirs", "gitFiles", "memory", "environment", "sessionTime", "promptCache", "compactions", "tokens"];
|
|
309
|
+
STATUSLINE_ROWS = ["context", "quota", "addedDirs", "gitFiles", "memory", "environment", "sessionTime", "promptCache", "compactions", "tokens", "tools", "skills", "mcp", "agents", "todos"];
|
|
310
310
|
STATUSLINE_SESSION_TIME_PARTS = ["started", "lastReply"];
|
|
311
311
|
PROMPT_CACHE_TTL_SECONDS = { fiveMinutes: 300, oneHour: 3600 };
|
|
312
312
|
STATUSLINE_COLOUR_NAMES = [
|
|
@@ -337,13 +337,13 @@ var init_statusline = __esm({
|
|
|
337
337
|
PRESET_BUNDLES = {
|
|
338
338
|
standard: { layout: { header: DEFAULT_HEADER_SEGMENTS, rows: DEFAULT_ROWS }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: false }, context: { breakdown: "never" } },
|
|
339
339
|
full: {
|
|
340
|
-
layout: { header: ["model", "project", "vcs", "effort", "advisor", "version", "outputStyle", "cost", "sessionName", "duration"], rows: ["context", "quota", "addedDirs", "memory", "environment", "promptCache", "compactions", "tokens"] },
|
|
340
|
+
layout: { header: ["model", "project", "vcs", "effort", "advisor", "version", "outputStyle", "cost", "sessionName", "duration"], rows: ["context", "quota", "addedDirs", "memory", "environment", "tools", "skills", "mcp", "agents", "todos", "promptCache", "compactions", "tokens"] },
|
|
341
341
|
git: GIT_WITH_DIRTY_MARKER,
|
|
342
342
|
jj: { enabled: true, showDirty: true, showConflicts: true },
|
|
343
343
|
usage: { resetLabel: true },
|
|
344
344
|
context: { breakdown: "critical" }
|
|
345
345
|
},
|
|
346
|
-
essential: { layout: { header: ["model", "project", "vcs", "duration"], rows: ["context", "addedDirs"] }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: true }, context: { breakdown: "never" } },
|
|
346
|
+
essential: { layout: { header: ["model", "project", "vcs", "duration"], rows: ["context", "addedDirs", "tools", "agents", "todos"] }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: true }, context: { breakdown: "never" } },
|
|
347
347
|
minimal: { layout: { header: ["model", "project", "vcs"], rows: ["context", "addedDirs"] }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: true }, context: { breakdown: "never" } }
|
|
348
348
|
};
|
|
349
349
|
STATUSLINE_PATH_LEVELS = ["1", "2", "3", "full"];
|
|
@@ -459,6 +459,10 @@ var init_statusline = __esm({
|
|
|
459
459
|
promptCache: {
|
|
460
460
|
ttlSeconds: z2.number().int().min(1).describe("How long the prompt cache lives, in seconds, when the transcript has not yet shown which tier the session writes (five minutes or one hour); the tier the transcript shows takes over once it does.")
|
|
461
461
|
},
|
|
462
|
+
tools: {
|
|
463
|
+
nameMaxLength: z2.number().int().min(0).describe("The most terminal columns of a tool's name the tools row draws, cut with an ellipsis. With a limit set, a tool of an MCP server is shown by its own name, without the server's, whether or not it needs cutting. 0 draws every name whole, an MCP tool's with its server."),
|
|
464
|
+
maxVisible: z2.number().int().min(0).describe("The most kinds of finished tool call the tools row names, the most-used first, with the rest counted as +N more. 0 names every kind.")
|
|
465
|
+
},
|
|
462
466
|
colours: {
|
|
463
467
|
context: colourValue.describe("The colour of the context bar and its figures below the warning threshold."),
|
|
464
468
|
usage: colourValue.describe("The colour of the quota bars and their figures below the warning threshold."),
|
|
@@ -470,7 +474,9 @@ var init_statusline = __esm({
|
|
|
470
474
|
empty: colourValue.describe("The colour of the unused part of a bar."),
|
|
471
475
|
project: colourValue.describe("The colour of the project path segment."),
|
|
472
476
|
git: colourValue.describe("The colour of the version control segment's wrapper text (`git:(` and `)`)."),
|
|
473
|
-
gitBranch: colourValue.describe("The colour of the branch or bookmark and its ahead, behind and dirty markers.")
|
|
477
|
+
gitBranch: colourValue.describe("The colour of the branch or bookmark and its ahead, behind and dirty markers."),
|
|
478
|
+
activity: colourValue.describe("The colour of the names of the tools, skills and MCP servers the tools, skills and mcp rows draw. Their running markers take colours.warning and their finished markers colours.context."),
|
|
479
|
+
agent: colourValue.describe("The colour of an agent's type in the agents row.")
|
|
474
480
|
},
|
|
475
481
|
project: {
|
|
476
482
|
pathLevels: z2.enum(STATUSLINE_PATH_LEVELS).describe("How many trailing directories of the working directory the project segment shows: 1, 2 or 3, or full for the whole absolute path."),
|
|
@@ -497,7 +503,7 @@ var init_statusline = __esm({
|
|
|
497
503
|
LANGUAGE_ALIASES = { zh: "zh-Hans", "zh-TW": "zh-Hant" };
|
|
498
504
|
TOP_LEVEL = {
|
|
499
505
|
language: z2.enum(STATUSLINE_LANGUAGES).describe(LANGUAGE_DESCRIPTION),
|
|
500
|
-
preset: z2.enum(STATUSLINE_PRESETS).describe("A named bundle of settings (layout.header, layout.rows, git.enabled, git.showDirty, git.showAheadBehind, git.showLineDiff, jj.enabled, jj.showDirty, jj.showConflicts, usage.resetLabel and context.breakdown) that this layer sets beneath the keys it names itself and above everything the shallower layers set: standard is the statusline's own; full, essential and minimal are claude-hud's presets. Each draws the model, project and version control segments and the context row; full adds the effort, advisor, version, output style, cost, session name and duration segments and the quota, added directories, memory, environment, prompt cache, compactions and session tokens rows, with the token breakdown at high use, essential adds the duration
|
|
506
|
+
preset: z2.enum(STATUSLINE_PRESETS).describe("A named bundle of settings (layout.header, layout.rows, git.enabled, git.showDirty, git.showAheadBehind, git.showLineDiff, jj.enabled, jj.showDirty, jj.showConflicts, usage.resetLabel and context.breakdown) that this layer sets beneath the keys it names itself and above everything the shallower layers set: standard is the statusline's own; full, essential and minimal are claude-hud's presets. Each draws the model, project and version control segments and the context row; full adds the effort, advisor, version, output style, cost, session name and duration segments and the quota, added directories, memory, environment, tools, skills, mcp, agents, todos, prompt cache, compactions and session tokens rows, with the token breakdown at high use, essential adds the duration, the added directories row and the tools, agents and todos rows, and minimal adds the added directories row alone.")
|
|
501
507
|
};
|
|
502
508
|
StatuslineSchema = z2.strictObject({
|
|
503
509
|
language: z2.enum(LANGUAGE_TAGS).transform(canonicalLanguage).describe(LANGUAGE_DESCRIPTION).optional(),
|
|
@@ -518,6 +524,7 @@ var init_statusline = __esm({
|
|
|
518
524
|
environment: z2.strictObject(SHAPES.environment).partial().optional(),
|
|
519
525
|
sessionTime: z2.strictObject(SHAPES.sessionTime).partial().optional(),
|
|
520
526
|
promptCache: z2.strictObject(SHAPES.promptCache).partial().optional(),
|
|
527
|
+
tools: z2.strictObject(SHAPES.tools).partial().optional(),
|
|
521
528
|
colours: z2.strictObject(SHAPES.colours).partial().optional(),
|
|
522
529
|
project: z2.strictObject(SHAPES.project).partial().optional(),
|
|
523
530
|
git: z2.strictObject(SHAPES.git).partial().optional(),
|
|
@@ -542,6 +549,7 @@ var init_statusline = __esm({
|
|
|
542
549
|
environment: z2.strictObject(SHAPES.environment),
|
|
543
550
|
sessionTime: z2.strictObject(SHAPES.sessionTime),
|
|
544
551
|
promptCache: z2.strictObject(SHAPES.promptCache),
|
|
552
|
+
tools: z2.strictObject(SHAPES.tools),
|
|
545
553
|
colours: z2.strictObject(SHAPES.colours),
|
|
546
554
|
project: z2.strictObject(SHAPES.project),
|
|
547
555
|
git: z2.strictObject(SHAPES.git),
|
|
@@ -566,6 +574,7 @@ var init_statusline = __esm({
|
|
|
566
574
|
environment: { threshold: 0 },
|
|
567
575
|
sessionTime: { parts: [...STATUSLINE_SESSION_TIME_PARTS] },
|
|
568
576
|
promptCache: { ttlSeconds: PROMPT_CACHE_TTL_SECONDS.fiveMinutes },
|
|
577
|
+
tools: { nameMaxLength: 0, maxVisible: 4 },
|
|
569
578
|
colours: {
|
|
570
579
|
context: "green",
|
|
571
580
|
usage: "green",
|
|
@@ -577,7 +586,9 @@ var init_statusline = __esm({
|
|
|
577
586
|
empty: "brightBlack",
|
|
578
587
|
project: "yellow",
|
|
579
588
|
git: "magenta",
|
|
580
|
-
gitBranch: "cyan"
|
|
589
|
+
gitBranch: "cyan",
|
|
590
|
+
activity: "cyan",
|
|
591
|
+
agent: "magenta"
|
|
581
592
|
},
|
|
582
593
|
project: { pathLevels: "1", addedDirsLayout: "inline" },
|
|
583
594
|
git: { enabled: true, showDirty: true, showAheadBehind: false, showLineDiff: false, branchOverflow: "truncate", pushWarnAt: 0, pushCriticalAt: 0 },
|
|
@@ -3901,12 +3912,13 @@ function pruneDeadFrontDoorSessions(fs14, sessionsDir, listed, isRunning) {
|
|
|
3901
3912
|
}
|
|
3902
3913
|
return removed;
|
|
3903
3914
|
}
|
|
3904
|
-
var FRONT_DOOR_PROTOCOL, FrontDoorSessionSchema, FrontDoorStateSchema, MAX_TCP_PORT, FrontDoorDirectRecordSchema, RECORD_TEMPORARY_FILE;
|
|
3915
|
+
var FRONT_DOOR_PROTOCOL, FRONT_DOOR_HANDOVER_PROTOCOL, FrontDoorSessionSchema, FrontDoorStateSchema, MAX_TCP_PORT, FrontDoorDirectRecordSchema, RECORD_TEMPORARY_FILE;
|
|
3905
3916
|
var init_state = __esm({
|
|
3906
3917
|
"src/frontdoor/state.ts"() {
|
|
3907
3918
|
"use strict";
|
|
3908
3919
|
init_schema();
|
|
3909
|
-
FRONT_DOOR_PROTOCOL =
|
|
3920
|
+
FRONT_DOOR_PROTOCOL = 6;
|
|
3921
|
+
FRONT_DOOR_HANDOVER_PROTOCOL = 6;
|
|
3910
3922
|
FrontDoorSessionSchema = z5.strictObject({ pid: z5.number().int().positive(), startedAt: z5.number(), token: z5.string().min(1), supervisorPid: z5.number().int().positive().optional(), sessionId: z5.string().min(1).optional(), models: ModelsConfigSchema.optional() });
|
|
3911
3923
|
FrontDoorStateSchema = z5.strictObject({
|
|
3912
3924
|
/**
|
|
@@ -4003,18 +4015,24 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4003
4015
|
...lastConnectPort === void 0 ? {} : { lastConnectPort },
|
|
4004
4016
|
...lastDirectPort === void 0 ? {} : { lastDirectPort }
|
|
4005
4017
|
});
|
|
4018
|
+
const { predecessor } = ports;
|
|
4019
|
+
const sourceOf = (listener, preferredPort) => predecessor === void 0 ? { preferredPort } : { inherit: async () => await predecessor.take(listener) };
|
|
4006
4020
|
const fail = (message) => {
|
|
4007
4021
|
ports.closeRcStreamHub();
|
|
4008
|
-
|
|
4009
|
-
|
|
4022
|
+
if (predecessor === void 0) {
|
|
4023
|
+
writeFrontDoorState(fs14, paths.frontdoorStateFile, { lastError: message, ...sticky() });
|
|
4024
|
+
fs14.removeRecursive(paths.frontdoorLockFile);
|
|
4025
|
+
}
|
|
4010
4026
|
ports.log(`agent-shim frontdoor supervisor: ${message}`);
|
|
4011
4027
|
return 1;
|
|
4012
4028
|
};
|
|
4013
|
-
|
|
4029
|
+
if (predecessor === void 0) {
|
|
4030
|
+
writeFrontDoorState(fs14, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, ...sticky() });
|
|
4031
|
+
}
|
|
4014
4032
|
const previousSticky = lastPort;
|
|
4015
4033
|
let http3;
|
|
4016
4034
|
try {
|
|
4017
|
-
http3 = await ports.startProviderListener(lastPort);
|
|
4035
|
+
http3 = await ports.startProviderListener(sourceOf("provider", lastPort));
|
|
4018
4036
|
} catch (error) {
|
|
4019
4037
|
ports.doorHealth.listenerFailed("provider", error instanceof Error ? error.message : String(error));
|
|
4020
4038
|
return fail(`could not start the provider listener: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -4026,7 +4044,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4026
4044
|
const previousStickyConnect = lastConnectPort;
|
|
4027
4045
|
let connect3;
|
|
4028
4046
|
try {
|
|
4029
|
-
connect3 = await ports.startConnectListener(lastConnectPort);
|
|
4047
|
+
connect3 = await ports.startConnectListener(sourceOf("connect", lastConnectPort));
|
|
4030
4048
|
} catch (error) {
|
|
4031
4049
|
await http3.close();
|
|
4032
4050
|
ports.doorHealth.listenerFailed("connect", error instanceof Error ? error.message : String(error));
|
|
@@ -4039,7 +4057,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4039
4057
|
const previousStickyDirect = lastDirectPort;
|
|
4040
4058
|
let direct;
|
|
4041
4059
|
try {
|
|
4042
|
-
direct = await ports.startDirectListener(lastDirectPort);
|
|
4060
|
+
direct = await ports.startDirectListener(sourceOf("direct", lastDirectPort));
|
|
4043
4061
|
} catch (error) {
|
|
4044
4062
|
await connect3.close();
|
|
4045
4063
|
await http3.close();
|
|
@@ -4053,8 +4071,12 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4053
4071
|
writeFrontDoorDirectRecord(fs14, paths.frontdoorDirectRecordsDir, { pid: ports.ownPid, directPort: direct.port });
|
|
4054
4072
|
writeFrontDoorState(fs14, paths.frontdoorStateFile, { protocol: FRONT_DOOR_PROTOCOL, supervisorPid: ports.ownPid, port: http3.port, connectPort: connect3.port, directPort: direct.port, ...sticky() });
|
|
4055
4073
|
ports.doorHealth.generation({ providerPort: http3.port, connectPort: connect3.port, directPort: direct.port });
|
|
4056
|
-
|
|
4057
|
-
|
|
4074
|
+
if (predecessor === void 0) {
|
|
4075
|
+
fs14.removeRecursive(paths.frontdoorLockFile);
|
|
4076
|
+
} else {
|
|
4077
|
+
predecessor.serving();
|
|
4078
|
+
}
|
|
4079
|
+
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: front door on 127.0.0.1:${String(http3.port)}, CONNECT surface on 127.0.0.1:${String(connect3.port)}${predecessor === void 0 ? "" : ", taken over from the door it replaced"}`);
|
|
4058
4080
|
const watchdog = ports.startWatchdog?.();
|
|
4059
4081
|
let idleSince;
|
|
4060
4082
|
let ticks = 0;
|
|
@@ -4074,14 +4096,16 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4074
4096
|
resolve();
|
|
4075
4097
|
};
|
|
4076
4098
|
ports.retire?.addEventListener("abort", wake, { once: true });
|
|
4099
|
+
ports.handover?.requested.addEventListener("abort", wake, { once: true });
|
|
4077
4100
|
void ports.sleep(FRONTDOOR_POLL_MS).then(() => {
|
|
4078
4101
|
ports.retire?.removeEventListener("abort", wake);
|
|
4102
|
+
ports.handover?.requested.removeEventListener("abort", wake);
|
|
4079
4103
|
resolve();
|
|
4080
4104
|
});
|
|
4081
4105
|
});
|
|
4082
4106
|
};
|
|
4083
4107
|
const retireByDrain = async () => {
|
|
4084
|
-
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}:
|
|
4108
|
+
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: releasing the front door's addresses and finishing the connections it carries`);
|
|
4085
4109
|
watchdog?.stop();
|
|
4086
4110
|
ports.stopBackgroundWork?.();
|
|
4087
4111
|
const drained = [direct.drain(), connect3.drain(), http3.drain()];
|
|
@@ -4096,6 +4120,17 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4096
4120
|
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: the connections this door carried have ended; exiting`);
|
|
4097
4121
|
return 0;
|
|
4098
4122
|
};
|
|
4123
|
+
const handOverThenDrain = async (run) => {
|
|
4124
|
+
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: asked to hand the front door's listeners to a successor; accepting on them until it serves`);
|
|
4125
|
+
const outcome = await run({ provider: http3.listening, connect: connect3.listening, direct: direct.listening });
|
|
4126
|
+
if (outcome.ok) {
|
|
4127
|
+
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: successor ${String(outcome.successorPid)} serves the front door's listeners`);
|
|
4128
|
+
ports.doorHealth.superseded(outcome.successorPid);
|
|
4129
|
+
} else {
|
|
4130
|
+
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: the handover failed (${outcome.reason}); retiring by drain so a successor is started on the released addresses`);
|
|
4131
|
+
}
|
|
4132
|
+
return await retireByDrain();
|
|
4133
|
+
};
|
|
4099
4134
|
const closeServing = async () => {
|
|
4100
4135
|
watchdog?.stop();
|
|
4101
4136
|
await direct.close();
|
|
@@ -4113,8 +4148,12 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4113
4148
|
};
|
|
4114
4149
|
for (; ; ) {
|
|
4115
4150
|
if (ports.retire?.aborted === true) {
|
|
4151
|
+
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: asked to exit`);
|
|
4116
4152
|
return await retireByDrain();
|
|
4117
4153
|
}
|
|
4154
|
+
if (ports.handover?.requested.aborted === true && supersededBy === void 0) {
|
|
4155
|
+
return await handOverThenDrain(ports.handover.run);
|
|
4156
|
+
}
|
|
4118
4157
|
if (options.tickLimit !== void 0 && ticks >= options.tickLimit) {
|
|
4119
4158
|
watchdog?.stop();
|
|
4120
4159
|
return FRONTDOOR_SUPERVISOR_STILL_RUNNING;
|
|
@@ -4252,8 +4291,10 @@ function caParses(ca) {
|
|
|
4252
4291
|
return false;
|
|
4253
4292
|
}
|
|
4254
4293
|
}
|
|
4255
|
-
async function startConnectServer(config, effects,
|
|
4294
|
+
async function startConnectServer(config, effects, source) {
|
|
4256
4295
|
const tunnelTokens = /* @__PURE__ */ new WeakMap();
|
|
4296
|
+
const ledger = createConnectionLedger(config.limits, config.isLiveCapability);
|
|
4297
|
+
const lateSessionDeadlines = /* @__PURE__ */ new WeakMap();
|
|
4257
4298
|
const onUpgrade = (host) => (request4, socket, head) => {
|
|
4258
4299
|
config.capture?.upgrade(request4);
|
|
4259
4300
|
if (head.length > 0) {
|
|
@@ -4275,6 +4316,12 @@ ${request4.rawHeaders.reduce((accumulated, value, index) => index % 2 === 0 ? `$
|
|
|
4275
4316
|
return { host, serveSecure: serveSecure2, tlsAcceptor: tlsAcceptor2 };
|
|
4276
4317
|
}
|
|
4277
4318
|
const handleHostRequest = async (request4, response) => {
|
|
4319
|
+
if (ledger.retiring()) {
|
|
4320
|
+
clearTimeout(lateSessionDeadlines.get(request4.socket));
|
|
4321
|
+
response.once("close", () => {
|
|
4322
|
+
request4.socket.end();
|
|
4323
|
+
});
|
|
4324
|
+
}
|
|
4278
4325
|
if (config.localSurface !== void 0 && await config.localSurface.serve(host, request4, response)) {
|
|
4279
4326
|
return;
|
|
4280
4327
|
}
|
|
@@ -4294,13 +4341,19 @@ ${request4.rawHeaders.reduce((accumulated, value, index) => index % 2 === 0 ? `$
|
|
|
4294
4341
|
const httpSession = effects.createHttpSession(handler, onUpgrade(host));
|
|
4295
4342
|
const serveSecure = (secure, capability) => {
|
|
4296
4343
|
tunnelTokens.set(secure, capability);
|
|
4344
|
+
if (ledger.retiring()) {
|
|
4345
|
+
const deadline = setTimeout(() => {
|
|
4346
|
+
secure.destroy();
|
|
4347
|
+
}, config.limits.headDeadlineMs);
|
|
4348
|
+
deadline.unref();
|
|
4349
|
+
lateSessionDeadlines.set(secure, deadline);
|
|
4350
|
+
}
|
|
4297
4351
|
httpSession.serve(secure);
|
|
4298
4352
|
};
|
|
4299
4353
|
const tlsAcceptor = effects.createTlsAcceptor(config.leafFor(host), serveSecure);
|
|
4300
4354
|
return { host, serveSecure, httpSession, tlsAcceptor };
|
|
4301
4355
|
});
|
|
4302
|
-
const
|
|
4303
|
-
const listener = await effects.listenLoopback(preferredPort, (socket) => {
|
|
4356
|
+
const listener = await effects.listenLoopback(source, (socket) => {
|
|
4304
4357
|
handleConnect(socket, { config, effects, sessions, ledger });
|
|
4305
4358
|
});
|
|
4306
4359
|
const apiSession = sessions.find((session) => session.host === config.routedHost);
|
|
@@ -4313,7 +4366,7 @@ ${request4.rawHeaders.reduce((accumulated, value, index) => index % 2 === 0 ? `$
|
|
|
4313
4366
|
}
|
|
4314
4367
|
session.serveSecure(secure, config.transparentCapability ?? "");
|
|
4315
4368
|
});
|
|
4316
|
-
const transparent = config.transparentPort === void 0 || apiSession === void 0 ? void 0 : await effects.listenLoopback(config.transparentPort, (socket) => {
|
|
4369
|
+
const transparent = config.transparentPort === void 0 || apiSession === void 0 ? void 0 : await effects.listenLoopback({ preferredPort: config.transparentPort }, (socket) => {
|
|
4317
4370
|
sniAcceptor.accept(socket);
|
|
4318
4371
|
});
|
|
4319
4372
|
const closeSurface = async () => {
|
|
@@ -4328,6 +4381,7 @@ ${request4.rawHeaders.reduce((accumulated, value, index) => index % 2 === 0 ? `$
|
|
|
4328
4381
|
};
|
|
4329
4382
|
return {
|
|
4330
4383
|
port: listener.port,
|
|
4384
|
+
listening: listener.listening,
|
|
4331
4385
|
...transparent === void 0 ? {} : { transparentPort: transparent.port },
|
|
4332
4386
|
openTunnels: ledger.openTunnels,
|
|
4333
4387
|
drain: async () => {
|
|
@@ -4344,7 +4398,9 @@ function createConnectionLedger(limits, isLiveCapability2) {
|
|
|
4344
4398
|
const authenticated = /* @__PURE__ */ new Map();
|
|
4345
4399
|
let tunnels = 0;
|
|
4346
4400
|
const blind = /* @__PURE__ */ new Set();
|
|
4347
|
-
|
|
4401
|
+
const live = /* @__PURE__ */ new Set();
|
|
4402
|
+
let retiring = false;
|
|
4403
|
+
let onNoConnections;
|
|
4348
4404
|
const leavePending = (socket) => {
|
|
4349
4405
|
const deadline = pending.get(socket);
|
|
4350
4406
|
if (deadline !== void 0) {
|
|
@@ -4376,20 +4432,19 @@ function createConnectionLedger(limits, isLiveCapability2) {
|
|
|
4376
4432
|
refuse(socket, REFUSAL.requestTimeout);
|
|
4377
4433
|
}, limits.headDeadlineMs)
|
|
4378
4434
|
);
|
|
4435
|
+
live.add(socket);
|
|
4379
4436
|
socket.once("close", () => {
|
|
4380
4437
|
leavePending(socket);
|
|
4438
|
+
live.delete(socket);
|
|
4439
|
+
if (live.size === 0) {
|
|
4440
|
+
onNoConnections?.();
|
|
4441
|
+
}
|
|
4381
4442
|
});
|
|
4382
4443
|
},
|
|
4383
4444
|
headReceived: leavePending,
|
|
4384
4445
|
openTunnels: () => tunnels,
|
|
4385
4446
|
retire: async () => {
|
|
4386
|
-
|
|
4387
|
-
socket.destroy();
|
|
4388
|
-
}
|
|
4389
|
-
for (const deadline of pending.values()) {
|
|
4390
|
-
clearTimeout(deadline);
|
|
4391
|
-
}
|
|
4392
|
-
pending.clear();
|
|
4447
|
+
retiring = true;
|
|
4393
4448
|
for (const sockets of authenticated.values()) {
|
|
4394
4449
|
for (const socket of sockets) {
|
|
4395
4450
|
if (!blind.has(socket)) {
|
|
@@ -4397,12 +4452,13 @@ function createConnectionLedger(limits, isLiveCapability2) {
|
|
|
4397
4452
|
}
|
|
4398
4453
|
}
|
|
4399
4454
|
}
|
|
4400
|
-
if (
|
|
4455
|
+
if (live.size > 0) {
|
|
4401
4456
|
await new Promise((resolve) => {
|
|
4402
|
-
|
|
4457
|
+
onNoConnections = resolve;
|
|
4403
4458
|
});
|
|
4404
4459
|
}
|
|
4405
4460
|
},
|
|
4461
|
+
retiring: () => retiring,
|
|
4406
4462
|
establish: (socket, capability, kind) => {
|
|
4407
4463
|
if (tunnels >= limits.maxTunnels) {
|
|
4408
4464
|
return false;
|
|
@@ -4417,9 +4473,6 @@ function createConnectionLedger(limits, isLiveCapability2) {
|
|
|
4417
4473
|
socket.once("close", () => {
|
|
4418
4474
|
tunnels -= 1;
|
|
4419
4475
|
blind.delete(socket);
|
|
4420
|
-
if (blind.size === 0) {
|
|
4421
|
-
onNoBlindTunnels?.();
|
|
4422
|
-
}
|
|
4423
4476
|
sockets.delete(socket);
|
|
4424
4477
|
if (sockets.size === 0 && authenticated.get(capability) === sockets) {
|
|
4425
4478
|
authenticated.delete(capability);
|
|
@@ -4627,7 +4680,7 @@ var init_package = __esm({
|
|
|
4627
4680
|
"package.json"() {
|
|
4628
4681
|
package_default = {
|
|
4629
4682
|
name: "claude-use",
|
|
4630
|
-
version: "11.
|
|
4683
|
+
version: "11.64.0",
|
|
4631
4684
|
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.",
|
|
4632
4685
|
license: "MIT",
|
|
4633
4686
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -10154,7 +10207,8 @@ var init_replacement = __esm({
|
|
|
10154
10207
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
10155
10208
|
function ensureFrontDoor(params) {
|
|
10156
10209
|
const { paths, ports } = params;
|
|
10157
|
-
const
|
|
10210
|
+
const startedAt = ports.now();
|
|
10211
|
+
let deadline = startedAt + FRONTDOOR_START_TIMEOUT_MS;
|
|
10158
10212
|
let spawned = false;
|
|
10159
10213
|
let replaced = false;
|
|
10160
10214
|
const distrusted = /* @__PURE__ */ new Set();
|
|
@@ -10194,6 +10248,19 @@ function ensureFrontDoor(params) {
|
|
|
10194
10248
|
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
10195
10249
|
}
|
|
10196
10250
|
};
|
|
10251
|
+
const handOverAndAwait = (supervisorPid, doorProtocol, reason, request4) => {
|
|
10252
|
+
recordReplacement(supervisorPid, doorProtocol, reason, "SIGUSR2");
|
|
10253
|
+
request4(supervisorPid);
|
|
10254
|
+
const waitEnds = ports.now() + FRONTDOOR_START_TIMEOUT_MS + FRONTDOOR_EXIT_GRACE_MS;
|
|
10255
|
+
deadline += FRONTDOOR_START_TIMEOUT_MS + FRONTDOOR_EXIT_GRACE_MS;
|
|
10256
|
+
while (ports.isRunning(supervisorPid) && readFrontDoorState(ports.fs, paths.frontdoorStateFile)?.supervisorPid === supervisorPid) {
|
|
10257
|
+
if (ports.now() >= waitEnds) {
|
|
10258
|
+
stopAndAwaitExit(supervisorPid, doorProtocol, reason, `the front door (pid ${String(supervisorPid)}) did not act on a request to hand its listeners over, and did not exit when asked to`);
|
|
10259
|
+
return;
|
|
10260
|
+
}
|
|
10261
|
+
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
10262
|
+
}
|
|
10263
|
+
};
|
|
10197
10264
|
for (; ; ) {
|
|
10198
10265
|
const state = readFrontDoorState(ports.fs, paths.frontdoorStateFile);
|
|
10199
10266
|
const supervisorPid = state?.supervisorPid;
|
|
@@ -10207,12 +10274,16 @@ function ensureFrontDoor(params) {
|
|
|
10207
10274
|
const verdict = verifyWithRetry(state.port);
|
|
10208
10275
|
const doorProtocol = state.protocol ?? 0;
|
|
10209
10276
|
if (verdict.ok && !replaced && !spawned && (params.replace !== void 0 || doorProtocol < FRONT_DOOR_PROTOCOL)) {
|
|
10210
|
-
|
|
10211
|
-
supervisorPid,
|
|
10212
|
-
|
|
10213
|
-
|
|
10214
|
-
|
|
10215
|
-
|
|
10277
|
+
if (params.replace !== void 0 && doorProtocol >= FRONT_DOOR_HANDOVER_PROTOCOL && ports.requestHandover !== void 0 && ports.isFrontDoorSupervisor(supervisorPid)) {
|
|
10278
|
+
handOverAndAwait(supervisorPid, doorProtocol, params.replace, ports.requestHandover);
|
|
10279
|
+
} else {
|
|
10280
|
+
stopAndAwaitExit(
|
|
10281
|
+
supervisorPid,
|
|
10282
|
+
doorProtocol,
|
|
10283
|
+
params.replace ?? "protocol-older",
|
|
10284
|
+
`the front door (pid ${String(supervisorPid)}, protocol ${String(doorProtocol)}; this launcher speaks protocol ${String(FRONT_DOOR_PROTOCOL)}) was asked to be replaced and did not exit`
|
|
10285
|
+
);
|
|
10286
|
+
}
|
|
10216
10287
|
replaced = true;
|
|
10217
10288
|
continue;
|
|
10218
10289
|
}
|
|
@@ -10264,7 +10335,7 @@ function ensureFrontDoor(params) {
|
|
|
10264
10335
|
if (ports.now() >= deadline) {
|
|
10265
10336
|
const lastError = state?.lastError;
|
|
10266
10337
|
throw new FrontDoorStartError(
|
|
10267
|
-
`the front door did not become ready within ${String(
|
|
10338
|
+
`the front door did not become ready within ${String(deadline - startedAt)}ms` + (lastError === void 0 ? "" : ` (last error: ${lastError})`) + (lastRejection === void 0 ? "" : ` (${lastRejection})`) + (busyDoor === void 0 ? "" : `. It was not replaced because ${String(busyDoor.sessions)} live session(s) are using it and would lose their connections; run \`agent-shim frontdoor restart\` to replace it deliberately`) + `. Daemon log: ${paths.frontdoorLogPath}`
|
|
10268
10339
|
);
|
|
10269
10340
|
}
|
|
10270
10341
|
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
@@ -11907,6 +11978,12 @@ function realEnsurePorts(paths, spawnDaemon) {
|
|
|
11907
11978
|
killSupervisor: (pid) => {
|
|
11908
11979
|
process.kill(pid, "SIGKILL");
|
|
11909
11980
|
},
|
|
11981
|
+
// Windows has no user signals (Node refuses to send one), so a replacement there keeps the stop-and-start path.
|
|
11982
|
+
...process.platform === "win32" ? {} : {
|
|
11983
|
+
requestHandover: (pid) => {
|
|
11984
|
+
process.kill(pid, "SIGUSR2");
|
|
11985
|
+
}
|
|
11986
|
+
},
|
|
11910
11987
|
// Read fresh for each probe: a replacement supervisor may have regenerated an unparseable CA, and the probe must trust exactly what the serving door's leaf chains to.
|
|
11911
11988
|
verifyListener: (port) => probeFrontDoorSync(port, fs13.readFileSync(paths.frontdoorCaCertFile, "utf8"))
|
|
11912
11989
|
};
|
|
@@ -14336,7 +14413,7 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
|
|
|
14336
14413
|
function realConnectEffects(ports = DOOR_SOURCE_PORTS) {
|
|
14337
14414
|
const plainAgent = new ExemptHttpAgent(ports);
|
|
14338
14415
|
const tlsAgent = new ExemptTlsAgent(ports);
|
|
14339
|
-
const listenOnce = async (
|
|
14416
|
+
const listenOnce = async (target, onSocket) => await new Promise((resolve, reject) => {
|
|
14340
14417
|
const accepted = /* @__PURE__ */ new Set();
|
|
14341
14418
|
const server = net2.createServer((socket) => {
|
|
14342
14419
|
accepted.add(socket);
|
|
@@ -14346,7 +14423,7 @@ function realConnectEffects(ports = DOOR_SOURCE_PORTS) {
|
|
|
14346
14423
|
onSocket(socket);
|
|
14347
14424
|
});
|
|
14348
14425
|
server.once("error", reject);
|
|
14349
|
-
|
|
14426
|
+
const onListening = () => {
|
|
14350
14427
|
const address = server.address();
|
|
14351
14428
|
const bound = typeof address === "object" && address !== null ? address.port : 0;
|
|
14352
14429
|
if (bound === 0) {
|
|
@@ -14355,6 +14432,7 @@ function realConnectEffects(ports = DOOR_SOURCE_PORTS) {
|
|
|
14355
14432
|
}
|
|
14356
14433
|
resolve({
|
|
14357
14434
|
port: bound,
|
|
14435
|
+
listening: server,
|
|
14358
14436
|
// The listening socket is released by `close` at once; the connections already accepted are untouched and keep the server's `close` callback pending until they end.
|
|
14359
14437
|
stopAccepting: () => {
|
|
14360
14438
|
server.close();
|
|
@@ -14370,10 +14448,19 @@ function realConnectEffects(ports = DOOR_SOURCE_PORTS) {
|
|
|
14370
14448
|
});
|
|
14371
14449
|
}
|
|
14372
14450
|
});
|
|
14373
|
-
}
|
|
14451
|
+
};
|
|
14452
|
+
if (typeof target === "number") {
|
|
14453
|
+
server.listen(target, "127.0.0.1", onListening);
|
|
14454
|
+
} else {
|
|
14455
|
+
server.listen(target, onListening);
|
|
14456
|
+
}
|
|
14374
14457
|
});
|
|
14375
14458
|
return {
|
|
14376
|
-
listenLoopback: async (
|
|
14459
|
+
listenLoopback: async (source, onSocket) => {
|
|
14460
|
+
if ("inherit" in source) {
|
|
14461
|
+
return await listenOnce(await source.inherit(), onSocket);
|
|
14462
|
+
}
|
|
14463
|
+
const { preferredPort } = source;
|
|
14377
14464
|
if (preferredPort !== void 0) {
|
|
14378
14465
|
try {
|
|
14379
14466
|
return await listenOnce(preferredPort, onSocket);
|