claude-use 11.53.0 → 11.54.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 +918 -600
- package/dist/index.cjs +52 -10
- package/dist/index.mjs +53 -11
- package/dist/types/index.d.ts +840 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -140,7 +140,7 @@ var init_proxyBypass = __esm({
|
|
|
140
140
|
|
|
141
141
|
// src/config/statusline.ts
|
|
142
142
|
function distinctList(member) {
|
|
143
|
-
return import_zod.z.array(member).refine((items) => new Set(items).size === items.length, "must not repeat
|
|
143
|
+
return import_zod.z.array(member).refine((items) => new Set(items).size === items.length, "must not repeat an entry");
|
|
144
144
|
}
|
|
145
145
|
function isSingleVisibleGrapheme(text) {
|
|
146
146
|
return [...GRAPHEMES.segment(text)].length === 1 && !/[\p{C}\p{Z}]/u.test(text);
|
|
@@ -165,12 +165,12 @@ function resolveStatusline(settings) {
|
|
|
165
165
|
}
|
|
166
166
|
return resolved;
|
|
167
167
|
}
|
|
168
|
-
var import_zod, STATUSLINE_HEADER_SEGMENTS, STATUSLINE_ROWS, STATUSLINE_COLOUR_NAMES, DEFAULT_HEADER_SEGMENTS, DEFAULT_ROWS, STATUSLINE_PATH_LEVELS, MAX_PERCENT, MAX_STATUSLINE_PALETTE_INDEX, MAX_STATUSLINE_LABEL_CHARS, MAX_BAR_CELLS, LABEL_RE2, colourValue, GRAPHEMES, barCharacter, labelText, wholePercent, SHAPES, StatuslineSchema, ResolvedStatuslineSchema, STATUSLINE_DEFAULTS, STATUSLINE_ENV;
|
|
168
|
+
var import_zod, STATUSLINE_HEADER_SEGMENTS, STATUSLINE_ROWS, STATUSLINE_COLOUR_NAMES, DEFAULT_HEADER_SEGMENTS, DEFAULT_ROWS, STATUSLINE_PATH_LEVELS, MAX_PERCENT, MAX_STATUSLINE_PALETTE_INDEX, MAX_STATUSLINE_LABEL_CHARS, MAX_BAR_CELLS, MAX_ACCOUNT_USER_CHARS, MAX_DISPLAY_TEXT_CHARS, LABEL_RE2, OPTIONAL_LABEL_RE, colourValue, GRAPHEMES, barCharacter, labelText, overrideText, wholePercent, SHAPES, StatuslineSchema, ResolvedStatuslineSchema, STATUSLINE_DEFAULTS, STATUSLINE_ENV;
|
|
169
169
|
var init_statusline = __esm({
|
|
170
170
|
"src/config/statusline.ts"() {
|
|
171
171
|
"use strict";
|
|
172
172
|
import_zod = require("zod");
|
|
173
|
-
STATUSLINE_HEADER_SEGMENTS = ["model", "provider", "route", "account", "identity", "headroom", "project", "vcs"];
|
|
173
|
+
STATUSLINE_HEADER_SEGMENTS = ["model", "provider", "route", "account", "identity", "headroom", "project", "vcs", "effort", "advisor", "version", "outputStyle"];
|
|
174
174
|
STATUSLINE_ROWS = ["context", "quota", "addedDirs", "gitFiles"];
|
|
175
175
|
STATUSLINE_COLOUR_NAMES = [
|
|
176
176
|
"default",
|
|
@@ -199,17 +199,39 @@ var init_statusline = __esm({
|
|
|
199
199
|
MAX_STATUSLINE_PALETTE_INDEX = 255;
|
|
200
200
|
MAX_STATUSLINE_LABEL_CHARS = 12;
|
|
201
201
|
MAX_BAR_CELLS = 40;
|
|
202
|
+
MAX_ACCOUNT_USER_CHARS = 254;
|
|
203
|
+
MAX_DISPLAY_TEXT_CHARS = 80;
|
|
202
204
|
LABEL_RE2 = /^[^\p{C}\p{Z}]+(?: [^\p{C}\p{Z}]+)*$/u;
|
|
205
|
+
OPTIONAL_LABEL_RE = /^(?:[^\p{C}\p{Z}]+(?: [^\p{C}\p{Z}]+)*)?$/u;
|
|
203
206
|
colourValue = import_zod.z.union([import_zod.z.enum(STATUSLINE_COLOUR_NAMES), import_zod.z.number().int().min(0).max(MAX_STATUSLINE_PALETTE_INDEX), import_zod.z.string().regex(/^#[0-9a-fA-F]{6}$/, "must be a colour name, a palette index from 0 to 255 or #rrggbb")]);
|
|
204
207
|
GRAPHEMES = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
205
208
|
barCharacter = import_zod.z.string().refine(isSingleVisibleGrapheme, "must be a single visible character");
|
|
206
209
|
labelText = import_zod.z.string().max(MAX_STATUSLINE_LABEL_CHARS).regex(LABEL_RE2, "must be visible text without control characters");
|
|
210
|
+
overrideText = import_zod.z.string().max(MAX_DISPLAY_TEXT_CHARS).regex(OPTIONAL_LABEL_RE, "must be visible text without control characters");
|
|
207
211
|
wholePercent = import_zod.z.number().int().min(1).max(MAX_PERCENT);
|
|
208
212
|
SHAPES = {
|
|
209
213
|
layout: {
|
|
210
214
|
header: distinctList(import_zod.z.enum(STATUSLINE_HEADER_SEGMENTS)).describe("The header segments to draw, in drawing order; a segment left out is hidden, and an empty list hides the header."),
|
|
211
215
|
rows: distinctList(import_zod.z.enum(STATUSLINE_ROWS)).describe("The rows to draw below the header, in drawing order; a row left out is hidden, and an empty list hides every row.")
|
|
212
216
|
},
|
|
217
|
+
model: {
|
|
218
|
+
format: import_zod.z.enum(["full", "compact", "short"]).describe("How the model's name is written: full is the name as the client gives it, compact drops a context-window suffix such as (1M context), and short also drops a leading Claude."),
|
|
219
|
+
override: overrideText.describe("A name to show in place of the client's own model name, whatever model is running; empty shows the model's own name. A dynamic mode's served model still follows it."),
|
|
220
|
+
source: import_zod.z.enum(["client", "transcript", "auto"]).describe("Where the model's name comes from: client is the name the client reports, transcript is the model the session's last reply came from (what a proxy actually served), and auto uses the transcript's model only when it is not a Claude model, which is what a proxy redirect looks like.")
|
|
221
|
+
},
|
|
222
|
+
provider: {
|
|
223
|
+
name: overrideText.describe("A label to show in place of the launch's provider name, or on its own when the launch has no provider; empty shows the provider's own name.")
|
|
224
|
+
},
|
|
225
|
+
account: {
|
|
226
|
+
parts: distinctList(import_zod.z.enum(["user", "organisation", "plan"])).describe("What the account segment says about the login account, in drawing order: the account's email address, its organisation (shown for team and enterprise accounts) and its plan. A part left out is hidden, and an empty list hides the segment."),
|
|
227
|
+
userLength: import_zod.z.number().int().min(0).max(MAX_ACCOUNT_USER_CHARS).describe("The most characters of the account's email address to show, with an ellipsis after a cut one; 0 shows all of it.")
|
|
228
|
+
},
|
|
229
|
+
effort: {
|
|
230
|
+
format: import_zod.z.enum(["full", "symbol", "text"]).describe("How the reasoning effort is written: full is a symbol and the level (a filled circle that grows with the level, then the name), symbol is the symbol alone, and text is the level's name alone. A level with no symbol is always written as its name.")
|
|
231
|
+
},
|
|
232
|
+
advisor: {
|
|
233
|
+
override: overrideText.describe("A name to show for the advisor model in place of the one the session's transcript records; empty shows the transcript's, prettified.")
|
|
234
|
+
},
|
|
213
235
|
bands: {
|
|
214
236
|
warnAt: wholePercent.describe("The whole percentage of use at which a bar turns yellow; it must be below criticalAt."),
|
|
215
237
|
criticalAt: wholePercent.describe("The whole percentage of use at which a bar turns red.")
|
|
@@ -257,6 +279,11 @@ var init_statusline = __esm({
|
|
|
257
279
|
};
|
|
258
280
|
StatuslineSchema = import_zod.z.strictObject({
|
|
259
281
|
layout: import_zod.z.strictObject(SHAPES.layout).partial().optional(),
|
|
282
|
+
model: import_zod.z.strictObject(SHAPES.model).partial().optional(),
|
|
283
|
+
provider: import_zod.z.strictObject(SHAPES.provider).partial().optional(),
|
|
284
|
+
account: import_zod.z.strictObject(SHAPES.account).partial().optional(),
|
|
285
|
+
effort: import_zod.z.strictObject(SHAPES.effort).partial().optional(),
|
|
286
|
+
advisor: import_zod.z.strictObject(SHAPES.advisor).partial().optional(),
|
|
260
287
|
bands: import_zod.z.strictObject(SHAPES.bands).partial().optional(),
|
|
261
288
|
labels: import_zod.z.strictObject(SHAPES.labels).partial().optional(),
|
|
262
289
|
bar: import_zod.z.strictObject(SHAPES.bar).partial().optional(),
|
|
@@ -267,6 +294,11 @@ var init_statusline = __esm({
|
|
|
267
294
|
});
|
|
268
295
|
ResolvedStatuslineSchema = import_zod.z.strictObject({
|
|
269
296
|
layout: import_zod.z.strictObject(SHAPES.layout),
|
|
297
|
+
model: import_zod.z.strictObject(SHAPES.model),
|
|
298
|
+
provider: import_zod.z.strictObject(SHAPES.provider),
|
|
299
|
+
account: import_zod.z.strictObject(SHAPES.account),
|
|
300
|
+
effort: import_zod.z.strictObject(SHAPES.effort),
|
|
301
|
+
advisor: import_zod.z.strictObject(SHAPES.advisor),
|
|
270
302
|
bands: import_zod.z.strictObject(SHAPES.bands),
|
|
271
303
|
labels: import_zod.z.strictObject(SHAPES.labels),
|
|
272
304
|
bar: import_zod.z.strictObject(SHAPES.bar),
|
|
@@ -277,6 +309,11 @@ var init_statusline = __esm({
|
|
|
277
309
|
});
|
|
278
310
|
STATUSLINE_DEFAULTS = {
|
|
279
311
|
layout: { header: [...DEFAULT_HEADER_SEGMENTS], rows: [...DEFAULT_ROWS] },
|
|
312
|
+
model: { format: "full", override: "", source: "client" },
|
|
313
|
+
provider: { name: "" },
|
|
314
|
+
account: { parts: ["user", "organisation", "plan"], userLength: 0 },
|
|
315
|
+
effort: { format: "full" },
|
|
316
|
+
advisor: { override: "" },
|
|
280
317
|
bands: { warnAt: 70, criticalAt: 90 },
|
|
281
318
|
labels: { fiveHour: "5h", sevenDay: "Wk" },
|
|
282
319
|
bar: { width: 10, filled: "\u2588", empty: "\u2591" },
|
|
@@ -3791,9 +3828,9 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3791
3828
|
const watchdog = ports.startWatchdog?.();
|
|
3792
3829
|
let idleSince;
|
|
3793
3830
|
let ticks = 0;
|
|
3794
|
-
const supersedingOwner = () => {
|
|
3831
|
+
const supersedingOwner = async () => {
|
|
3795
3832
|
const owner = readFrontDoorState(fs14, paths.frontdoorStateFile)?.supervisorPid;
|
|
3796
|
-
return owner !== void 0 && owner !== ports.ownPid && ports.
|
|
3833
|
+
return owner !== void 0 && owner !== ports.ownPid && (await ports.runningAmong([owner])).has(owner) ? owner : void 0;
|
|
3797
3834
|
};
|
|
3798
3835
|
let supersededBy;
|
|
3799
3836
|
let served;
|
|
@@ -3818,7 +3855,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3818
3855
|
watchdog?.stop();
|
|
3819
3856
|
ports.stopBackgroundWork?.();
|
|
3820
3857
|
const drained = [direct.drain(), connect3.drain(), http3.drain()];
|
|
3821
|
-
if (supersedingOwner() === void 0) {
|
|
3858
|
+
if (await supersedingOwner() === void 0) {
|
|
3822
3859
|
writeFrontDoorState(fs14, paths.frontdoorStateFile, sticky());
|
|
3823
3860
|
}
|
|
3824
3861
|
markFrontDoorDraining(fs14, paths.frontdoorDrainingDir, ports.ownPid);
|
|
@@ -3839,7 +3876,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3839
3876
|
};
|
|
3840
3877
|
const shutdown = async () => {
|
|
3841
3878
|
await closeServing();
|
|
3842
|
-
if (supersedingOwner() === void 0) {
|
|
3879
|
+
if (await supersedingOwner() === void 0) {
|
|
3843
3880
|
writeFrontDoorState(fs14, paths.frontdoorStateFile, sticky());
|
|
3844
3881
|
}
|
|
3845
3882
|
return 0;
|
|
@@ -3855,13 +3892,14 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3855
3892
|
}
|
|
3856
3893
|
ticks += 1;
|
|
3857
3894
|
const listed = listFrontDoorSessions(fs14, paths.frontdoorSessionsDir);
|
|
3858
|
-
const
|
|
3895
|
+
const running = await ports.runningAmong(listed.map((session) => session.pid));
|
|
3896
|
+
const pruned = pruneDeadFrontDoorSessions(fs14, paths.frontdoorSessionsDir, (pid) => running.has(pid));
|
|
3859
3897
|
ports.observeLaunchRegistry(listed, pruned);
|
|
3860
3898
|
ports.checkQuotaExpiry();
|
|
3861
3899
|
const prunedPids = new Set(pruned);
|
|
3862
3900
|
const live = listed.filter((session) => !prunedPids.has(session.pid));
|
|
3863
3901
|
if (supersededBy === void 0) {
|
|
3864
|
-
supersededBy = supersedingOwner();
|
|
3902
|
+
supersededBy = await supersedingOwner();
|
|
3865
3903
|
if (supersededBy !== void 0) {
|
|
3866
3904
|
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: supervisor ${String(supersededBy)} now owns the front door; taking no new sessions and exiting once the sessions this door serves have ended`);
|
|
3867
3905
|
ports.doorHealth.superseded(supersededBy);
|
|
@@ -4361,7 +4399,7 @@ var init_package = __esm({
|
|
|
4361
4399
|
"package.json"() {
|
|
4362
4400
|
package_default = {
|
|
4363
4401
|
name: "claude-use",
|
|
4364
|
-
version: "11.
|
|
4402
|
+
version: "11.54.1",
|
|
4365
4403
|
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.",
|
|
4366
4404
|
license: "MIT",
|
|
4367
4405
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -5615,6 +5653,7 @@ function realIsProcessAlive(pid) {
|
|
|
5615
5653
|
}
|
|
5616
5654
|
}
|
|
5617
5655
|
function realIsProcessZombie(pid) {
|
|
5656
|
+
refuseToBlockInRole("a synchronous process-table read");
|
|
5618
5657
|
const result = (0, import_node_child_process2.spawnSync)("ps", ["-o", "stat=", "-p", String(pid)], { encoding: "utf8" });
|
|
5619
5658
|
return result.status === 0 && result.stdout.trim().startsWith("Z");
|
|
5620
5659
|
}
|
|
@@ -5622,14 +5661,17 @@ function realIsProcessRunning(pid) {
|
|
|
5622
5661
|
return realIsProcessAlive(pid) && !realIsProcessZombie(pid);
|
|
5623
5662
|
}
|
|
5624
5663
|
function realIsFrontDoorSupervisor(pid) {
|
|
5664
|
+
refuseToBlockInRole("a synchronous process-table read");
|
|
5625
5665
|
const result = (0, import_node_child_process2.spawnSync)("ps", ["-o", "pid=,command=", "-p", String(pid)], { encoding: "utf8" });
|
|
5626
5666
|
return result.status === 0 && parseFrontDoorSupervisorPids(result.stdout).includes(pid);
|
|
5627
5667
|
}
|
|
5628
5668
|
function realProcessCommandLine(pid) {
|
|
5669
|
+
refuseToBlockInRole("a synchronous process-table read");
|
|
5629
5670
|
const result = (0, import_node_child_process2.spawnSync)("ps", ["-o", "command=", "-p", String(pid)], { encoding: "utf8", timeout: PS_TIMEOUT_MS });
|
|
5630
5671
|
return result.status === 0 ? result.stdout.trim() : void 0;
|
|
5631
5672
|
}
|
|
5632
5673
|
function realFrontDoorLiveness(pids) {
|
|
5674
|
+
refuseToBlockInRole("a synchronous process-table read");
|
|
5633
5675
|
return frontDoorLivenessOf(pids, (asked) => {
|
|
5634
5676
|
const result = (0, import_node_child_process2.spawnSync)("ps", ["-o", "pid=,stat=,command=", "-p", asked.map(String).join(",")], { encoding: "utf8", timeout: PS_TIMEOUT_MS });
|
|
5635
5677
|
return { status: result.status, stdout: result.stdout, stderr: result.stderr, ...result.error === void 0 ? {} : { error: result.error } };
|
package/dist/index.mjs
CHANGED
|
@@ -119,7 +119,7 @@ var init_proxyBypass = __esm({
|
|
|
119
119
|
// src/config/statusline.ts
|
|
120
120
|
import { z } from "zod";
|
|
121
121
|
function distinctList(member) {
|
|
122
|
-
return z.array(member).refine((items) => new Set(items).size === items.length, "must not repeat
|
|
122
|
+
return z.array(member).refine((items) => new Set(items).size === items.length, "must not repeat an entry");
|
|
123
123
|
}
|
|
124
124
|
function isSingleVisibleGrapheme(text) {
|
|
125
125
|
return [...GRAPHEMES.segment(text)].length === 1 && !/[\p{C}\p{Z}]/u.test(text);
|
|
@@ -144,11 +144,11 @@ function resolveStatusline(settings) {
|
|
|
144
144
|
}
|
|
145
145
|
return resolved;
|
|
146
146
|
}
|
|
147
|
-
var STATUSLINE_HEADER_SEGMENTS, STATUSLINE_ROWS, STATUSLINE_COLOUR_NAMES, DEFAULT_HEADER_SEGMENTS, DEFAULT_ROWS, STATUSLINE_PATH_LEVELS, MAX_PERCENT, MAX_STATUSLINE_PALETTE_INDEX, MAX_STATUSLINE_LABEL_CHARS, MAX_BAR_CELLS, LABEL_RE2, colourValue, GRAPHEMES, barCharacter, labelText, wholePercent, SHAPES, StatuslineSchema, ResolvedStatuslineSchema, STATUSLINE_DEFAULTS, STATUSLINE_ENV;
|
|
147
|
+
var STATUSLINE_HEADER_SEGMENTS, STATUSLINE_ROWS, STATUSLINE_COLOUR_NAMES, DEFAULT_HEADER_SEGMENTS, DEFAULT_ROWS, STATUSLINE_PATH_LEVELS, MAX_PERCENT, MAX_STATUSLINE_PALETTE_INDEX, MAX_STATUSLINE_LABEL_CHARS, MAX_BAR_CELLS, MAX_ACCOUNT_USER_CHARS, MAX_DISPLAY_TEXT_CHARS, LABEL_RE2, OPTIONAL_LABEL_RE, colourValue, GRAPHEMES, barCharacter, labelText, overrideText, wholePercent, SHAPES, StatuslineSchema, ResolvedStatuslineSchema, STATUSLINE_DEFAULTS, STATUSLINE_ENV;
|
|
148
148
|
var init_statusline = __esm({
|
|
149
149
|
"src/config/statusline.ts"() {
|
|
150
150
|
"use strict";
|
|
151
|
-
STATUSLINE_HEADER_SEGMENTS = ["model", "provider", "route", "account", "identity", "headroom", "project", "vcs"];
|
|
151
|
+
STATUSLINE_HEADER_SEGMENTS = ["model", "provider", "route", "account", "identity", "headroom", "project", "vcs", "effort", "advisor", "version", "outputStyle"];
|
|
152
152
|
STATUSLINE_ROWS = ["context", "quota", "addedDirs", "gitFiles"];
|
|
153
153
|
STATUSLINE_COLOUR_NAMES = [
|
|
154
154
|
"default",
|
|
@@ -177,17 +177,39 @@ var init_statusline = __esm({
|
|
|
177
177
|
MAX_STATUSLINE_PALETTE_INDEX = 255;
|
|
178
178
|
MAX_STATUSLINE_LABEL_CHARS = 12;
|
|
179
179
|
MAX_BAR_CELLS = 40;
|
|
180
|
+
MAX_ACCOUNT_USER_CHARS = 254;
|
|
181
|
+
MAX_DISPLAY_TEXT_CHARS = 80;
|
|
180
182
|
LABEL_RE2 = /^[^\p{C}\p{Z}]+(?: [^\p{C}\p{Z}]+)*$/u;
|
|
183
|
+
OPTIONAL_LABEL_RE = /^(?:[^\p{C}\p{Z}]+(?: [^\p{C}\p{Z}]+)*)?$/u;
|
|
181
184
|
colourValue = z.union([z.enum(STATUSLINE_COLOUR_NAMES), z.number().int().min(0).max(MAX_STATUSLINE_PALETTE_INDEX), z.string().regex(/^#[0-9a-fA-F]{6}$/, "must be a colour name, a palette index from 0 to 255 or #rrggbb")]);
|
|
182
185
|
GRAPHEMES = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
183
186
|
barCharacter = z.string().refine(isSingleVisibleGrapheme, "must be a single visible character");
|
|
184
187
|
labelText = z.string().max(MAX_STATUSLINE_LABEL_CHARS).regex(LABEL_RE2, "must be visible text without control characters");
|
|
188
|
+
overrideText = z.string().max(MAX_DISPLAY_TEXT_CHARS).regex(OPTIONAL_LABEL_RE, "must be visible text without control characters");
|
|
185
189
|
wholePercent = z.number().int().min(1).max(MAX_PERCENT);
|
|
186
190
|
SHAPES = {
|
|
187
191
|
layout: {
|
|
188
192
|
header: distinctList(z.enum(STATUSLINE_HEADER_SEGMENTS)).describe("The header segments to draw, in drawing order; a segment left out is hidden, and an empty list hides the header."),
|
|
189
193
|
rows: distinctList(z.enum(STATUSLINE_ROWS)).describe("The rows to draw below the header, in drawing order; a row left out is hidden, and an empty list hides every row.")
|
|
190
194
|
},
|
|
195
|
+
model: {
|
|
196
|
+
format: z.enum(["full", "compact", "short"]).describe("How the model's name is written: full is the name as the client gives it, compact drops a context-window suffix such as (1M context), and short also drops a leading Claude."),
|
|
197
|
+
override: overrideText.describe("A name to show in place of the client's own model name, whatever model is running; empty shows the model's own name. A dynamic mode's served model still follows it."),
|
|
198
|
+
source: z.enum(["client", "transcript", "auto"]).describe("Where the model's name comes from: client is the name the client reports, transcript is the model the session's last reply came from (what a proxy actually served), and auto uses the transcript's model only when it is not a Claude model, which is what a proxy redirect looks like.")
|
|
199
|
+
},
|
|
200
|
+
provider: {
|
|
201
|
+
name: overrideText.describe("A label to show in place of the launch's provider name, or on its own when the launch has no provider; empty shows the provider's own name.")
|
|
202
|
+
},
|
|
203
|
+
account: {
|
|
204
|
+
parts: distinctList(z.enum(["user", "organisation", "plan"])).describe("What the account segment says about the login account, in drawing order: the account's email address, its organisation (shown for team and enterprise accounts) and its plan. A part left out is hidden, and an empty list hides the segment."),
|
|
205
|
+
userLength: z.number().int().min(0).max(MAX_ACCOUNT_USER_CHARS).describe("The most characters of the account's email address to show, with an ellipsis after a cut one; 0 shows all of it.")
|
|
206
|
+
},
|
|
207
|
+
effort: {
|
|
208
|
+
format: z.enum(["full", "symbol", "text"]).describe("How the reasoning effort is written: full is a symbol and the level (a filled circle that grows with the level, then the name), symbol is the symbol alone, and text is the level's name alone. A level with no symbol is always written as its name.")
|
|
209
|
+
},
|
|
210
|
+
advisor: {
|
|
211
|
+
override: overrideText.describe("A name to show for the advisor model in place of the one the session's transcript records; empty shows the transcript's, prettified.")
|
|
212
|
+
},
|
|
191
213
|
bands: {
|
|
192
214
|
warnAt: wholePercent.describe("The whole percentage of use at which a bar turns yellow; it must be below criticalAt."),
|
|
193
215
|
criticalAt: wholePercent.describe("The whole percentage of use at which a bar turns red.")
|
|
@@ -235,6 +257,11 @@ var init_statusline = __esm({
|
|
|
235
257
|
};
|
|
236
258
|
StatuslineSchema = z.strictObject({
|
|
237
259
|
layout: z.strictObject(SHAPES.layout).partial().optional(),
|
|
260
|
+
model: z.strictObject(SHAPES.model).partial().optional(),
|
|
261
|
+
provider: z.strictObject(SHAPES.provider).partial().optional(),
|
|
262
|
+
account: z.strictObject(SHAPES.account).partial().optional(),
|
|
263
|
+
effort: z.strictObject(SHAPES.effort).partial().optional(),
|
|
264
|
+
advisor: z.strictObject(SHAPES.advisor).partial().optional(),
|
|
238
265
|
bands: z.strictObject(SHAPES.bands).partial().optional(),
|
|
239
266
|
labels: z.strictObject(SHAPES.labels).partial().optional(),
|
|
240
267
|
bar: z.strictObject(SHAPES.bar).partial().optional(),
|
|
@@ -245,6 +272,11 @@ var init_statusline = __esm({
|
|
|
245
272
|
});
|
|
246
273
|
ResolvedStatuslineSchema = z.strictObject({
|
|
247
274
|
layout: z.strictObject(SHAPES.layout),
|
|
275
|
+
model: z.strictObject(SHAPES.model),
|
|
276
|
+
provider: z.strictObject(SHAPES.provider),
|
|
277
|
+
account: z.strictObject(SHAPES.account),
|
|
278
|
+
effort: z.strictObject(SHAPES.effort),
|
|
279
|
+
advisor: z.strictObject(SHAPES.advisor),
|
|
248
280
|
bands: z.strictObject(SHAPES.bands),
|
|
249
281
|
labels: z.strictObject(SHAPES.labels),
|
|
250
282
|
bar: z.strictObject(SHAPES.bar),
|
|
@@ -255,6 +287,11 @@ var init_statusline = __esm({
|
|
|
255
287
|
});
|
|
256
288
|
STATUSLINE_DEFAULTS = {
|
|
257
289
|
layout: { header: [...DEFAULT_HEADER_SEGMENTS], rows: [...DEFAULT_ROWS] },
|
|
290
|
+
model: { format: "full", override: "", source: "client" },
|
|
291
|
+
provider: { name: "" },
|
|
292
|
+
account: { parts: ["user", "organisation", "plan"], userLength: 0 },
|
|
293
|
+
effort: { format: "full" },
|
|
294
|
+
advisor: { override: "" },
|
|
258
295
|
bands: { warnAt: 70, criticalAt: 90 },
|
|
259
296
|
labels: { fiveHour: "5h", sevenDay: "Wk" },
|
|
260
297
|
bar: { width: 10, filled: "\u2588", empty: "\u2591" },
|
|
@@ -3768,9 +3805,9 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3768
3805
|
const watchdog = ports.startWatchdog?.();
|
|
3769
3806
|
let idleSince;
|
|
3770
3807
|
let ticks = 0;
|
|
3771
|
-
const supersedingOwner = () => {
|
|
3808
|
+
const supersedingOwner = async () => {
|
|
3772
3809
|
const owner = readFrontDoorState(fs14, paths.frontdoorStateFile)?.supervisorPid;
|
|
3773
|
-
return owner !== void 0 && owner !== ports.ownPid && ports.
|
|
3810
|
+
return owner !== void 0 && owner !== ports.ownPid && (await ports.runningAmong([owner])).has(owner) ? owner : void 0;
|
|
3774
3811
|
};
|
|
3775
3812
|
let supersededBy;
|
|
3776
3813
|
let served;
|
|
@@ -3795,7 +3832,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3795
3832
|
watchdog?.stop();
|
|
3796
3833
|
ports.stopBackgroundWork?.();
|
|
3797
3834
|
const drained = [direct.drain(), connect3.drain(), http3.drain()];
|
|
3798
|
-
if (supersedingOwner() === void 0) {
|
|
3835
|
+
if (await supersedingOwner() === void 0) {
|
|
3799
3836
|
writeFrontDoorState(fs14, paths.frontdoorStateFile, sticky());
|
|
3800
3837
|
}
|
|
3801
3838
|
markFrontDoorDraining(fs14, paths.frontdoorDrainingDir, ports.ownPid);
|
|
@@ -3816,7 +3853,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3816
3853
|
};
|
|
3817
3854
|
const shutdown = async () => {
|
|
3818
3855
|
await closeServing();
|
|
3819
|
-
if (supersedingOwner() === void 0) {
|
|
3856
|
+
if (await supersedingOwner() === void 0) {
|
|
3820
3857
|
writeFrontDoorState(fs14, paths.frontdoorStateFile, sticky());
|
|
3821
3858
|
}
|
|
3822
3859
|
return 0;
|
|
@@ -3832,13 +3869,14 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3832
3869
|
}
|
|
3833
3870
|
ticks += 1;
|
|
3834
3871
|
const listed = listFrontDoorSessions(fs14, paths.frontdoorSessionsDir);
|
|
3835
|
-
const
|
|
3872
|
+
const running = await ports.runningAmong(listed.map((session) => session.pid));
|
|
3873
|
+
const pruned = pruneDeadFrontDoorSessions(fs14, paths.frontdoorSessionsDir, (pid) => running.has(pid));
|
|
3836
3874
|
ports.observeLaunchRegistry(listed, pruned);
|
|
3837
3875
|
ports.checkQuotaExpiry();
|
|
3838
3876
|
const prunedPids = new Set(pruned);
|
|
3839
3877
|
const live = listed.filter((session) => !prunedPids.has(session.pid));
|
|
3840
3878
|
if (supersededBy === void 0) {
|
|
3841
|
-
supersededBy = supersedingOwner();
|
|
3879
|
+
supersededBy = await supersedingOwner();
|
|
3842
3880
|
if (supersededBy !== void 0) {
|
|
3843
3881
|
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: supervisor ${String(supersededBy)} now owns the front door; taking no new sessions and exiting once the sessions this door serves have ended`);
|
|
3844
3882
|
ports.doorHealth.superseded(supersededBy);
|
|
@@ -4337,7 +4375,7 @@ var init_package = __esm({
|
|
|
4337
4375
|
"package.json"() {
|
|
4338
4376
|
package_default = {
|
|
4339
4377
|
name: "claude-use",
|
|
4340
|
-
version: "11.
|
|
4378
|
+
version: "11.54.1",
|
|
4341
4379
|
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.",
|
|
4342
4380
|
license: "MIT",
|
|
4343
4381
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -5571,7 +5609,7 @@ var init_logStyle = __esm({
|
|
|
5571
5609
|
});
|
|
5572
5610
|
|
|
5573
5611
|
// src/realPorts.ts
|
|
5574
|
-
import { spawn as spawn2, spawnSync } from "node:child_process";
|
|
5612
|
+
import { execFile, spawn as spawn2, spawnSync } from "node:child_process";
|
|
5575
5613
|
import { createHash as createHash5 } from "node:crypto";
|
|
5576
5614
|
import fs3 from "node:fs";
|
|
5577
5615
|
import os3 from "node:os";
|
|
@@ -5596,6 +5634,7 @@ function realIsProcessAlive(pid) {
|
|
|
5596
5634
|
}
|
|
5597
5635
|
}
|
|
5598
5636
|
function realIsProcessZombie(pid) {
|
|
5637
|
+
refuseToBlockInRole("a synchronous process-table read");
|
|
5599
5638
|
const result = spawnSync("ps", ["-o", "stat=", "-p", String(pid)], { encoding: "utf8" });
|
|
5600
5639
|
return result.status === 0 && result.stdout.trim().startsWith("Z");
|
|
5601
5640
|
}
|
|
@@ -5603,14 +5642,17 @@ function realIsProcessRunning(pid) {
|
|
|
5603
5642
|
return realIsProcessAlive(pid) && !realIsProcessZombie(pid);
|
|
5604
5643
|
}
|
|
5605
5644
|
function realIsFrontDoorSupervisor(pid) {
|
|
5645
|
+
refuseToBlockInRole("a synchronous process-table read");
|
|
5606
5646
|
const result = spawnSync("ps", ["-o", "pid=,command=", "-p", String(pid)], { encoding: "utf8" });
|
|
5607
5647
|
return result.status === 0 && parseFrontDoorSupervisorPids(result.stdout).includes(pid);
|
|
5608
5648
|
}
|
|
5609
5649
|
function realProcessCommandLine(pid) {
|
|
5650
|
+
refuseToBlockInRole("a synchronous process-table read");
|
|
5610
5651
|
const result = spawnSync("ps", ["-o", "command=", "-p", String(pid)], { encoding: "utf8", timeout: PS_TIMEOUT_MS });
|
|
5611
5652
|
return result.status === 0 ? result.stdout.trim() : void 0;
|
|
5612
5653
|
}
|
|
5613
5654
|
function realFrontDoorLiveness(pids) {
|
|
5655
|
+
refuseToBlockInRole("a synchronous process-table read");
|
|
5614
5656
|
return frontDoorLivenessOf(pids, (asked) => {
|
|
5615
5657
|
const result = spawnSync("ps", ["-o", "pid=,stat=,command=", "-p", asked.map(String).join(",")], { encoding: "utf8", timeout: PS_TIMEOUT_MS });
|
|
5616
5658
|
return { status: result.status, stdout: result.stdout, stderr: result.stderr, ...result.error === void 0 ? {} : { error: result.error } };
|