agent-shim 8.9.0 → 8.10.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/README.md +3 -1
- package/dist/cli.cjs +159 -45
- package/dist/index.cjs +348 -239
- package/dist/index.mjs +350 -241
- package/dist/types/index.d.ts +35 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -95,7 +95,8 @@ agent-shim identity resolve-conflicts <name> # interactively resolve a retained
|
|
|
95
95
|
agent-shim profile add [name] [--extends <profile>]... [--description <text>] # interactive with no options on a terminal [--json]
|
|
96
96
|
agent-shim profile set <name> [--category <category>=<bool>]... [--entry <category>/<path>=<bool>]... [--json]
|
|
97
97
|
agent-shim profile set <name> [--extends <profile>]... [--no-extends] [--description <text> | --no-description] [--json]
|
|
98
|
-
agent-shim profile set <name> [--[no-]launch-skip-permissions] [--[no-]launch-remote-control] [--[no-]launch-headroom] [--[no-]launch-track-usage]
|
|
98
|
+
agent-shim profile set <name> [--[no-]launch-skip-permissions] [--[no-]launch-remote-control] [--[no-]launch-headroom] [--[no-]launch-track-usage]
|
|
99
|
+
agent-shim profile set <name> [--launch-claude-version <version> | --no-launch-claude-version] [--json] [--json]
|
|
99
100
|
agent-shim profile set <name> [--launch-provider <provider> | --no-launch-provider] [--json]
|
|
100
101
|
agent-shim profile list [--json]
|
|
101
102
|
agent-shim profile show <name> [--json]
|
|
@@ -150,6 +151,7 @@ agent-shim run [@<identity>] [launch flags] [claude arguments]
|
|
|
150
151
|
# --identity <name> --config-profile <name> --provider <name> | --no-provider
|
|
151
152
|
# --category <category>=<bool> --share <category>/<path> --hide <category>/<path> (each repeatable)
|
|
152
153
|
# --[no-]skip-permissions --[no-]remote-control --[no-]headroom --[no-]track-usage --[no-]wait
|
|
154
|
+
# --claude-version <version> run exactly this installed Claude Code version
|
|
153
155
|
# --native run the real claude with nothing from agent-shim applied; cannot be combined with the flags above
|
|
154
156
|
claude @<identity> ... # the same, once `agent-shim shim enable` has run
|
|
155
157
|
```
|
package/dist/cli.cjs
CHANGED
|
@@ -55043,9 +55043,9 @@ function applyPatch(filePath, schema, patch, options = {}) {
|
|
|
55043
55043
|
if (!result.success) {
|
|
55044
55044
|
throw new ConfigValidationError(filePath, result.error.issues);
|
|
55045
55045
|
}
|
|
55046
|
-
const
|
|
55047
|
-
writeJsonAtomic(filePath,
|
|
55048
|
-
return
|
|
55046
|
+
const validated2 = result.data;
|
|
55047
|
+
writeJsonAtomic(filePath, validated2, storeFs);
|
|
55048
|
+
return validated2;
|
|
55049
55049
|
}
|
|
55050
55050
|
|
|
55051
55051
|
// src/realPorts.ts
|
|
@@ -55085,6 +55085,23 @@ function compareVersions(a2, b) {
|
|
|
55085
55085
|
}
|
|
55086
55086
|
return 0;
|
|
55087
55087
|
}
|
|
55088
|
+
var ClaudeVersionNotInstalledError = class extends CliError {
|
|
55089
|
+
constructor(version2, versionsDir, installed) {
|
|
55090
|
+
super(
|
|
55091
|
+
`Claude Code ${version2} is pinned for this launch but is not installed under "${versionsDir}"` + (installed.length === 0 ? " (no versions are installed there)." : `. Installed: ${installed.join(", ")}.`) + " Install it, or change or remove the pin (--claude-version, AGENT_SHIM_CLAUDE_VERSION, or launch.claudeVersion)."
|
|
55092
|
+
);
|
|
55093
|
+
this.version = version2;
|
|
55094
|
+
this.versionsDir = versionsDir;
|
|
55095
|
+
this.installed = installed;
|
|
55096
|
+
this.name = "ClaudeVersionNotInstalledError";
|
|
55097
|
+
}
|
|
55098
|
+
version;
|
|
55099
|
+
versionsDir;
|
|
55100
|
+
installed;
|
|
55101
|
+
};
|
|
55102
|
+
function installedVersions(entries) {
|
|
55103
|
+
return entries.filter((entry) => entry.isFile && entry.isExecutable && entry.sizeBytes > 0 && isNumericDottedVersion(entry.name)).map((entry) => entry.name).sort(compareVersions);
|
|
55104
|
+
}
|
|
55088
55105
|
function pickHighestVersion(entries) {
|
|
55089
55106
|
const candidates = entries.filter(
|
|
55090
55107
|
(entry) => entry.isFile && entry.isExecutable && entry.sizeBytes > 0 && isNumericDottedVersion(entry.name)
|
|
@@ -55100,6 +55117,13 @@ function discoverClaudeBinary(options) {
|
|
|
55100
55117
|
const versionsDir = options.versionsDir ?? defaultVersionsDir();
|
|
55101
55118
|
const entries = options.listVersionsDir(versionsDir);
|
|
55102
55119
|
const highestVersion = pickHighestVersion(entries);
|
|
55120
|
+
if (options.version !== void 0) {
|
|
55121
|
+
const installed = installedVersions(entries);
|
|
55122
|
+
if (!installed.includes(options.version)) {
|
|
55123
|
+
throw new ClaudeVersionNotInstalledError(options.version, versionsDir, installed);
|
|
55124
|
+
}
|
|
55125
|
+
return { path: import_node_path3.default.join(versionsDir, options.version), source: "versions-dir", version: options.version };
|
|
55126
|
+
}
|
|
55103
55127
|
if (highestVersion !== void 0) {
|
|
55104
55128
|
return {
|
|
55105
55129
|
path: import_node_path3.default.join(versionsDir, highestVersion),
|
|
@@ -55167,7 +55191,9 @@ var LaunchSchema = external_exports.strictObject({
|
|
|
55167
55191
|
remoteControl: external_exports.boolean().optional(),
|
|
55168
55192
|
provider: external_exports.string().min(1).optional(),
|
|
55169
55193
|
headroom: external_exports.boolean().optional(),
|
|
55170
|
-
trackUsage: external_exports.boolean().optional()
|
|
55194
|
+
trackUsage: external_exports.boolean().optional(),
|
|
55195
|
+
/** The exact Claude Code version to run, as it is named in Claude Code's versions directory (`2.1.220`). A pin that is not installed fails the launch; it never falls back to the highest version. */
|
|
55196
|
+
claudeVersion: external_exports.string().regex(NUMERIC_DOTTED_VERSION_RE, "must be an exact dotted-numeric Claude Code version such as 2.1.220").optional()
|
|
55171
55197
|
});
|
|
55172
55198
|
var CREDENTIAL_TARGETS = ["bearer", "apiKey", "oauthToken"];
|
|
55173
55199
|
var PROVIDER_CREDENTIAL_TARGETS = ["bearer", "apiKey"];
|
|
@@ -56501,13 +56527,17 @@ function realContentSourcePath() {
|
|
|
56501
56527
|
return resolveContentSourcePath({ isSea: (0, import_node_sea.isSea)(), execPath: process.execPath, argv1: process.argv[1] });
|
|
56502
56528
|
}
|
|
56503
56529
|
function realResolveClaudeBinary(isOwnBinary) {
|
|
56504
|
-
return () => discoverClaudeBinary({
|
|
56530
|
+
return (request7) => discoverClaudeBinary({
|
|
56505
56531
|
listVersionsDir,
|
|
56506
56532
|
pathDirs: (process.env.PATH ?? "").split(import_node_path8.default.delimiter).filter((dir) => dir !== ""),
|
|
56507
56533
|
findExecutableInDir,
|
|
56508
|
-
isOwnBinary
|
|
56534
|
+
isOwnBinary,
|
|
56535
|
+
...request7?.version === void 0 ? {} : { version: request7.version }
|
|
56509
56536
|
});
|
|
56510
56537
|
}
|
|
56538
|
+
function realInstalledClaudeVersions() {
|
|
56539
|
+
return installedVersions(listVersionsDir(defaultVersionsDir()));
|
|
56540
|
+
}
|
|
56511
56541
|
|
|
56512
56542
|
// src/claudeShim.ts
|
|
56513
56543
|
var EXECUTABLE_FILE_MODE = 493;
|
|
@@ -59284,6 +59314,9 @@ function flattenLayers(layers, options) {
|
|
|
59284
59314
|
if (layer.launch.trackUsage !== void 0) {
|
|
59285
59315
|
launch.trackUsage = layer.launch.trackUsage;
|
|
59286
59316
|
}
|
|
59317
|
+
if (layer.launch.claudeVersion !== void 0) {
|
|
59318
|
+
launch.claudeVersion = layer.launch.claudeVersion;
|
|
59319
|
+
}
|
|
59287
59320
|
}
|
|
59288
59321
|
if (layer.entries === void 0) {
|
|
59289
59322
|
continue;
|
|
@@ -61264,6 +61297,9 @@ function applyProfileSet(paths, name, options) {
|
|
|
61264
61297
|
if (options.launchProvider !== void 0) {
|
|
61265
61298
|
launchPatch.provider = options.launchProvider === false ? void 0 : options.launchProvider;
|
|
61266
61299
|
}
|
|
61300
|
+
if (options.launchClaudeVersion !== void 0) {
|
|
61301
|
+
launchPatch.claudeVersion = options.launchClaudeVersion === false ? void 0 : options.launchClaudeVersion;
|
|
61302
|
+
}
|
|
61267
61303
|
if (Object.keys(launchPatch).length > 0) {
|
|
61268
61304
|
setProfileLaunchFlags(paths, name, launchPatch);
|
|
61269
61305
|
touched = true;
|
|
@@ -61305,7 +61341,7 @@ function registerProfileCommand(program2, deps) {
|
|
|
61305
61341
|
withExamples(
|
|
61306
61342
|
profile.command("set <name>").description(
|
|
61307
61343
|
"Update a configuration profile's categories, entries, extends list, description or launch settings. With no options on a terminal, walks through its categories."
|
|
61308
|
-
).option("--category <category=bool>", "Share (true) or hide (false) a whole category (repeatable).", collectBoolPair).option("--entry <path=bool>", "Share (true) or hide (false) one <category>/<path> entry (repeatable).", collectBoolPair).option("--extends <profile>", "Replace the extends list with these profiles (repeatable, in order).", collectRepeated).option("--no-extends", "Clear the extends list.").option("--description <text>", "Replace the description.").option("--no-description", "Clear the description.").option("--launch-skip-permissions", "Launches under this profile skip permission prompts.").option("--no-launch-skip-permissions", "Launches under this profile keep permission prompts.").option("--launch-remote-control", "Launches under this profile enable Remote Control.").option("--no-launch-remote-control", "Launches under this profile leave Remote Control off.").option("--launch-headroom", "Launches under this profile route through headroom.").option("--no-launch-headroom", "Launches under this profile route direct.").option("--launch-track-usage", "Launches under this profile route through the front door so their requests and quota are recorded, with no headroom needed.").option("--no-launch-track-usage", "Launches under this profile are not recorded unless a provider or headroom routes them anyway.").option("--launch-provider <provider>", "Launches under this profile route through this provider.").option("--no-launch-provider", "Clear this profile's provider selection.").option("--json", "Print the result as JSON.").action(async (name, allOptions) => {
|
|
61344
|
+
).option("--category <category=bool>", "Share (true) or hide (false) a whole category (repeatable).", collectBoolPair).option("--entry <path=bool>", "Share (true) or hide (false) one <category>/<path> entry (repeatable).", collectBoolPair).option("--extends <profile>", "Replace the extends list with these profiles (repeatable, in order).", collectRepeated).option("--no-extends", "Clear the extends list.").option("--description <text>", "Replace the description.").option("--no-description", "Clear the description.").option("--launch-skip-permissions", "Launches under this profile skip permission prompts.").option("--no-launch-skip-permissions", "Launches under this profile keep permission prompts.").option("--launch-remote-control", "Launches under this profile enable Remote Control.").option("--no-launch-remote-control", "Launches under this profile leave Remote Control off.").option("--launch-headroom", "Launches under this profile route through headroom.").option("--no-launch-headroom", "Launches under this profile route direct.").option("--launch-track-usage", "Launches under this profile route through the front door so their requests and quota are recorded, with no headroom needed.").option("--no-launch-track-usage", "Launches under this profile are not recorded unless a provider or headroom routes them anyway.").option("--launch-provider <provider>", "Launches under this profile route through this provider.").option("--no-launch-provider", "Clear this profile's provider selection.").option("--launch-claude-version <version>", "Launches under this profile run exactly this installed Claude Code version (such as 2.1.220); a version that is not installed fails the launch.").option("--no-launch-claude-version", "Clear this profile's Claude Code version pin.").option("--json", "Print the result as JSON.").action(async (name, allOptions) => {
|
|
61309
61345
|
const { json: json2, ...options } = allOptions;
|
|
61310
61346
|
requireProfileExists(paths, name);
|
|
61311
61347
|
if (Object.entries(allOptions).every(([key, value2]) => key === "json" || value2 === void 0)) {
|
|
@@ -61673,7 +61709,7 @@ function registerIdentityCommand(program2, deps) {
|
|
|
61673
61709
|
// package.json
|
|
61674
61710
|
var package_default = {
|
|
61675
61711
|
name: "agent-shim",
|
|
61676
|
-
version: "8.
|
|
61712
|
+
version: "8.10.0",
|
|
61677
61713
|
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.",
|
|
61678
61714
|
license: "MIT",
|
|
61679
61715
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -63553,6 +63589,34 @@ function parseEnvBool(variable, value2) {
|
|
|
63553
63589
|
return parsed;
|
|
63554
63590
|
}
|
|
63555
63591
|
|
|
63592
|
+
// src/launcher/claudeVersion.ts
|
|
63593
|
+
var InvalidClaudeVersionError = class extends UsageError {
|
|
63594
|
+
constructor(value2, origin) {
|
|
63595
|
+
super(`${origin} names Claude Code version "${value2}", which is not an exact dotted-numeric version such as 2.1.220.`);
|
|
63596
|
+
this.value = value2;
|
|
63597
|
+
this.origin = origin;
|
|
63598
|
+
this.name = "InvalidClaudeVersionError";
|
|
63599
|
+
}
|
|
63600
|
+
value;
|
|
63601
|
+
origin;
|
|
63602
|
+
};
|
|
63603
|
+
function validated(value2, origin) {
|
|
63604
|
+
if (!NUMERIC_DOTTED_VERSION_RE.test(value2)) {
|
|
63605
|
+
throw new InvalidClaudeVersionError(value2, origin);
|
|
63606
|
+
}
|
|
63607
|
+
return value2;
|
|
63608
|
+
}
|
|
63609
|
+
function resolveClaudeVersion(params) {
|
|
63610
|
+
if (params.flag !== void 0) {
|
|
63611
|
+
return { version: validated(params.flag, "--claude-version"), source: "flag" };
|
|
63612
|
+
}
|
|
63613
|
+
const fromEnv = params.env.AGENT_SHIM_CLAUDE_VERSION;
|
|
63614
|
+
if (fromEnv !== void 0 && fromEnv !== "") {
|
|
63615
|
+
return { version: validated(fromEnv, "AGENT_SHIM_CLAUDE_VERSION"), source: "environment" };
|
|
63616
|
+
}
|
|
63617
|
+
return params.cascade === void 0 ? void 0 : { version: params.cascade, source: "cascade" };
|
|
63618
|
+
}
|
|
63619
|
+
|
|
63556
63620
|
// src/launcher/guard.ts
|
|
63557
63621
|
var AMBIENT_CREDENTIAL_VARS = [
|
|
63558
63622
|
"ANTHROPIC_API_KEY",
|
|
@@ -63750,6 +63814,19 @@ function buildCredentialReport(provider, identity, identityName, cacheEnv) {
|
|
|
63750
63814
|
...identityCached === void 0 ? {} : { identityCached }
|
|
63751
63815
|
};
|
|
63752
63816
|
}
|
|
63817
|
+
function buildClaudeVersionReport(params, cascadePin) {
|
|
63818
|
+
const installed = params.installedClaudeVersions;
|
|
63819
|
+
if (installed === void 0) {
|
|
63820
|
+
return void 0;
|
|
63821
|
+
}
|
|
63822
|
+
const pin = resolveClaudeVersion({ env: params.env, ...cascadePin === void 0 ? {} : { cascade: cascadePin } });
|
|
63823
|
+
const highestInstalled = installed.at(-1);
|
|
63824
|
+
return {
|
|
63825
|
+
...pin === void 0 ? {} : { pinned: { ...pin, installed: installed.includes(pin.version) } },
|
|
63826
|
+
...highestInstalled === void 0 ? {} : { highestInstalled },
|
|
63827
|
+
installed
|
|
63828
|
+
};
|
|
63829
|
+
}
|
|
63753
63830
|
function runCheck(params) {
|
|
63754
63831
|
const facts = buildEntryFacts({
|
|
63755
63832
|
fs: params.farmFs,
|
|
@@ -63774,6 +63851,7 @@ function runCheck(params) {
|
|
|
63774
63851
|
const settingsShared = resolved.flattened.categories.get("settings") ?? SHIPPED_CATEGORY_DEFAULTS.settings;
|
|
63775
63852
|
const settingsExposure = inspectSettingsExposure({ settingsShared, files: params.settingsFiles });
|
|
63776
63853
|
const keychain = params.platform === "darwin" && params.run !== void 0 && params.farmRoot !== void 0 ? lookupKeychainService(params.run, params.farmRoot) : void 0;
|
|
63854
|
+
const claudeVersion = buildClaudeVersionReport(params, resolved.flattened.launch.claudeVersion);
|
|
63777
63855
|
return {
|
|
63778
63856
|
...params.identityName === void 0 ? {} : { identityName: params.identityName },
|
|
63779
63857
|
identitySource: params.identitySource,
|
|
@@ -63786,7 +63864,8 @@ function runCheck(params) {
|
|
|
63786
63864
|
ambientCredential,
|
|
63787
63865
|
...keychain === void 0 ? {} : { keychain },
|
|
63788
63866
|
settingsExposure,
|
|
63789
|
-
credential: buildCredentialReport(params.provider, params.identity, params.identityName, params.credentialCache)
|
|
63867
|
+
credential: buildCredentialReport(params.provider, params.identity, params.identityName, params.credentialCache),
|
|
63868
|
+
...claudeVersion === void 0 ? {} : { claudeVersion }
|
|
63790
63869
|
};
|
|
63791
63870
|
}
|
|
63792
63871
|
function formatCheckReport(report) {
|
|
@@ -63835,6 +63914,17 @@ function formatCheckReport(report) {
|
|
|
63835
63914
|
if (credential.applies === "stored-login") {
|
|
63836
63915
|
lines.push(" The identity's stored login (no credential block applies).");
|
|
63837
63916
|
}
|
|
63917
|
+
if (report.claudeVersion !== void 0) {
|
|
63918
|
+
lines.push("", "Claude Code version:");
|
|
63919
|
+
const { pinned, highestInstalled, installed } = report.claudeVersion;
|
|
63920
|
+
if (pinned !== void 0) {
|
|
63921
|
+
lines.push(
|
|
63922
|
+
pinned.installed ? ` ${pinned.version}, pinned by the ${pinned.source} (installed)` : ` ${pinned.version}, pinned by the ${pinned.source}, but NOT installed; a launch here fails. Installed: ${installed.length === 0 ? "none" : installed.join(", ")}`
|
|
63923
|
+
);
|
|
63924
|
+
} else {
|
|
63925
|
+
lines.push(highestInstalled === void 0 ? " none installed in the versions directory (a launch falls back to a claude on PATH)" : ` ${highestInstalled} (the highest installed; nothing pins a version)`);
|
|
63926
|
+
}
|
|
63927
|
+
}
|
|
63838
63928
|
lines.push("", "Ambient-credential exposure:");
|
|
63839
63929
|
lines.push(
|
|
63840
63930
|
report.ambientCredential.ok ? ` OK \u2014 none of ${AMBIENT_CREDENTIAL_VARS.join(", ")} is set to a non-empty value.` : report.ambientCredential.message.split("\n").map((line) => ` ${line}`).join("\n")
|
|
@@ -63873,11 +63963,12 @@ function checkReportToJson(report) {
|
|
|
63873
63963
|
ambientCredential: report.ambientCredential.ok ? { ok: true } : { ok: false, variable: report.ambientCredential.variable, message: report.ambientCredential.message },
|
|
63874
63964
|
...report.keychain === void 0 ? {} : { keychain: report.keychain },
|
|
63875
63965
|
settingsExposure: report.settingsExposure,
|
|
63876
|
-
credential: report.credential
|
|
63966
|
+
credential: report.credential,
|
|
63967
|
+
...report.claudeVersion === void 0 ? {} : { claudeVersion: report.claudeVersion }
|
|
63877
63968
|
};
|
|
63878
63969
|
}
|
|
63879
63970
|
function checkReportHasWarnings(report) {
|
|
63880
|
-
return report.resolved.diagnostics.some((diagnostic) => diagnostic.severity !== "info") || report.projectEncodingAmbiguities.length > 0 || !report.ambientCredential.ok || report.credential.provider?.problem !== void 0;
|
|
63971
|
+
return report.resolved.diagnostics.some((diagnostic) => diagnostic.severity !== "info") || report.projectEncodingAmbiguities.length > 0 || !report.ambientCredential.ok || report.credential.provider?.problem !== void 0 || report.claudeVersion?.pinned?.installed === false;
|
|
63881
63972
|
}
|
|
63882
63973
|
function loadCheckProvider(paths, name) {
|
|
63883
63974
|
let definition;
|
|
@@ -63963,6 +64054,7 @@ function collectCheckReport(params) {
|
|
|
63963
64054
|
settingsFiles,
|
|
63964
64055
|
run: realRunPort,
|
|
63965
64056
|
credentialCache: realCredentialCacheEnv(paths),
|
|
64057
|
+
installedClaudeVersions: realInstalledClaudeVersions(),
|
|
63966
64058
|
...farmRoot === void 0 ? {} : { farmRoot },
|
|
63967
64059
|
platform: process.platform,
|
|
63968
64060
|
...provider === void 0 ? {} : { provider }
|
|
@@ -68686,11 +68778,11 @@ async function validateORPCError(map3, error62) {
|
|
|
68686
68778
|
if (!config2.data) {
|
|
68687
68779
|
return defined ? error62 : new ORPCError(code, { defined: true, status, message, data, cause });
|
|
68688
68780
|
}
|
|
68689
|
-
const
|
|
68690
|
-
if (
|
|
68781
|
+
const validated2 = await config2.data["~standard"].validate(error62.data);
|
|
68782
|
+
if (validated2.issues) {
|
|
68691
68783
|
return defined ? new ORPCError(code, { defined: false, status, message, data, cause }) : error62;
|
|
68692
68784
|
}
|
|
68693
|
-
return new ORPCError(code, { defined: true, status, message, data:
|
|
68785
|
+
return new ORPCError(code, { defined: true, status, message, data: validated2.value, cause });
|
|
68694
68786
|
}
|
|
68695
68787
|
var ContractProcedure = class {
|
|
68696
68788
|
/**
|
|
@@ -72649,7 +72741,7 @@ var ConflictingIdentityError = class extends UsageError {
|
|
|
72649
72741
|
positional;
|
|
72650
72742
|
flag;
|
|
72651
72743
|
};
|
|
72652
|
-
var VALUED_FLAGS = ["--identity", "--config-profile", "--provider", "--category", "--share", "--hide"];
|
|
72744
|
+
var VALUED_FLAGS = ["--identity", "--config-profile", "--provider", "--claude-version", "--category", "--share", "--hide"];
|
|
72653
72745
|
var BOOLEAN_FLAGS = [
|
|
72654
72746
|
{ flag: "--headroom", key: "headroom" },
|
|
72655
72747
|
{ flag: "--track-usage", key: "trackUsage" },
|
|
@@ -72695,6 +72787,7 @@ function parseLauncherArgv(argv) {
|
|
|
72695
72787
|
let flagIdentity;
|
|
72696
72788
|
let configProfile;
|
|
72697
72789
|
let provider;
|
|
72790
|
+
let claudeVersion;
|
|
72698
72791
|
const booleans = {};
|
|
72699
72792
|
const categoryFlags = [];
|
|
72700
72793
|
const shareFlags = [];
|
|
@@ -72749,6 +72842,9 @@ function parseLauncherArgv(argv) {
|
|
|
72749
72842
|
case "--provider":
|
|
72750
72843
|
provider = value2;
|
|
72751
72844
|
break;
|
|
72845
|
+
case "--claude-version":
|
|
72846
|
+
claudeVersion = value2;
|
|
72847
|
+
break;
|
|
72752
72848
|
case "--category":
|
|
72753
72849
|
categoryFlags.push(value2);
|
|
72754
72850
|
break;
|
|
@@ -72770,6 +72866,7 @@ function parseLauncherArgv(argv) {
|
|
|
72770
72866
|
...identity === void 0 ? {} : { identity },
|
|
72771
72867
|
...configProfile === void 0 ? {} : { configProfile },
|
|
72772
72868
|
...provider === void 0 ? {} : { provider },
|
|
72869
|
+
...claudeVersion === void 0 ? {} : { claudeVersion },
|
|
72773
72870
|
...native ? { native: true } : {},
|
|
72774
72871
|
...booleans,
|
|
72775
72872
|
categoryFlags,
|
|
@@ -73173,13 +73270,13 @@ function pushProvider(push, entry, cacheEnv) {
|
|
|
73173
73270
|
push("provider", "fail", new LegacyProviderFileError(entry.path, conversion).message, entry.name);
|
|
73174
73271
|
return;
|
|
73175
73272
|
}
|
|
73176
|
-
const
|
|
73177
|
-
if (!
|
|
73178
|
-
push("provider", "fail", new ConfigValidationError(entry.path,
|
|
73273
|
+
const validated2 = ProviderSchema.safeParse(parsed);
|
|
73274
|
+
if (!validated2.success) {
|
|
73275
|
+
push("provider", "fail", new ConfigValidationError(entry.path, validated2.error.issues).message, entry.name);
|
|
73179
73276
|
return;
|
|
73180
73277
|
}
|
|
73181
|
-
const cache = cacheClause(cacheEnv, `provider ${entry.name}`,
|
|
73182
|
-
push("provider", cache.unreadable ? "fail" : "pass", `${entry.name} is valid (${describeProviderEndpoint(
|
|
73278
|
+
const cache = cacheClause(cacheEnv, `provider ${entry.name}`, validated2.data.credential);
|
|
73279
|
+
push("provider", cache.unreadable ? "fail" : "pass", `${entry.name} is valid (${describeProviderEndpoint(validated2.data)}, credential ${describeCredential(validated2.data.credential)})${cache.text}.`, entry.name);
|
|
73183
73280
|
}
|
|
73184
73281
|
function pushLegacyName(push, params) {
|
|
73185
73282
|
const legacyVariables = Object.keys(params.env).filter((name) => name.startsWith(LEGACY_ENV_PREFIX) && params.env[name] !== void 0).sort();
|
|
@@ -73203,6 +73300,13 @@ function runDoctor(params) {
|
|
|
73203
73300
|
const push = (section, severity, message, subject) => {
|
|
73204
73301
|
findings.push({ section, severity, message, ...subject === void 0 ? {} : { subject } });
|
|
73205
73302
|
};
|
|
73303
|
+
const checkPin = (section, subject, where, version2) => {
|
|
73304
|
+
const installed = params.installedClaudeVersions;
|
|
73305
|
+
if (version2 === void 0 || installed === void 0 || installed.includes(version2)) {
|
|
73306
|
+
return;
|
|
73307
|
+
}
|
|
73308
|
+
push(section, "warn", `${where} pins Claude Code ${version2}, which is not installed (installed: ${installed.length === 0 ? "none" : installed.join(", ")}); a launch that resolves to it fails.`, subject);
|
|
73309
|
+
};
|
|
73206
73310
|
const ambient = detectAmbientCredential(params.env);
|
|
73207
73311
|
if (ambient === void 0) {
|
|
73208
73312
|
push("ambient-credential", "pass", "No ambient-credential environment variable is set.");
|
|
@@ -73235,12 +73339,13 @@ function runDoctor(params) {
|
|
|
73235
73339
|
pushLegacyName(push, params);
|
|
73236
73340
|
const profileSources = /* @__PURE__ */ new Map();
|
|
73237
73341
|
for (const entry of params.configProfiles) {
|
|
73238
|
-
const
|
|
73239
|
-
if (!
|
|
73240
|
-
push("config-profile", "fail",
|
|
73342
|
+
const validated2 = validateJson(ConfigProfileSchema, entry);
|
|
73343
|
+
if (!validated2.ok) {
|
|
73344
|
+
push("config-profile", "fail", validated2.message, entry.name);
|
|
73241
73345
|
continue;
|
|
73242
73346
|
}
|
|
73243
|
-
profileSources.set(entry.name, { name: entry.name, profile:
|
|
73347
|
+
profileSources.set(entry.name, { name: entry.name, profile: validated2.data });
|
|
73348
|
+
checkPin("config-profile", entry.name, `Configuration profile "${entry.name}"`, validated2.data.launch?.claudeVersion);
|
|
73244
73349
|
}
|
|
73245
73350
|
const loadProfile = (name) => profileSources.get(name);
|
|
73246
73351
|
for (const name of profileSources.keys()) {
|
|
@@ -73256,13 +73361,13 @@ function runDoctor(params) {
|
|
|
73256
73361
|
const validProfileNames = new Set(profileSources.keys());
|
|
73257
73362
|
const validIdentityNames = /* @__PURE__ */ new Set();
|
|
73258
73363
|
for (const entry of params.identities) {
|
|
73259
|
-
const
|
|
73260
|
-
if (!
|
|
73261
|
-
push("identity", "fail",
|
|
73364
|
+
const validated2 = validateJson(IdentitySchema, entry);
|
|
73365
|
+
if (!validated2.ok) {
|
|
73366
|
+
push("identity", "fail", validated2.message, entry.name);
|
|
73262
73367
|
continue;
|
|
73263
73368
|
}
|
|
73264
73369
|
validIdentityNames.add(entry.name);
|
|
73265
|
-
const defaultProfile =
|
|
73370
|
+
const defaultProfile = validated2.data.defaultConfigProfile;
|
|
73266
73371
|
if (defaultProfile !== void 0 && !validProfileNames.has(defaultProfile)) {
|
|
73267
73372
|
push(
|
|
73268
73373
|
"identity",
|
|
@@ -73271,7 +73376,7 @@ function runDoctor(params) {
|
|
|
73271
73376
|
entry.name
|
|
73272
73377
|
);
|
|
73273
73378
|
} else {
|
|
73274
|
-
const credential =
|
|
73379
|
+
const credential = validated2.data.credential;
|
|
73275
73380
|
const cache = credential === void 0 ? { text: "", unreadable: false } : cacheClause(params.credentialCache, `identity ${entry.name}`, credential);
|
|
73276
73381
|
push(
|
|
73277
73382
|
"identity",
|
|
@@ -73309,12 +73414,12 @@ function runDoctor(params) {
|
|
|
73309
73414
|
if (params.directoryRules.raw === void 0) {
|
|
73310
73415
|
push("directory-rules", "pass", "No directory-rules.json configured.");
|
|
73311
73416
|
} else {
|
|
73312
|
-
const
|
|
73313
|
-
if (!
|
|
73314
|
-
push("directory-rules", "fail",
|
|
73417
|
+
const validated2 = validateJson(DirectoryRulesSchema, params.directoryRules);
|
|
73418
|
+
if (!validated2.ok) {
|
|
73419
|
+
push("directory-rules", "fail", validated2.message);
|
|
73315
73420
|
} else {
|
|
73316
73421
|
push("directory-rules", "pass", `${params.directoryRules.path} is valid.`);
|
|
73317
|
-
for (const rule of
|
|
73422
|
+
for (const rule of validated2.data.rules) {
|
|
73318
73423
|
const badRefs = [];
|
|
73319
73424
|
if (rule.identity !== void 0 && !selectionExists(rule.identity)) {
|
|
73320
73425
|
badRefs.push(poolNameOf(rule.identity) === void 0 ? `identity "${rule.identity}"` : `pool "${poolNameOf(rule.identity) ?? ""}"`);
|
|
@@ -73322,6 +73427,7 @@ function runDoctor(params) {
|
|
|
73322
73427
|
if (rule.configProfile !== void 0 && !validProfileNames.has(rule.configProfile)) {
|
|
73323
73428
|
badRefs.push(`configuration profile "${rule.configProfile}"`);
|
|
73324
73429
|
}
|
|
73430
|
+
checkPin("directory-rules", rule.path, `Rule for "${rule.path}"`, rule.launch?.claudeVersion);
|
|
73325
73431
|
if (badRefs.length > 0) {
|
|
73326
73432
|
push("directory-rules", "fail", `Rule for "${rule.path}" names ${badRefs.join(" and ")}, which do not exist.`, rule.path);
|
|
73327
73433
|
} else {
|
|
@@ -73333,11 +73439,11 @@ function runDoctor(params) {
|
|
|
73333
73439
|
if (params.globalConfig.raw === void 0) {
|
|
73334
73440
|
push("global-config", "pass", "No config.json configured.");
|
|
73335
73441
|
} else {
|
|
73336
|
-
const
|
|
73337
|
-
if (!
|
|
73338
|
-
push("global-config", "fail",
|
|
73442
|
+
const validated2 = validateJson(GlobalConfigSchema, params.globalConfig);
|
|
73443
|
+
if (!validated2.ok) {
|
|
73444
|
+
push("global-config", "fail", validated2.message);
|
|
73339
73445
|
} else {
|
|
73340
|
-
const defaultProfile =
|
|
73446
|
+
const defaultProfile = validated2.data.defaultConfigProfile;
|
|
73341
73447
|
if (defaultProfile !== void 0 && !validProfileNames.has(defaultProfile)) {
|
|
73342
73448
|
push(
|
|
73343
73449
|
"global-config",
|
|
@@ -73346,27 +73452,28 @@ function runDoctor(params) {
|
|
|
73346
73452
|
);
|
|
73347
73453
|
} else {
|
|
73348
73454
|
push("global-config", "pass", `${params.globalConfig.path} is valid.`);
|
|
73455
|
+
checkPin("global-config", void 0, "config.json", validated2.data.launch?.claudeVersion);
|
|
73349
73456
|
}
|
|
73350
73457
|
}
|
|
73351
73458
|
}
|
|
73352
73459
|
if (params.categoriesLocal.raw === void 0) {
|
|
73353
73460
|
push("categories-local", "pass", "No categories.local.json configured.");
|
|
73354
73461
|
} else {
|
|
73355
|
-
const
|
|
73462
|
+
const validated2 = validateJson(CategoryClassificationOverlaySchema, params.categoriesLocal);
|
|
73356
73463
|
push(
|
|
73357
73464
|
"categories-local",
|
|
73358
|
-
|
|
73359
|
-
|
|
73465
|
+
validated2.ok ? "pass" : "fail",
|
|
73466
|
+
validated2.ok ? `${params.categoriesLocal.path} is valid.` : validated2.message
|
|
73360
73467
|
);
|
|
73361
73468
|
}
|
|
73362
73469
|
if (params.headroom.state.raw === void 0) {
|
|
73363
73470
|
push("headroom", "pass", "No headroom daemon has ever run; nothing to check.");
|
|
73364
73471
|
} else {
|
|
73365
|
-
const
|
|
73366
|
-
if (!
|
|
73367
|
-
push("headroom", "fail",
|
|
73472
|
+
const validated2 = validateJson(HeadroomStateSchema, params.headroom.state);
|
|
73473
|
+
if (!validated2.ok) {
|
|
73474
|
+
push("headroom", "fail", validated2.message);
|
|
73368
73475
|
} else {
|
|
73369
|
-
const state =
|
|
73476
|
+
const state = validated2.data;
|
|
73370
73477
|
const supervisorAlive = state.supervisorPid !== void 0 && params.headroom.isRunning(state.supervisorPid);
|
|
73371
73478
|
const headroomAlive = state.headroomPid !== void 0 && params.headroom.isRunning(state.headroomPid);
|
|
73372
73479
|
if (state.supervisorPid === void 0) {
|
|
@@ -73536,6 +73643,7 @@ function collectDoctorReport(params) {
|
|
|
73536
73643
|
const report = runDoctor({
|
|
73537
73644
|
env: params.env,
|
|
73538
73645
|
credentialCache: realCredentialCacheEnv(paths),
|
|
73646
|
+
installedClaudeVersions: realInstalledClaudeVersions(),
|
|
73539
73647
|
identities,
|
|
73540
73648
|
configProfiles,
|
|
73541
73649
|
providers,
|
|
@@ -74686,6 +74794,7 @@ Launching:
|
|
|
74686
74794
|
--category <category=bool> share or hide a category (repeatable)
|
|
74687
74795
|
--share <path>, --hide <path> share or hide one <category>/<path> entry (repeatable)
|
|
74688
74796
|
--[no-]skip-permissions, --[no-]remote-control, --[no-]headroom, --[no-]track-usage
|
|
74797
|
+
--claude-version <version> run exactly this installed Claude Code version (not the highest)
|
|
74689
74798
|
--[no-]wait with @pool:<name>, sleep until the earliest member returns when all are refused
|
|
74690
74799
|
--native run the real claude with nothing from agent-shim applied (no other launch flag allowed)
|
|
74691
74800
|
|
|
@@ -75173,7 +75282,11 @@ function prepareLaunch(params) {
|
|
|
75173
75282
|
} else if (params.farm !== void 0) {
|
|
75174
75283
|
cascadeLaunch = flattenLayers(assembleCascade(params.farm.loadCascade(configProfileDecision.name, cliOverride)).layers, { home: params.farm.home }).launch;
|
|
75175
75284
|
}
|
|
75176
|
-
const
|
|
75285
|
+
const pinnedVersion = resolveClaudeVersion({ env, ...parsedArgv.claudeVersion === void 0 ? {} : { flag: parsedArgv.claudeVersion }, ...cascadeLaunch?.claudeVersion === void 0 ? {} : { cascade: cascadeLaunch.claudeVersion } });
|
|
75286
|
+
const discovered = params.resolveClaudeBinary(pinnedVersion === void 0 ? void 0 : { version: pinnedVersion.version });
|
|
75287
|
+
if (pinnedVersion !== void 0) {
|
|
75288
|
+
log.info(`agent-shim: Claude Code ${pinnedVersion.version} (pinned by ${pinnedVersion.source})`);
|
|
75289
|
+
}
|
|
75177
75290
|
const resolvedFlags = resolveLaunchFlags({
|
|
75178
75291
|
env,
|
|
75179
75292
|
// A pool pick reads the usage the front door records, so a pool launch records its own unless something says otherwise.
|
|
@@ -75319,6 +75432,7 @@ function otherLaunchFlags(parsed) {
|
|
|
75319
75432
|
...parsed.identity === void 0 ? [] : ["@<identity> / --identity"],
|
|
75320
75433
|
...parsed.configProfile === void 0 ? [] : ["--config-profile"],
|
|
75321
75434
|
...parsed.provider === void 0 ? [] : [parsed.provider === false ? "--no-provider" : "--provider"],
|
|
75435
|
+
...parsed.claudeVersion === void 0 ? [] : ["--claude-version"],
|
|
75322
75436
|
...parsed.headroom === void 0 ? [] : ["--[no-]headroom"],
|
|
75323
75437
|
...parsed.trackUsage === void 0 ? [] : ["--[no-]track-usage"],
|
|
75324
75438
|
...parsed.skipPermissions === void 0 ? [] : ["--[no-]skip-permissions"],
|