claude-multi 0.6.4 → 0.8.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/CHANGELOG.md +61 -0
- package/dist/cli.js +1047 -672
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -7300,15 +7300,31 @@ function getApiKeyPlaceholder(providerName) {
|
|
|
7300
7300
|
return prefix ? `${prefix}...` : "sk-...";
|
|
7301
7301
|
}
|
|
7302
7302
|
function providerHasRegions(providerName) {
|
|
7303
|
-
return providerName
|
|
7303
|
+
return providerName in PROVIDER_REGION_MAPS;
|
|
7304
|
+
}
|
|
7305
|
+
function getProviderRegions(providerName) {
|
|
7306
|
+
return PROVIDER_REGION_MAPS[providerName];
|
|
7307
|
+
}
|
|
7308
|
+
function detectRegionFromBaseUrl(baseUrl) {
|
|
7309
|
+
for (const regionMap of Object.values(PROVIDER_REGION_MAPS)) {
|
|
7310
|
+
for (const [regionCode, config] of Object.entries(regionMap)) {
|
|
7311
|
+
const escaped = config.baseUrl.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7312
|
+
const regex = new RegExp(`^${escaped}/?$`);
|
|
7313
|
+
if (regex.test(baseUrl)) {
|
|
7314
|
+
return regionCode;
|
|
7315
|
+
}
|
|
7316
|
+
}
|
|
7317
|
+
}
|
|
7318
|
+
return null;
|
|
7304
7319
|
}
|
|
7305
7320
|
function resolveRegionTemplate(template, region) {
|
|
7306
7321
|
if (!providerHasRegions(template.name)) {
|
|
7307
7322
|
return template;
|
|
7308
7323
|
}
|
|
7309
|
-
const
|
|
7324
|
+
const regionMap = PROVIDER_REGION_MAPS[template.name];
|
|
7325
|
+
const regionConfig = regionMap?.[region];
|
|
7310
7326
|
if (!regionConfig) {
|
|
7311
|
-
throw new Error(`Unknown region '${region}' for ${template.name}. Available: ${Object.keys(
|
|
7327
|
+
throw new Error(`Unknown region '${region}' for ${template.name}. Available: ${regionMap ? Object.keys(regionMap).join(", ") : "none"}`);
|
|
7312
7328
|
}
|
|
7313
7329
|
const resolved = structuredClone(template);
|
|
7314
7330
|
resolved.settings.env.ANTHROPIC_BASE_URL = regionConfig.baseUrl;
|
|
@@ -7338,7 +7354,8 @@ function getProviderByBaseUrl(baseUrl) {
|
|
|
7338
7354
|
if (baseUrl === templateUrl)
|
|
7339
7355
|
return name;
|
|
7340
7356
|
}
|
|
7341
|
-
|
|
7357
|
+
const regionCode = detectRegionFromBaseUrl(baseUrl);
|
|
7358
|
+
if (regionCode) {
|
|
7342
7359
|
return "mimo-token";
|
|
7343
7360
|
}
|
|
7344
7361
|
return null;
|
|
@@ -7357,7 +7374,7 @@ function detectProvider(configDir) {
|
|
|
7357
7374
|
return null;
|
|
7358
7375
|
}
|
|
7359
7376
|
}
|
|
7360
|
-
var PROVIDER_COMMON_ENV, PROVIDER_TEMPLATES, API_KEY_PREFIXES, MIMO_TOKEN_REGIONS;
|
|
7377
|
+
var PROVIDER_COMMON_ENV, PROVIDER_TEMPLATES, API_KEY_PREFIXES, MIMO_TOKEN_REGIONS, PROVIDER_REGION_MAPS;
|
|
7361
7378
|
var init_templates = __esm(() => {
|
|
7362
7379
|
PROVIDER_COMMON_ENV = {};
|
|
7363
7380
|
PROVIDER_TEMPLATES = {
|
|
@@ -7379,7 +7396,9 @@ var init_templates = __esm(() => {
|
|
|
7379
7396
|
REASONING_EFFORT: "high",
|
|
7380
7397
|
MAX_THINKING_TOKENS: "8000",
|
|
7381
7398
|
ENABLE_STREAMING: "true",
|
|
7382
|
-
MAX_OUTPUT_TOKENS: "64000"
|
|
7399
|
+
MAX_OUTPUT_TOKENS: "64000",
|
|
7400
|
+
CLAUDE_CODE_AUTO_COMPACT_WINDOW: "131072",
|
|
7401
|
+
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE: "75"
|
|
7383
7402
|
},
|
|
7384
7403
|
includeCoAuthoredBy: false,
|
|
7385
7404
|
alwaysThinkingEnabled: false
|
|
@@ -7388,25 +7407,26 @@ var init_templates = __esm(() => {
|
|
|
7388
7407
|
minimax: {
|
|
7389
7408
|
name: "minimax",
|
|
7390
7409
|
displayName: "MiniMax",
|
|
7391
|
-
description: "MiniMax-
|
|
7410
|
+
description: "MiniMax-M3 — 1M context, frontier coding/agentic, native multimodal — via minimax.io",
|
|
7392
7411
|
settings: {
|
|
7393
7412
|
env: {
|
|
7394
7413
|
ANTHROPIC_AUTH_TOKEN: "",
|
|
7395
7414
|
ANTHROPIC_BASE_URL: "https://api.minimax.io/anthropic",
|
|
7396
7415
|
API_TIMEOUT_MS: "3000000",
|
|
7397
7416
|
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1",
|
|
7398
|
-
ANTHROPIC_MODEL: "MiniMax-
|
|
7399
|
-
ANTHROPIC_SMALL_FAST_MODEL: "MiniMax-
|
|
7400
|
-
ANTHROPIC_DEFAULT_SONNET_MODEL: "MiniMax-
|
|
7401
|
-
ANTHROPIC_DEFAULT_OPUS_MODEL: "MiniMax-
|
|
7402
|
-
ANTHROPIC_DEFAULT_HAIKU_MODEL: "MiniMax-
|
|
7417
|
+
ANTHROPIC_MODEL: "MiniMax-M3",
|
|
7418
|
+
ANTHROPIC_SMALL_FAST_MODEL: "MiniMax-M3",
|
|
7419
|
+
ANTHROPIC_DEFAULT_SONNET_MODEL: "MiniMax-M3",
|
|
7420
|
+
ANTHROPIC_DEFAULT_OPUS_MODEL: "MiniMax-M3",
|
|
7421
|
+
ANTHROPIC_DEFAULT_HAIKU_MODEL: "MiniMax-M3",
|
|
7403
7422
|
ENABLE_THINKING: "true",
|
|
7404
7423
|
REASONING_EFFORT: "high",
|
|
7405
|
-
MAX_OUTPUT_TOKENS: "
|
|
7406
|
-
MAX_THINKING_TOKENS: "32000"
|
|
7424
|
+
MAX_OUTPUT_TOKENS: "512000",
|
|
7425
|
+
MAX_THINKING_TOKENS: "32000",
|
|
7426
|
+
CLAUDE_CODE_EFFORT_LEVEL: "max"
|
|
7407
7427
|
},
|
|
7408
7428
|
includeCoAuthoredBy: false,
|
|
7409
|
-
alwaysThinkingEnabled:
|
|
7429
|
+
alwaysThinkingEnabled: false
|
|
7410
7430
|
}
|
|
7411
7431
|
},
|
|
7412
7432
|
deepseek: {
|
|
@@ -7493,7 +7513,9 @@ var init_templates = __esm(() => {
|
|
|
7493
7513
|
ENABLE_THINKING: "true",
|
|
7494
7514
|
REASONING_EFFORT: "high",
|
|
7495
7515
|
MAX_THINKING_TOKENS: "16000",
|
|
7496
|
-
MAX_OUTPUT_TOKENS: "65536"
|
|
7516
|
+
MAX_OUTPUT_TOKENS: "65536",
|
|
7517
|
+
CLAUDE_CODE_AUTO_COMPACT_WINDOW: "131072",
|
|
7518
|
+
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE: "75"
|
|
7497
7519
|
},
|
|
7498
7520
|
includeCoAuthoredBy: false,
|
|
7499
7521
|
alwaysThinkingEnabled: false
|
|
@@ -7516,7 +7538,9 @@ var init_templates = __esm(() => {
|
|
|
7516
7538
|
ENABLE_THINKING: "true",
|
|
7517
7539
|
REASONING_EFFORT: "high",
|
|
7518
7540
|
MAX_THINKING_TOKENS: "16000",
|
|
7519
|
-
MAX_OUTPUT_TOKENS: "65536"
|
|
7541
|
+
MAX_OUTPUT_TOKENS: "65536",
|
|
7542
|
+
CLAUDE_CODE_AUTO_COMPACT_WINDOW: "131072",
|
|
7543
|
+
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE: "75"
|
|
7520
7544
|
},
|
|
7521
7545
|
includeCoAuthoredBy: false,
|
|
7522
7546
|
alwaysThinkingEnabled: false
|
|
@@ -7539,7 +7563,9 @@ var init_templates = __esm(() => {
|
|
|
7539
7563
|
ENABLE_THINKING: "true",
|
|
7540
7564
|
REASONING_EFFORT: "high",
|
|
7541
7565
|
MAX_THINKING_TOKENS: "16000",
|
|
7542
|
-
MAX_OUTPUT_TOKENS: "65536"
|
|
7566
|
+
MAX_OUTPUT_TOKENS: "65536",
|
|
7567
|
+
CLAUDE_CODE_AUTO_COMPACT_WINDOW: "131072",
|
|
7568
|
+
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE: "75"
|
|
7543
7569
|
},
|
|
7544
7570
|
includeCoAuthoredBy: false,
|
|
7545
7571
|
alwaysThinkingEnabled: false
|
|
@@ -7563,6 +7589,9 @@ var init_templates = __esm(() => {
|
|
|
7563
7589
|
baseUrl: "https://token-plan-ams.xiaomimimo.com/anthropic"
|
|
7564
7590
|
}
|
|
7565
7591
|
};
|
|
7592
|
+
PROVIDER_REGION_MAPS = {
|
|
7593
|
+
"mimo-token": MIMO_TOKEN_REGIONS
|
|
7594
|
+
};
|
|
7566
7595
|
});
|
|
7567
7596
|
|
|
7568
7597
|
// src/util/json-file.ts
|
|
@@ -7665,6 +7694,22 @@ var init_constants = __esm(() => {
|
|
|
7665
7694
|
};
|
|
7666
7695
|
});
|
|
7667
7696
|
|
|
7697
|
+
// src/constants/env.ts
|
|
7698
|
+
var TUNABLE_ENV_VARS;
|
|
7699
|
+
var init_env = __esm(() => {
|
|
7700
|
+
TUNABLE_ENV_VARS = new Set([
|
|
7701
|
+
"MAX_OUTPUT_TOKENS",
|
|
7702
|
+
"MAX_THINKING_TOKENS",
|
|
7703
|
+
"REASONING_EFFORT",
|
|
7704
|
+
"ENABLE_THINKING",
|
|
7705
|
+
"ENABLE_STREAMING",
|
|
7706
|
+
"API_TIMEOUT_MS",
|
|
7707
|
+
"CLAUDE_CODE_EFFORT_LEVEL",
|
|
7708
|
+
"CLAUDE_CODE_AUTO_COMPACT_WINDOW",
|
|
7709
|
+
"CLAUDE_AUTOCOMPACT_PCT_OVERRIDE"
|
|
7710
|
+
]);
|
|
7711
|
+
});
|
|
7712
|
+
|
|
7668
7713
|
// node_modules/semver/internal/constants.js
|
|
7669
7714
|
var require_constants = __commonJS((exports, module) => {
|
|
7670
7715
|
var SEMVER_SPEC_VERSION = "2.0.0";
|
|
@@ -9492,22 +9537,11 @@ var require_semver2 = __commonJS((exports, module) => {
|
|
|
9492
9537
|
});
|
|
9493
9538
|
|
|
9494
9539
|
// src/paths.ts
|
|
9495
|
-
var exports_paths = {};
|
|
9496
|
-
__export(exports_paths, {
|
|
9497
|
-
getBaseDir: () => getBaseDir,
|
|
9498
|
-
PINNED_CLAUDE_BIN: () => PINNED_CLAUDE_BIN,
|
|
9499
|
-
PINNED_BIN_DIR: () => PINNED_BIN_DIR
|
|
9500
|
-
});
|
|
9501
9540
|
import { homedir } from "node:os";
|
|
9502
|
-
import { join as join2 } from "node:path";
|
|
9503
9541
|
function getBaseDir() {
|
|
9504
9542
|
return process.env.CLAUDE_MULTI_HOME || homedir();
|
|
9505
9543
|
}
|
|
9506
|
-
var
|
|
9507
|
-
var init_paths = __esm(() => {
|
|
9508
|
-
PINNED_BIN_DIR = join2(homedir(), ".claude-multi", "bin");
|
|
9509
|
-
PINNED_CLAUDE_BIN = process.platform === "win32" ? join2(PINNED_BIN_DIR, "node_modules", ".bin", "claude.cmd") : join2(PINNED_BIN_DIR, "node_modules", ".bin", "claude");
|
|
9510
|
-
});
|
|
9544
|
+
var init_paths = () => {};
|
|
9511
9545
|
|
|
9512
9546
|
// src/util/runtime.ts
|
|
9513
9547
|
function detectPackageManager() {
|
|
@@ -9521,27 +9555,12 @@ function detectPackageManager() {
|
|
|
9521
9555
|
}
|
|
9522
9556
|
|
|
9523
9557
|
// src/version.ts
|
|
9524
|
-
var exports_version = {};
|
|
9525
|
-
__export(exports_version, {
|
|
9526
|
-
upgradeClaudeMulti: () => upgradeClaudeMulti,
|
|
9527
|
-
updateClaudeCode: () => updateClaudeCode,
|
|
9528
|
-
isThirdPartyApiBroken: () => isThirdPartyApiBroken,
|
|
9529
|
-
installPinnedClaude: () => installPinnedClaude,
|
|
9530
|
-
getPinnedBinaryVersion: () => getPinnedBinaryVersion,
|
|
9531
|
-
getLatestVersion: () => getLatestVersion,
|
|
9532
|
-
getLatestClaudeMultiVersion: () => getLatestClaudeMultiVersion,
|
|
9533
|
-
getCurrentVersion: () => getCurrentVersion,
|
|
9534
|
-
getClaudeMultiVersion: () => getClaudeMultiVersion,
|
|
9535
|
-
checkForUpdates: () => checkForUpdates,
|
|
9536
|
-
checkForClaudeMultiUpdates: () => checkForClaudeMultiUpdates,
|
|
9537
|
-
COMPATIBLE_CLAUDE_VERSION: () => COMPATIBLE_CLAUDE_VERSION
|
|
9538
|
-
});
|
|
9539
9558
|
import { execSync } from "node:child_process";
|
|
9540
|
-
import {
|
|
9541
|
-
import { join as
|
|
9559
|
+
import { readFileSync as readFileSync2 } from "node:fs";
|
|
9560
|
+
import { join as join2, dirname } from "node:path";
|
|
9542
9561
|
import { fileURLToPath } from "node:url";
|
|
9543
9562
|
function getClaudeMultiVersion() {
|
|
9544
|
-
const pkgPath =
|
|
9563
|
+
const pkgPath = join2(dirname(fileURLToPath(import.meta.url)), "..", "package.json");
|
|
9545
9564
|
const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
|
|
9546
9565
|
if (typeof pkg !== "object" || pkg === null || typeof pkg.version !== "string") {
|
|
9547
9566
|
throw new ClaudeMultiError(ErrorCode.CONFIG_CORRUPTED, "Could not read package version");
|
|
@@ -9601,40 +9620,6 @@ function getCurrentVersion() {
|
|
|
9601
9620
|
return null;
|
|
9602
9621
|
}
|
|
9603
9622
|
}
|
|
9604
|
-
function isThirdPartyApiBroken(version) {
|
|
9605
|
-
return import_semver.default.gte(version, "2.1.154") && import_semver.default.lt(version, "2.1.156");
|
|
9606
|
-
}
|
|
9607
|
-
function getPinnedBinaryVersion() {
|
|
9608
|
-
const pkgJsonPath = join3(PINNED_BIN_DIR, "node_modules", "@anthropic-ai", "claude-code", "package.json");
|
|
9609
|
-
try {
|
|
9610
|
-
if (!existsSync2(pkgJsonPath))
|
|
9611
|
-
return null;
|
|
9612
|
-
const pkg = JSON.parse(readFileSync2(pkgJsonPath, "utf-8"));
|
|
9613
|
-
return pkg.version ?? null;
|
|
9614
|
-
} catch {
|
|
9615
|
-
return null;
|
|
9616
|
-
}
|
|
9617
|
-
}
|
|
9618
|
-
function installPinnedClaude() {
|
|
9619
|
-
const pm = detectPackageManager();
|
|
9620
|
-
mkdirSync(PINNED_BIN_DIR, { recursive: true });
|
|
9621
|
-
const pkgJsonPath = join3(PINNED_BIN_DIR, "package.json");
|
|
9622
|
-
if (!existsSync2(pkgJsonPath)) {
|
|
9623
|
-
writeFileSync(pkgJsonPath, JSON.stringify({ dependencies: {} }, null, 2));
|
|
9624
|
-
}
|
|
9625
|
-
const pkg = `@anthropic-ai/claude-code@${COMPATIBLE_CLAUDE_VERSION}`;
|
|
9626
|
-
const commands = {
|
|
9627
|
-
bun: `bun add --cwd ${PINNED_BIN_DIR} ${pkg}`,
|
|
9628
|
-
npm: `npm install --prefix ${PINNED_BIN_DIR} ${pkg}`,
|
|
9629
|
-
pnpm: `pnpm add --dir ${PINNED_BIN_DIR} ${pkg}`,
|
|
9630
|
-
deno: `cd ${PINNED_BIN_DIR} && npm install ${pkg}`
|
|
9631
|
-
};
|
|
9632
|
-
try {
|
|
9633
|
-
execSync(commands[pm], { stdio: "inherit" });
|
|
9634
|
-
} catch (err) {
|
|
9635
|
-
throw new ClaudeMultiError(ErrorCode.UPDATE_FAILED, `Failed to install pinned Claude v${COMPATIBLE_CLAUDE_VERSION}: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
|
|
9636
|
-
}
|
|
9637
|
-
}
|
|
9638
9623
|
async function getLatestVersion() {
|
|
9639
9624
|
try {
|
|
9640
9625
|
const response = await fetch("https://registry.npmjs.org/@anthropic-ai/claude-code/latest");
|
|
@@ -9669,20 +9654,15 @@ function updateClaudeCode() {
|
|
|
9669
9654
|
throw new ClaudeMultiError(ErrorCode.UPDATE_FAILED, `Failed to update @anthropic-ai/claude-code: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
|
|
9670
9655
|
}
|
|
9671
9656
|
}
|
|
9672
|
-
var import_semver, COMPATIBLE_CLAUDE_VERSION = "2.1.156";
|
|
9673
9657
|
var init_version = __esm(() => {
|
|
9674
9658
|
init_errors();
|
|
9675
|
-
init_paths();
|
|
9676
|
-
import_semver = __toESM(require_semver2(), 1);
|
|
9677
9659
|
});
|
|
9678
9660
|
|
|
9679
9661
|
// src/wrapper.ts
|
|
9680
9662
|
var exports_wrapper = {};
|
|
9681
9663
|
__export(exports_wrapper, {
|
|
9682
|
-
tryGetGlobalClaudePath: () => tryGetGlobalClaudePath,
|
|
9683
9664
|
tryGetClaudePath: () => tryGetClaudePath,
|
|
9684
9665
|
removeWrapper: () => removeWrapper,
|
|
9685
|
-
getGlobalClaudePath: () => getGlobalClaudePath,
|
|
9686
9666
|
getDefaultBinaryPath: () => getDefaultBinaryPath,
|
|
9687
9667
|
getClaudePath: () => getClaudePath,
|
|
9688
9668
|
generateWrapperScriptSafe: () => generateWrapperScriptSafe,
|
|
@@ -9691,7 +9671,7 @@ __export(exports_wrapper, {
|
|
|
9691
9671
|
createWrapper: () => createWrapper,
|
|
9692
9672
|
buildWrapperScript: () => buildWrapperScript
|
|
9693
9673
|
});
|
|
9694
|
-
import { existsSync as
|
|
9674
|
+
import { existsSync as existsSync2, mkdirSync, chmodSync, unlinkSync } from "node:fs";
|
|
9695
9675
|
import { writeFile as writeFile2 } from "node:fs/promises";
|
|
9696
9676
|
import { resolve, dirname as dirname2 } from "node:path";
|
|
9697
9677
|
import { execSync as execSync2 } from "node:child_process";
|
|
@@ -9699,19 +9679,15 @@ function getClaudePath() {
|
|
|
9699
9679
|
const override = process.env.CLAUDE_MULTI_CLAUDE_PATH;
|
|
9700
9680
|
if (override) {
|
|
9701
9681
|
const resolved = resolve(override);
|
|
9702
|
-
if (!
|
|
9682
|
+
if (!existsSync2(resolved)) {
|
|
9703
9683
|
throw new ClaudeMultiError(ErrorCode.CLAUDE_NOT_FOUND, `CLAUDE_MULTI_CLAUDE_PATH points to ${resolved} but that file does not exist`);
|
|
9704
9684
|
}
|
|
9705
9685
|
return resolved;
|
|
9706
9686
|
}
|
|
9707
|
-
if (existsSync3(PINNED_CLAUDE_BIN)) {
|
|
9708
|
-
return PINNED_CLAUDE_BIN;
|
|
9709
|
-
}
|
|
9710
9687
|
try {
|
|
9711
9688
|
const command = process.platform === "win32" ? "where claude" : "which claude";
|
|
9712
9689
|
const claudePath = execSync2(command, { encoding: "utf-8" }).trim();
|
|
9713
|
-
const firstPath = claudePath.split(
|
|
9714
|
-
`)[0];
|
|
9690
|
+
const firstPath = claudePath.split(/\r?\n/)[0];
|
|
9715
9691
|
if (!firstPath) {
|
|
9716
9692
|
throw new ClaudeMultiError(ErrorCode.CLAUDE_NOT_FOUND, "Could not determine Claude path");
|
|
9717
9693
|
}
|
|
@@ -9729,37 +9705,6 @@ function tryGetClaudePath() {
|
|
|
9729
9705
|
return null;
|
|
9730
9706
|
}
|
|
9731
9707
|
}
|
|
9732
|
-
function getGlobalClaudePath() {
|
|
9733
|
-
const override = process.env.CLAUDE_MULTI_CLAUDE_PATH;
|
|
9734
|
-
if (override) {
|
|
9735
|
-
const resolved = resolve(override);
|
|
9736
|
-
if (!existsSync3(resolved)) {
|
|
9737
|
-
throw new ClaudeMultiError(ErrorCode.CLAUDE_NOT_FOUND, `CLAUDE_MULTI_CLAUDE_PATH points to ${resolved} but that file does not exist`);
|
|
9738
|
-
}
|
|
9739
|
-
return resolved;
|
|
9740
|
-
}
|
|
9741
|
-
try {
|
|
9742
|
-
const command = process.platform === "win32" ? "where claude" : "which claude";
|
|
9743
|
-
const claudePath = execSync2(command, { encoding: "utf-8" }).trim();
|
|
9744
|
-
const firstPath = claudePath.split(`
|
|
9745
|
-
`)[0];
|
|
9746
|
-
if (!firstPath) {
|
|
9747
|
-
throw new ClaudeMultiError(ErrorCode.CLAUDE_NOT_FOUND, "Could not determine Claude path");
|
|
9748
|
-
}
|
|
9749
|
-
return firstPath.trim();
|
|
9750
|
-
} catch (err) {
|
|
9751
|
-
if (err instanceof ClaudeMultiError)
|
|
9752
|
-
throw err;
|
|
9753
|
-
throw new ClaudeMultiError(ErrorCode.CLAUDE_NOT_FOUND, "Claude Code is not installed. Please install @anthropic-ai/claude-code first.", { cause: err });
|
|
9754
|
-
}
|
|
9755
|
-
}
|
|
9756
|
-
function tryGetGlobalClaudePath() {
|
|
9757
|
-
try {
|
|
9758
|
-
return getGlobalClaudePath();
|
|
9759
|
-
} catch {
|
|
9760
|
-
return null;
|
|
9761
|
-
}
|
|
9762
|
-
}
|
|
9763
9708
|
function generateWrapperScriptSafe(options) {
|
|
9764
9709
|
const claudePath = tryGetClaudePath();
|
|
9765
9710
|
if (!claudePath)
|
|
@@ -9791,11 +9736,11 @@ set "CLAUDE_CONFIG_DIR=${options.configDir}"
|
|
|
9791
9736
|
async function createWrapper(options) {
|
|
9792
9737
|
const { binaryPath, configDir } = options;
|
|
9793
9738
|
const binDir = dirname2(binaryPath);
|
|
9794
|
-
if (!
|
|
9795
|
-
|
|
9739
|
+
if (!existsSync2(binDir)) {
|
|
9740
|
+
mkdirSync(binDir, { recursive: true });
|
|
9796
9741
|
}
|
|
9797
|
-
if (!
|
|
9798
|
-
|
|
9742
|
+
if (!existsSync2(configDir)) {
|
|
9743
|
+
mkdirSync(configDir, { recursive: true });
|
|
9799
9744
|
}
|
|
9800
9745
|
if (process.platform === "win32") {
|
|
9801
9746
|
const script = generateWindowsWrapperScript(options);
|
|
@@ -9807,7 +9752,7 @@ async function createWrapper(options) {
|
|
|
9807
9752
|
}
|
|
9808
9753
|
}
|
|
9809
9754
|
function removeWrapper(binaryPath) {
|
|
9810
|
-
if (
|
|
9755
|
+
if (existsSync2(binaryPath)) {
|
|
9811
9756
|
unlinkSync(binaryPath);
|
|
9812
9757
|
}
|
|
9813
9758
|
}
|
|
@@ -9832,7 +9777,6 @@ function getDefaultBinaryPath(name) {
|
|
|
9832
9777
|
}
|
|
9833
9778
|
var init_wrapper = __esm(() => {
|
|
9834
9779
|
init_errors();
|
|
9835
|
-
init_paths();
|
|
9836
9780
|
});
|
|
9837
9781
|
|
|
9838
9782
|
// src/migration.ts
|
|
@@ -9849,11 +9793,11 @@ __export(exports_migration, {
|
|
|
9849
9793
|
LEGACY_INSTANCE_VERSION: () => LEGACY_INSTANCE_VERSION,
|
|
9850
9794
|
CONFIG_VERSION: () => CONFIG_VERSION
|
|
9851
9795
|
});
|
|
9852
|
-
import { existsSync as
|
|
9853
|
-
import { join as
|
|
9796
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readdirSync, copyFileSync, readFileSync as readFileSync3, rmSync, writeFileSync, chmodSync as chmodSync2 } from "node:fs";
|
|
9797
|
+
import { join as join3, dirname as dirname3 } from "node:path";
|
|
9854
9798
|
function updateClaudeJson(configDir) {
|
|
9855
|
-
const stateFile =
|
|
9856
|
-
if (!
|
|
9799
|
+
const stateFile = join3(configDir, ".claude.json");
|
|
9800
|
+
if (!existsSync3(stateFile))
|
|
9857
9801
|
return;
|
|
9858
9802
|
try {
|
|
9859
9803
|
const raw = JSON.parse(readFileSync3(stateFile, "utf-8"));
|
|
@@ -9863,7 +9807,7 @@ function updateClaudeJson(configDir) {
|
|
|
9863
9807
|
changed = true;
|
|
9864
9808
|
}
|
|
9865
9809
|
if (changed) {
|
|
9866
|
-
|
|
9810
|
+
writeFileSync(stateFile, JSON.stringify(raw, null, 2), "utf-8");
|
|
9867
9811
|
}
|
|
9868
9812
|
} catch {}
|
|
9869
9813
|
}
|
|
@@ -9872,10 +9816,10 @@ function needsInstanceMigration(config) {
|
|
|
9872
9816
|
const stored = config.instanceMigrationVersion;
|
|
9873
9817
|
if (!stored)
|
|
9874
9818
|
return INSTANCE_MIGRATIONS.length > 0;
|
|
9875
|
-
const storedCoerced =
|
|
9819
|
+
const storedCoerced = import_semver.default.coerce(stored);
|
|
9876
9820
|
if (!storedCoerced)
|
|
9877
9821
|
return INSTANCE_MIGRATIONS.length > 0;
|
|
9878
|
-
return INSTANCE_MIGRATIONS.some((m) =>
|
|
9822
|
+
return INSTANCE_MIGRATIONS.some((m) => import_semver.default.gt(m.version, storedCoerced) && import_semver.default.lte(m.version, current));
|
|
9879
9823
|
}
|
|
9880
9824
|
async function runInstanceMigrations(config) {
|
|
9881
9825
|
if (!needsInstanceMigration(config))
|
|
@@ -9885,8 +9829,8 @@ async function runInstanceMigrations(config) {
|
|
|
9885
9829
|
try {
|
|
9886
9830
|
createBackup(config);
|
|
9887
9831
|
const currentVersion = getClaudeMultiVersion();
|
|
9888
|
-
const stored =
|
|
9889
|
-
const applicable = INSTANCE_MIGRATIONS.filter((m) => stored ?
|
|
9832
|
+
const stored = import_semver.default.coerce(config.instanceMigrationVersion || "0.0.0");
|
|
9833
|
+
const applicable = INSTANCE_MIGRATIONS.filter((m) => stored ? import_semver.default.gt(m.version, stored) && import_semver.default.lte(m.version, currentVersion) : true).toSorted((a, b) => import_semver.default.compare(a.version, b.version));
|
|
9890
9834
|
for (const migration of applicable) {
|
|
9891
9835
|
for (let i = 0;i < config.instances.length; i++) {
|
|
9892
9836
|
const migrated = await migration.migrate({ ...config.instances[i] }, config);
|
|
@@ -9900,26 +9844,31 @@ async function runInstanceMigrations(config) {
|
|
|
9900
9844
|
}
|
|
9901
9845
|
}
|
|
9902
9846
|
function getBackupDir() {
|
|
9903
|
-
return
|
|
9847
|
+
return join3(getBaseDir(), ".claude-multi", "backups");
|
|
9904
9848
|
}
|
|
9905
9849
|
function getLockFile() {
|
|
9906
|
-
return
|
|
9850
|
+
return join3(getBaseDir(), ".claude-multi", ".migration.lock");
|
|
9907
9851
|
}
|
|
9908
9852
|
function createLock() {
|
|
9909
9853
|
const lockFile = getLockFile();
|
|
9910
9854
|
const lockDir = dirname3(lockFile);
|
|
9911
|
-
if (!
|
|
9912
|
-
|
|
9913
|
-
if (
|
|
9855
|
+
if (!existsSync3(lockDir))
|
|
9856
|
+
mkdirSync2(lockDir, { recursive: true });
|
|
9857
|
+
if (existsSync3(lockFile)) {
|
|
9914
9858
|
try {
|
|
9915
9859
|
const raw = JSON.parse(readFileSync3(lockFile, "utf-8"));
|
|
9916
9860
|
if (typeof raw === "object" && raw !== null && "pid" in raw && typeof raw.pid === "number") {
|
|
9917
9861
|
const lock = raw;
|
|
9918
|
-
|
|
9919
|
-
|
|
9920
|
-
return false;
|
|
9921
|
-
} catch {
|
|
9862
|
+
const lockAge = Date.now() - new Date(lock.startedAt).getTime();
|
|
9863
|
+
if (lockAge > 30 * 60 * 1000) {
|
|
9922
9864
|
rmSync(lockFile, { force: true });
|
|
9865
|
+
} else {
|
|
9866
|
+
try {
|
|
9867
|
+
process.kill(lock.pid, 0);
|
|
9868
|
+
return false;
|
|
9869
|
+
} catch {
|
|
9870
|
+
rmSync(lockFile, { force: true });
|
|
9871
|
+
}
|
|
9923
9872
|
}
|
|
9924
9873
|
} else {
|
|
9925
9874
|
rmSync(lockFile, { force: true });
|
|
@@ -9928,7 +9877,7 @@ function createLock() {
|
|
|
9928
9877
|
rmSync(lockFile, { force: true });
|
|
9929
9878
|
}
|
|
9930
9879
|
}
|
|
9931
|
-
|
|
9880
|
+
writeFileSync(lockFile, JSON.stringify({
|
|
9932
9881
|
pid: process.pid,
|
|
9933
9882
|
startedAt: new Date().toISOString()
|
|
9934
9883
|
}), "utf-8");
|
|
@@ -9953,30 +9902,30 @@ function clearMigrationFailure(config) {
|
|
|
9953
9902
|
}
|
|
9954
9903
|
function createBackup(config) {
|
|
9955
9904
|
const backupDir = getBackupDir();
|
|
9956
|
-
if (!
|
|
9957
|
-
|
|
9905
|
+
if (!existsSync3(backupDir)) {
|
|
9906
|
+
mkdirSync2(backupDir, { recursive: true });
|
|
9958
9907
|
}
|
|
9959
9908
|
const ts = new Date().toISOString().replace(/[:.]/g, "-");
|
|
9960
9909
|
const rand = Math.random().toString(36).slice(2, 6);
|
|
9961
9910
|
const fromV = config.version || "1.0.0";
|
|
9962
|
-
const backupPath =
|
|
9963
|
-
|
|
9964
|
-
const configSrc =
|
|
9965
|
-
if (
|
|
9966
|
-
copyFileSync(configSrc,
|
|
9911
|
+
const backupPath = join3(backupDir, `${ts}-${rand}-v${fromV}-to-v${CONFIG_VERSION}`);
|
|
9912
|
+
mkdirSync2(backupPath, { recursive: true });
|
|
9913
|
+
const configSrc = join3(getBaseDir(), ".claude-multi", "config.json");
|
|
9914
|
+
if (existsSync3(configSrc)) {
|
|
9915
|
+
copyFileSync(configSrc, join3(backupPath, "config.json"));
|
|
9967
9916
|
}
|
|
9968
|
-
const instancesDir =
|
|
9917
|
+
const instancesDir = join3(backupPath, "instances");
|
|
9969
9918
|
for (const inst of config.instances) {
|
|
9970
|
-
const settingsFile =
|
|
9971
|
-
if (
|
|
9972
|
-
const instDir =
|
|
9973
|
-
|
|
9974
|
-
copyFileSync(settingsFile,
|
|
9919
|
+
const settingsFile = join3(inst.configDir, "settings.json");
|
|
9920
|
+
if (existsSync3(settingsFile)) {
|
|
9921
|
+
const instDir = join3(instancesDir, inst.name);
|
|
9922
|
+
mkdirSync2(instDir, { recursive: true });
|
|
9923
|
+
copyFileSync(settingsFile, join3(instDir, "settings.json"));
|
|
9975
9924
|
}
|
|
9976
9925
|
}
|
|
9977
9926
|
const backups = readdirSync(backupDir).toSorted();
|
|
9978
9927
|
for (let i = 0;i < backups.length - 3; i++) {
|
|
9979
|
-
rmSync(
|
|
9928
|
+
rmSync(join3(backupDir, backups[i]), { force: true, recursive: true });
|
|
9980
9929
|
}
|
|
9981
9930
|
return backupPath;
|
|
9982
9931
|
}
|
|
@@ -9994,7 +9943,7 @@ function runMigration(config) {
|
|
|
9994
9943
|
if (!inst.name || !inst.configDir || !inst.binaryPath) {
|
|
9995
9944
|
warnings.push(`Instance entry missing required fields, skipping: ${JSON.stringify(inst)}`);
|
|
9996
9945
|
}
|
|
9997
|
-
if (inst.configDir && !
|
|
9946
|
+
if (inst.configDir && !existsSync3(inst.configDir)) {
|
|
9998
9947
|
warnings.push(`Instance '${inst.name}' configDir does not exist: ${inst.configDir}`);
|
|
9999
9948
|
}
|
|
10000
9949
|
}
|
|
@@ -10027,18 +9976,19 @@ function getMigrationStatus(config) {
|
|
|
10027
9976
|
}
|
|
10028
9977
|
function listBackups() {
|
|
10029
9978
|
const backupDir = getBackupDir();
|
|
10030
|
-
if (!
|
|
9979
|
+
if (!existsSync3(backupDir))
|
|
10031
9980
|
return [];
|
|
10032
9981
|
return readdirSync(backupDir).toSorted().toReversed();
|
|
10033
9982
|
}
|
|
10034
|
-
var
|
|
9983
|
+
var import_semver, CONFIG_VERSION = "2.0.0", LEGACY_INSTANCE_VERSION = "0.5", INSTANCE_MIGRATIONS;
|
|
10035
9984
|
var init_migration = __esm(() => {
|
|
10036
9985
|
init_paths();
|
|
10037
9986
|
init_constants();
|
|
10038
9987
|
init_version();
|
|
9988
|
+
init_env();
|
|
10039
9989
|
init_wrapper();
|
|
10040
9990
|
init_templates();
|
|
10041
|
-
|
|
9991
|
+
import_semver = __toESM(require_semver2(), 1);
|
|
10042
9992
|
INSTANCE_MIGRATIONS = [
|
|
10043
9993
|
{
|
|
10044
9994
|
version: "0.6.2",
|
|
@@ -10048,17 +9998,19 @@ var init_migration = __esm(() => {
|
|
|
10048
9998
|
if (instance.createdWithVersion && instance.createdWithVersion !== LEGACY_INSTANCE_VERSION && instance.createdWithVersion === currentVersion) {
|
|
10049
9999
|
return Promise.resolve(instance);
|
|
10050
10000
|
}
|
|
10051
|
-
if (
|
|
10052
|
-
const claudePath =
|
|
10001
|
+
if (existsSync3(instance.binaryPath)) {
|
|
10002
|
+
const claudePath = tryGetClaudePath();
|
|
10053
10003
|
if (claudePath !== null) {
|
|
10054
10004
|
const expected = buildWrapperScript(instance, claudePath);
|
|
10055
10005
|
try {
|
|
10056
10006
|
const current = readFileSync3(instance.binaryPath, "utf-8");
|
|
10057
10007
|
if (current !== expected) {
|
|
10058
|
-
|
|
10008
|
+
writeFileSync(instance.binaryPath, expected, { mode: 493 });
|
|
10059
10009
|
chmodSync2(instance.binaryPath, 493);
|
|
10060
10010
|
}
|
|
10061
10011
|
} catch {}
|
|
10012
|
+
} else {
|
|
10013
|
+
console.warn(`[migration] Could not find claude binary, skipping wrapper regeneration for instance: ${instance.name}`);
|
|
10062
10014
|
}
|
|
10063
10015
|
}
|
|
10064
10016
|
updateClaudeJson(instance.configDir);
|
|
@@ -10069,28 +10021,53 @@ var init_migration = __esm(() => {
|
|
|
10069
10021
|
version: "0.6.3",
|
|
10070
10022
|
description: "Sync provider template env vars (model names, thinking/output limits) to latest",
|
|
10071
10023
|
migrate: (instance) => {
|
|
10024
|
+
const currentVersion = getClaudeMultiVersion();
|
|
10025
|
+
if (instance.createdWithVersion && instance.createdWithVersion !== LEGACY_INSTANCE_VERSION && instance.createdWithVersion === currentVersion) {
|
|
10026
|
+
return Promise.resolve(instance);
|
|
10027
|
+
}
|
|
10072
10028
|
const providerName = instance.providerTemplate ?? detectProvider(instance.configDir);
|
|
10073
10029
|
if (!providerName)
|
|
10074
10030
|
return Promise.resolve(instance);
|
|
10075
|
-
|
|
10031
|
+
let template = getProviderTemplate(providerName);
|
|
10076
10032
|
if (!template)
|
|
10077
10033
|
return Promise.resolve(instance);
|
|
10078
|
-
const settingsFile =
|
|
10034
|
+
const settingsFile = join3(instance.configDir, "settings.json");
|
|
10079
10035
|
try {
|
|
10080
|
-
if (!
|
|
10036
|
+
if (!existsSync3(settingsFile))
|
|
10081
10037
|
return Promise.resolve(instance);
|
|
10082
10038
|
const existing = JSON.parse(readFileSync3(settingsFile, "utf-8"));
|
|
10083
10039
|
const existingEnv = existing.env ?? {};
|
|
10084
10040
|
const apiKey = existingEnv.ANTHROPIC_AUTH_TOKEN ?? "";
|
|
10041
|
+
const existingBaseUrl = existingEnv.ANTHROPIC_BASE_URL;
|
|
10042
|
+
let resolvedRegional = false;
|
|
10043
|
+
if (providerHasRegions(providerName)) {
|
|
10044
|
+
const providerRegions = getProviderRegions(providerName);
|
|
10045
|
+
const detectedRegion = detectRegionFromBaseUrl(existingBaseUrl ?? "") ?? instance.providerRegion;
|
|
10046
|
+
if (detectedRegion && providerRegions && detectedRegion in providerRegions) {
|
|
10047
|
+
template = resolveRegionTemplate(template, detectedRegion);
|
|
10048
|
+
instance.providerRegion = detectedRegion;
|
|
10049
|
+
resolvedRegional = true;
|
|
10050
|
+
}
|
|
10051
|
+
}
|
|
10085
10052
|
const templateSettings = structuredClone(template.settings);
|
|
10086
10053
|
const newEnv = { ...templateSettings.env, ANTHROPIC_AUTH_TOKEN: apiKey };
|
|
10054
|
+
if (providerHasRegions(providerName) && !resolvedRegional && existingBaseUrl) {
|
|
10055
|
+
newEnv.ANTHROPIC_BASE_URL = existingBaseUrl;
|
|
10056
|
+
}
|
|
10057
|
+
for (const key of TUNABLE_ENV_VARS) {
|
|
10058
|
+
if (key in existingEnv && existingEnv[key] !== templateSettings.env[key]) {
|
|
10059
|
+
newEnv[key] = existingEnv[key];
|
|
10060
|
+
}
|
|
10061
|
+
}
|
|
10087
10062
|
existing.env = { ...existingEnv, ...newEnv };
|
|
10088
10063
|
existing.includeCoAuthoredBy = template.settings.includeCoAuthoredBy;
|
|
10089
10064
|
existing.alwaysThinkingEnabled = template.settings.alwaysThinkingEnabled;
|
|
10090
|
-
|
|
10091
|
-
|
|
10092
|
-
|
|
10093
|
-
|
|
10065
|
+
writeFileSync(settingsFile, JSON.stringify(existing, null, 2), "utf-8");
|
|
10066
|
+
if (!instance.providerTemplate) {
|
|
10067
|
+
instance.providerTemplate = providerName;
|
|
10068
|
+
}
|
|
10069
|
+
} catch (err) {
|
|
10070
|
+
console.warn(`[migration] Failed to sync provider template for '${instance.name}': ${err instanceof Error ? err.message : String(err)}`);
|
|
10094
10071
|
}
|
|
10095
10072
|
return Promise.resolve(instance);
|
|
10096
10073
|
}
|
|
@@ -10105,6 +10082,7 @@ __export(exports_config, {
|
|
|
10105
10082
|
validatePluginOperation: () => validatePluginOperation,
|
|
10106
10083
|
updateInstanceAutoSync: () => updateInstanceAutoSync,
|
|
10107
10084
|
unsyncPluginsAndSkills: () => unsyncPluginsAndSkills,
|
|
10085
|
+
syncProviderTemplateForInstance: () => syncProviderTemplateForInstance,
|
|
10108
10086
|
syncPluginsAndSkills: () => syncPluginsAndSkills,
|
|
10109
10087
|
setTestDefaultClaudeDir: () => setTestDefaultClaudeDir,
|
|
10110
10088
|
setTestConfigDir: () => setTestConfigDir,
|
|
@@ -10151,11 +10129,11 @@ __export(exports_config, {
|
|
|
10151
10129
|
clearTestConfigDir: () => clearTestConfigDir,
|
|
10152
10130
|
addInstance: () => addInstance
|
|
10153
10131
|
});
|
|
10154
|
-
import { existsSync as
|
|
10132
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readdirSync as readdirSync2, statSync, readlinkSync, rmSync as rmSync2, lstatSync, readFileSync as readFileSync4, writeFileSync as writeFileSync2, renameSync } from "node:fs";
|
|
10155
10133
|
import { readFile as readFile2, writeFile as writeFile3, copyFile, mkdir, symlink } from "node:fs/promises";
|
|
10156
10134
|
import { homedir as homedir2 } from "node:os";
|
|
10157
10135
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
10158
|
-
import { dirname as dirname4, isAbsolute, join as
|
|
10136
|
+
import { dirname as dirname4, isAbsolute, join as join4, relative, resolve as resolve2 } from "node:path";
|
|
10159
10137
|
function setTestConfigDir(dir) {
|
|
10160
10138
|
_testConfigDir = dir;
|
|
10161
10139
|
}
|
|
@@ -10163,19 +10141,19 @@ function clearTestConfigDir() {
|
|
|
10163
10141
|
_testConfigDir = undefined;
|
|
10164
10142
|
}
|
|
10165
10143
|
function getConfigDir() {
|
|
10166
|
-
return _testConfigDir ??
|
|
10144
|
+
return _testConfigDir ?? join4(homedir2(), ".claude-multi");
|
|
10167
10145
|
}
|
|
10168
10146
|
function getConfigFile() {
|
|
10169
|
-
return
|
|
10147
|
+
return join4(getConfigDir(), "config.json");
|
|
10170
10148
|
}
|
|
10171
10149
|
async function copyDirRecursive(source, target) {
|
|
10172
|
-
if (!
|
|
10150
|
+
if (!existsSync4(target)) {
|
|
10173
10151
|
await mkdir(target, { recursive: true });
|
|
10174
10152
|
}
|
|
10175
10153
|
const entries = readdirSync2(source);
|
|
10176
10154
|
await Promise.all(entries.map(async (entry) => {
|
|
10177
|
-
const src =
|
|
10178
|
-
const tgt =
|
|
10155
|
+
const src = join4(source, entry);
|
|
10156
|
+
const tgt = join4(target, entry);
|
|
10179
10157
|
const s = statSync(src);
|
|
10180
10158
|
if (s.isDirectory()) {
|
|
10181
10159
|
await copyDirRecursive(src, tgt);
|
|
@@ -10192,8 +10170,8 @@ function lstatSafe(path) {
|
|
|
10192
10170
|
}
|
|
10193
10171
|
}
|
|
10194
10172
|
function ensureConfigDir() {
|
|
10195
|
-
if (!
|
|
10196
|
-
|
|
10173
|
+
if (!existsSync4(getConfigDir())) {
|
|
10174
|
+
mkdirSync3(getConfigDir(), { recursive: true });
|
|
10197
10175
|
}
|
|
10198
10176
|
}
|
|
10199
10177
|
function isConfig(raw) {
|
|
@@ -10201,7 +10179,7 @@ function isConfig(raw) {
|
|
|
10201
10179
|
}
|
|
10202
10180
|
async function loadConfig() {
|
|
10203
10181
|
ensureConfigDir();
|
|
10204
|
-
if (!
|
|
10182
|
+
if (!existsSync4(getConfigFile())) {
|
|
10205
10183
|
const defaultConfig = {
|
|
10206
10184
|
instances: [],
|
|
10207
10185
|
version: "2.0.0"
|
|
@@ -10297,7 +10275,7 @@ function getDefaultClaudeDir() {
|
|
|
10297
10275
|
if (_testDefaultClaudeDir) {
|
|
10298
10276
|
return _testDefaultClaudeDir;
|
|
10299
10277
|
}
|
|
10300
|
-
return
|
|
10278
|
+
return join4(homedir2(), ".claude");
|
|
10301
10279
|
}
|
|
10302
10280
|
function isBrokenSymlink(path) {
|
|
10303
10281
|
try {
|
|
@@ -10313,7 +10291,7 @@ function isBrokenSymlink(path) {
|
|
|
10313
10291
|
} else {
|
|
10314
10292
|
targetPath = resolve2(dirname4(path), target);
|
|
10315
10293
|
}
|
|
10316
|
-
return !
|
|
10294
|
+
return !existsSync4(targetPath);
|
|
10317
10295
|
} catch {
|
|
10318
10296
|
return false;
|
|
10319
10297
|
}
|
|
@@ -10321,7 +10299,7 @@ function isBrokenSymlink(path) {
|
|
|
10321
10299
|
function detectBrokenSymlinks(configDir) {
|
|
10322
10300
|
const result = { broken: [], all: [] };
|
|
10323
10301
|
for (const dir of SYNC_DIRS) {
|
|
10324
|
-
const targetPath =
|
|
10302
|
+
const targetPath = join4(configDir, dir);
|
|
10325
10303
|
try {
|
|
10326
10304
|
const stats = lstatSync(targetPath);
|
|
10327
10305
|
result.all.push(dir);
|
|
@@ -10334,13 +10312,13 @@ function detectBrokenSymlinks(configDir) {
|
|
|
10334
10312
|
}
|
|
10335
10313
|
function hasDefaultClaudeConfig() {
|
|
10336
10314
|
const defaultDir = getDefaultClaudeDir();
|
|
10337
|
-
const settingsFile =
|
|
10338
|
-
return
|
|
10315
|
+
const settingsFile = join4(defaultDir, "settings.json");
|
|
10316
|
+
return existsSync4(defaultDir) && existsSync4(settingsFile);
|
|
10339
10317
|
}
|
|
10340
10318
|
async function copySettingsFromDefault(targetConfigDir) {
|
|
10341
10319
|
const defaultDir = getDefaultClaudeDir();
|
|
10342
|
-
const sourceSettings =
|
|
10343
|
-
if (!
|
|
10320
|
+
const sourceSettings = join4(defaultDir, "settings.json");
|
|
10321
|
+
if (!existsSync4(sourceSettings)) {
|
|
10344
10322
|
throw new ClaudeMultiError(ErrorCode.DEFAULT_SETTINGS_NOT_FOUND, "Default Claude settings.json not found");
|
|
10345
10323
|
}
|
|
10346
10324
|
const content = await readFile2(sourceSettings, "utf-8");
|
|
@@ -10356,18 +10334,18 @@ async function copySettingsFromDefault(targetConfigDir) {
|
|
|
10356
10334
|
safeSettings[key] = settings[key];
|
|
10357
10335
|
}
|
|
10358
10336
|
}
|
|
10359
|
-
if (!
|
|
10337
|
+
if (!existsSync4(targetConfigDir)) {
|
|
10360
10338
|
await mkdir(targetConfigDir, { recursive: true });
|
|
10361
10339
|
}
|
|
10362
|
-
const targetSettings =
|
|
10340
|
+
const targetSettings = join4(targetConfigDir, "settings.json");
|
|
10363
10341
|
await writeFile3(targetSettings, JSON.stringify(safeSettings, null, 2), "utf-8");
|
|
10364
10342
|
}
|
|
10365
10343
|
async function copyAllFromDefault(targetConfigDir, autoSync = false) {
|
|
10366
10344
|
const defaultDir = getDefaultClaudeDir();
|
|
10367
|
-
if (!
|
|
10345
|
+
if (!existsSync4(defaultDir)) {
|
|
10368
10346
|
throw new ClaudeMultiError(ErrorCode.DEFAULT_DIR_NOT_FOUND, "Default Claude directory not found");
|
|
10369
10347
|
}
|
|
10370
|
-
if (!
|
|
10348
|
+
if (!existsSync4(targetConfigDir)) {
|
|
10371
10349
|
await mkdir(targetConfigDir, { recursive: true });
|
|
10372
10350
|
}
|
|
10373
10351
|
const excludeFiles = [
|
|
@@ -10390,8 +10368,8 @@ async function copyAllFromDefault(targetConfigDir, autoSync = false) {
|
|
|
10390
10368
|
const copyRecursive = async (source, target) => {
|
|
10391
10369
|
const entries = readdirSync2(source);
|
|
10392
10370
|
for (const entry of entries) {
|
|
10393
|
-
const sourcePath =
|
|
10394
|
-
const targetPath =
|
|
10371
|
+
const sourcePath = join4(source, entry);
|
|
10372
|
+
const targetPath = join4(target, entry);
|
|
10395
10373
|
const stat = statSync(sourcePath);
|
|
10396
10374
|
if (excludeSet.has(entry)) {
|
|
10397
10375
|
continue;
|
|
@@ -10415,7 +10393,7 @@ async function copyAllFromDefault(targetConfigDir, autoSync = false) {
|
|
|
10415
10393
|
await symlink(sourcePath, targetPath, "dir");
|
|
10416
10394
|
console.log(` Symlinked: ${entry} -> ${sourcePath}`);
|
|
10417
10395
|
} else {
|
|
10418
|
-
if (!
|
|
10396
|
+
if (!existsSync4(targetPath)) {
|
|
10419
10397
|
await mkdir(targetPath, { recursive: true });
|
|
10420
10398
|
}
|
|
10421
10399
|
await copyRecursive(sourcePath, targetPath);
|
|
@@ -10428,11 +10406,11 @@ async function copyAllFromDefault(targetConfigDir, autoSync = false) {
|
|
|
10428
10406
|
await copyRecursive(defaultDir, targetConfigDir);
|
|
10429
10407
|
}
|
|
10430
10408
|
async function detectMcpConfigurations(configDir) {
|
|
10431
|
-
if (!
|
|
10409
|
+
if (!existsSync4(configDir)) {
|
|
10432
10410
|
return null;
|
|
10433
10411
|
}
|
|
10434
|
-
const settingsFile =
|
|
10435
|
-
if (
|
|
10412
|
+
const settingsFile = join4(configDir, "settings.json");
|
|
10413
|
+
if (existsSync4(settingsFile)) {
|
|
10436
10414
|
try {
|
|
10437
10415
|
const settingsContent = await readFile2(settingsFile, "utf-8");
|
|
10438
10416
|
const settings = JSON.parse(settingsContent);
|
|
@@ -10443,8 +10421,8 @@ async function detectMcpConfigurations(configDir) {
|
|
|
10443
10421
|
}
|
|
10444
10422
|
const mcpFiles = ["mcp.json", "mcp-servers.json", "claude-mcp.json"];
|
|
10445
10423
|
for (const mcpFile of mcpFiles) {
|
|
10446
|
-
const mcpFilePath =
|
|
10447
|
-
if (
|
|
10424
|
+
const mcpFilePath = join4(configDir, mcpFile);
|
|
10425
|
+
if (existsSync4(mcpFilePath)) {
|
|
10448
10426
|
try {
|
|
10449
10427
|
const mcpContent = await readFile2(mcpFilePath, "utf-8");
|
|
10450
10428
|
const mcpConfig = JSON.parse(mcpContent);
|
|
@@ -10463,12 +10441,12 @@ async function hasDefaultMcpConfig() {
|
|
|
10463
10441
|
}
|
|
10464
10442
|
async function copyMcpServersFromDefault(targetConfigDir) {
|
|
10465
10443
|
const defaultDir = getDefaultClaudeDir();
|
|
10466
|
-
if (!
|
|
10444
|
+
if (!existsSync4(targetConfigDir)) {
|
|
10467
10445
|
await mkdir(targetConfigDir, { recursive: true });
|
|
10468
10446
|
}
|
|
10469
|
-
const pluginsDir =
|
|
10470
|
-
const defaultPluginsDir =
|
|
10471
|
-
if (
|
|
10447
|
+
const pluginsDir = join4(targetConfigDir, "plugins");
|
|
10448
|
+
const defaultPluginsDir = join4(defaultDir, "plugins");
|
|
10449
|
+
if (existsSync4(defaultPluginsDir) && !existsSync4(pluginsDir)) {
|
|
10472
10450
|
await copyDirRecursive(defaultPluginsDir, pluginsDir);
|
|
10473
10451
|
}
|
|
10474
10452
|
const mcpConfig = await detectMcpConfigurations(defaultDir);
|
|
@@ -10488,8 +10466,8 @@ async function copyMcpServersFromDefault(targetConfigDir) {
|
|
|
10488
10466
|
}
|
|
10489
10467
|
}
|
|
10490
10468
|
async function writeMcpConfiguration(targetConfigDir, mcpConfig) {
|
|
10491
|
-
const settingsFile =
|
|
10492
|
-
if (
|
|
10469
|
+
const settingsFile = join4(targetConfigDir, "settings.json");
|
|
10470
|
+
if (existsSync4(settingsFile)) {
|
|
10493
10471
|
try {
|
|
10494
10472
|
const settingsContent = await readFile2(settingsFile, "utf-8");
|
|
10495
10473
|
const settings = JSON.parse(settingsContent);
|
|
@@ -10498,7 +10476,7 @@ async function writeMcpConfiguration(targetConfigDir, mcpConfig) {
|
|
|
10498
10476
|
return;
|
|
10499
10477
|
} catch {}
|
|
10500
10478
|
}
|
|
10501
|
-
const mcpFile =
|
|
10479
|
+
const mcpFile = join4(targetConfigDir, "mcp.json");
|
|
10502
10480
|
await writeFile3(mcpFile, JSON.stringify(mcpConfig, null, 2), "utf-8");
|
|
10503
10481
|
}
|
|
10504
10482
|
async function copyMcpServersBetweenInstances(sourceInstanceName, targetInstanceName) {
|
|
@@ -10527,18 +10505,18 @@ async function listMcpServers(instanceName) {
|
|
|
10527
10505
|
return mcpConfig?.mcpServers || null;
|
|
10528
10506
|
}
|
|
10529
10507
|
async function createSettingsFromTemplate(targetConfigDir, template, apiKey) {
|
|
10530
|
-
if (!
|
|
10508
|
+
if (!existsSync4(targetConfigDir)) {
|
|
10531
10509
|
await mkdir(targetConfigDir, { recursive: true });
|
|
10532
10510
|
}
|
|
10533
10511
|
const settings = applyProviderTemplate(template, apiKey);
|
|
10534
|
-
const settingsFile =
|
|
10512
|
+
const settingsFile = join4(targetConfigDir, "settings.json");
|
|
10535
10513
|
await writeFile3(settingsFile, JSON.stringify(settings, null, 2), "utf-8");
|
|
10536
10514
|
}
|
|
10537
10515
|
async function initializeInstanceState(configDir) {
|
|
10538
|
-
const stateFile =
|
|
10539
|
-
if (
|
|
10516
|
+
const stateFile = join4(configDir, ".claude.json");
|
|
10517
|
+
if (existsSync4(stateFile))
|
|
10540
10518
|
return;
|
|
10541
|
-
if (!
|
|
10519
|
+
if (!existsSync4(configDir)) {
|
|
10542
10520
|
await mkdir(configDir, { recursive: true });
|
|
10543
10521
|
}
|
|
10544
10522
|
const state = {
|
|
@@ -10561,9 +10539,9 @@ async function initializeInstanceState(configDir) {
|
|
|
10561
10539
|
await writeFile3(stateFile, JSON.stringify(state, null, 2), "utf-8");
|
|
10562
10540
|
}
|
|
10563
10541
|
async function mergeProviderEnv(configDir, template, apiKey) {
|
|
10564
|
-
const settingsFile =
|
|
10542
|
+
const settingsFile = join4(configDir, "settings.json");
|
|
10565
10543
|
let existing = {};
|
|
10566
|
-
if (
|
|
10544
|
+
if (existsSync4(settingsFile)) {
|
|
10567
10545
|
const raw = await readFile2(settingsFile, "utf-8");
|
|
10568
10546
|
existing = JSON.parse(raw);
|
|
10569
10547
|
}
|
|
@@ -10573,22 +10551,81 @@ async function mergeProviderEnv(configDir, template, apiKey) {
|
|
|
10573
10551
|
existing.includeCoAuthoredBy = template.settings.includeCoAuthoredBy;
|
|
10574
10552
|
await writeFile3(settingsFile, JSON.stringify(existing, null, 2), "utf-8");
|
|
10575
10553
|
}
|
|
10554
|
+
async function syncProviderTemplateForInstance(instance) {
|
|
10555
|
+
const providerName = instance.providerTemplate ?? detectProvider(instance.configDir);
|
|
10556
|
+
if (!providerName) {
|
|
10557
|
+
throw new ClaudeMultiError(ErrorCode.INSTANCE_NOT_FOUND, `Could not detect provider for '${instance.name}'`);
|
|
10558
|
+
}
|
|
10559
|
+
let template = getProviderTemplate(providerName);
|
|
10560
|
+
if (!template) {
|
|
10561
|
+
throw new ClaudeMultiError(ErrorCode.INSTANCE_NOT_FOUND, `Unknown provider template '${providerName}'`);
|
|
10562
|
+
}
|
|
10563
|
+
const settingsFile = join4(instance.configDir, "settings.json");
|
|
10564
|
+
if (!existsSync4(settingsFile)) {
|
|
10565
|
+
throw new ClaudeMultiError(ErrorCode.INSTANCE_DIR_NOT_FOUND, `No settings.json found for '${instance.name}'`);
|
|
10566
|
+
}
|
|
10567
|
+
const raw = JSON.parse(readFileSync4(settingsFile, "utf-8"));
|
|
10568
|
+
const existingEnv = raw.env ?? {};
|
|
10569
|
+
const apiKey = existingEnv.ANTHROPIC_AUTH_TOKEN ?? "";
|
|
10570
|
+
const existingBaseUrl = existingEnv.ANTHROPIC_BASE_URL;
|
|
10571
|
+
let resolvedRegion = null;
|
|
10572
|
+
if (providerHasRegions(providerName)) {
|
|
10573
|
+
const detectedRegion = existingBaseUrl ? detectRegionFromBaseUrl(existingBaseUrl) ?? instance.providerRegion : instance.providerRegion;
|
|
10574
|
+
if (detectedRegion) {
|
|
10575
|
+
const providerRegions = getProviderRegions(providerName);
|
|
10576
|
+
if (providerRegions && detectedRegion in providerRegions) {
|
|
10577
|
+
template = resolveRegionTemplate(template, detectedRegion);
|
|
10578
|
+
resolvedRegion = detectedRegion;
|
|
10579
|
+
}
|
|
10580
|
+
}
|
|
10581
|
+
}
|
|
10582
|
+
const templateSettings = structuredClone(template.settings);
|
|
10583
|
+
const newEnv = { ...templateSettings.env, ANTHROPIC_AUTH_TOKEN: apiKey };
|
|
10584
|
+
if (providerHasRegions(providerName) && !resolvedRegion && existingBaseUrl) {
|
|
10585
|
+
newEnv.ANTHROPIC_BASE_URL = existingBaseUrl;
|
|
10586
|
+
}
|
|
10587
|
+
for (const key of TUNABLE_ENV_VARS) {
|
|
10588
|
+
if (key in existingEnv && existingEnv[key] !== templateSettings.env[key]) {
|
|
10589
|
+
newEnv[key] = existingEnv[key];
|
|
10590
|
+
}
|
|
10591
|
+
}
|
|
10592
|
+
raw.env = { ...existingEnv, ...newEnv };
|
|
10593
|
+
raw.includeCoAuthoredBy = template.settings.includeCoAuthoredBy;
|
|
10594
|
+
raw.alwaysThinkingEnabled = template.settings.alwaysThinkingEnabled;
|
|
10595
|
+
writeFileSync2(settingsFile, JSON.stringify(raw, null, 2), "utf-8");
|
|
10596
|
+
let needsSave = false;
|
|
10597
|
+
const config = await loadConfig();
|
|
10598
|
+
const inst = config.instances.find((i) => i.name === instance.name);
|
|
10599
|
+
if (inst) {
|
|
10600
|
+
if (!inst.providerTemplate) {
|
|
10601
|
+
inst.providerTemplate = providerName;
|
|
10602
|
+
needsSave = true;
|
|
10603
|
+
}
|
|
10604
|
+
if (providerHasRegions(providerName) && resolvedRegion && !inst.providerRegion) {
|
|
10605
|
+
inst.providerRegion = resolvedRegion;
|
|
10606
|
+
needsSave = true;
|
|
10607
|
+
}
|
|
10608
|
+
if (needsSave) {
|
|
10609
|
+
await saveConfigAtomic(config);
|
|
10610
|
+
}
|
|
10611
|
+
}
|
|
10612
|
+
}
|
|
10576
10613
|
async function syncPluginsAndSkills(configDir) {
|
|
10577
10614
|
const defaultDir = getDefaultClaudeDir();
|
|
10578
|
-
if (!
|
|
10615
|
+
if (!existsSync4(configDir)) {
|
|
10579
10616
|
throw new ClaudeMultiError(ErrorCode.INSTANCE_DIR_NOT_FOUND, "Instance config directory does not exist");
|
|
10580
10617
|
}
|
|
10581
10618
|
await Promise.all(SYNC_DIRS.map(async (dir) => {
|
|
10582
|
-
const targetPath =
|
|
10583
|
-
const sourcePath =
|
|
10584
|
-
if (!
|
|
10619
|
+
const targetPath = join4(configDir, dir);
|
|
10620
|
+
const sourcePath = join4(defaultDir, dir);
|
|
10621
|
+
if (!existsSync4(sourcePath)) {
|
|
10585
10622
|
console.log(source_default.yellow(` ⚠ Source ${dir} not found in ${defaultDir}, skipping`));
|
|
10586
10623
|
return;
|
|
10587
10624
|
}
|
|
10588
|
-
if (
|
|
10625
|
+
if (existsSync4(targetPath)) {
|
|
10589
10626
|
try {
|
|
10590
10627
|
const linkTarget = readlinkSync(targetPath);
|
|
10591
|
-
if (linkTarget === sourcePath || linkTarget ===
|
|
10628
|
+
if (linkTarget === sourcePath || linkTarget === join4("..", "..", ".claude", dir)) {
|
|
10592
10629
|
console.log(source_default.gray(` ✓ ${dir} already synced`));
|
|
10593
10630
|
return;
|
|
10594
10631
|
}
|
|
@@ -10605,8 +10642,8 @@ async function syncPluginsAndSkills(configDir) {
|
|
|
10605
10642
|
async function copyFilesRecursive(source, target) {
|
|
10606
10643
|
const entries = readdirSync2(source);
|
|
10607
10644
|
await Promise.all(entries.map(async (entry) => {
|
|
10608
|
-
const sourceEntry =
|
|
10609
|
-
const targetEntry =
|
|
10645
|
+
const sourceEntry = join4(source, entry);
|
|
10646
|
+
const targetEntry = join4(target, entry);
|
|
10610
10647
|
const stat = statSync(sourceEntry);
|
|
10611
10648
|
if (stat.isDirectory()) {
|
|
10612
10649
|
await mkdir(targetEntry, { recursive: true });
|
|
@@ -10618,13 +10655,13 @@ async function copyFilesRecursive(source, target) {
|
|
|
10618
10655
|
}
|
|
10619
10656
|
async function unsyncPluginsAndSkills(configDir) {
|
|
10620
10657
|
const defaultDir = getDefaultClaudeDir();
|
|
10621
|
-
if (!
|
|
10658
|
+
if (!existsSync4(configDir)) {
|
|
10622
10659
|
throw new ClaudeMultiError(ErrorCode.INSTANCE_DIR_NOT_FOUND, "Instance config directory does not exist");
|
|
10623
10660
|
}
|
|
10624
10661
|
await Promise.all(SYNC_DIRS.map(async (dir) => {
|
|
10625
|
-
const targetPath =
|
|
10626
|
-
const sourcePath =
|
|
10627
|
-
if (!
|
|
10662
|
+
const targetPath = join4(configDir, dir);
|
|
10663
|
+
const sourcePath = join4(defaultDir, dir);
|
|
10664
|
+
if (!existsSync4(sourcePath)) {
|
|
10628
10665
|
console.log(source_default.yellow(` ⚠ Source ${dir} not found in ${defaultDir}, skipping`));
|
|
10629
10666
|
return;
|
|
10630
10667
|
}
|
|
@@ -10636,7 +10673,7 @@ async function unsyncPluginsAndSkills(configDir) {
|
|
|
10636
10673
|
if (isSymlink) {
|
|
10637
10674
|
rmSync2(targetPath, { force: true });
|
|
10638
10675
|
console.log(source_default.gray(` ✓ Removed symlink for ${dir}`));
|
|
10639
|
-
} else if (!
|
|
10676
|
+
} else if (!existsSync4(targetPath)) {} else {
|
|
10640
10677
|
console.log(source_default.yellow(` ⚠ ${dir} is already a regular directory, skipping`));
|
|
10641
10678
|
return;
|
|
10642
10679
|
}
|
|
@@ -10646,8 +10683,8 @@ async function unsyncPluginsAndSkills(configDir) {
|
|
|
10646
10683
|
}));
|
|
10647
10684
|
}
|
|
10648
10685
|
async function readClaudeSettings(configDir) {
|
|
10649
|
-
const settingsFile =
|
|
10650
|
-
if (!
|
|
10686
|
+
const settingsFile = join4(configDir, "settings.json");
|
|
10687
|
+
if (!existsSync4(settingsFile)) {
|
|
10651
10688
|
return null;
|
|
10652
10689
|
}
|
|
10653
10690
|
try {
|
|
@@ -10659,10 +10696,10 @@ async function readClaudeSettings(configDir) {
|
|
|
10659
10696
|
}
|
|
10660
10697
|
}
|
|
10661
10698
|
async function writeClaudeSettings(configDir, settings) {
|
|
10662
|
-
if (!
|
|
10699
|
+
if (!existsSync4(configDir)) {
|
|
10663
10700
|
await mkdir(configDir, { recursive: true });
|
|
10664
10701
|
}
|
|
10665
|
-
await writeJsonFileAtomic(
|
|
10702
|
+
await writeJsonFileAtomic(join4(configDir, "settings.json"), settings);
|
|
10666
10703
|
}
|
|
10667
10704
|
async function getEnabledPlugins(configDir) {
|
|
10668
10705
|
const settings = await readClaudeSettings(configDir);
|
|
@@ -10712,18 +10749,18 @@ function readMcpJsonFile(mcpPath) {
|
|
|
10712
10749
|
}
|
|
10713
10750
|
function scanPluginDir(baseDir, category, enabledPlugins) {
|
|
10714
10751
|
const subDir = category === PluginCategory.Internal ? "plugins" : "external_plugins";
|
|
10715
|
-
const dir =
|
|
10716
|
-
if (!
|
|
10752
|
+
const dir = join4(baseDir, MARKETPLACE_REL, subDir);
|
|
10753
|
+
if (!existsSync4(dir))
|
|
10717
10754
|
return [];
|
|
10718
10755
|
const results = [];
|
|
10719
10756
|
for (const entry of readdirSync2(dir, { withFileTypes: true })) {
|
|
10720
10757
|
if (!entry.isDirectory())
|
|
10721
10758
|
continue;
|
|
10722
|
-
const pluginPath =
|
|
10759
|
+
const pluginPath = join4(dir, entry.name);
|
|
10723
10760
|
let name = entry.name;
|
|
10724
10761
|
let description = "";
|
|
10725
|
-
const metaFile =
|
|
10726
|
-
if (
|
|
10762
|
+
const metaFile = join4(pluginPath, ".claude-plugin", "plugin.json");
|
|
10763
|
+
if (existsSync4(metaFile)) {
|
|
10727
10764
|
try {
|
|
10728
10765
|
const meta = JSON.parse(readFileSync4(metaFile, "utf-8"));
|
|
10729
10766
|
if (meta.name)
|
|
@@ -10734,8 +10771,8 @@ function scanPluginDir(baseDir, category, enabledPlugins) {
|
|
|
10734
10771
|
console.error(source_default.yellow(`Warning: Could not parse plugin metadata for ${entry.name}`));
|
|
10735
10772
|
}
|
|
10736
10773
|
}
|
|
10737
|
-
const mcpFile =
|
|
10738
|
-
const hasMcp =
|
|
10774
|
+
const mcpFile = join4(pluginPath, ".mcp.json");
|
|
10775
|
+
const hasMcp = existsSync4(mcpFile);
|
|
10739
10776
|
let mcpServerNames;
|
|
10740
10777
|
if (hasMcp) {
|
|
10741
10778
|
const servers = readMcpJsonFile(mcpFile);
|
|
@@ -10758,8 +10795,8 @@ function scanPluginDir(baseDir, category, enabledPlugins) {
|
|
|
10758
10795
|
}
|
|
10759
10796
|
function scanPluginsFromDir(baseDir) {
|
|
10760
10797
|
let enabledPlugins = {};
|
|
10761
|
-
const settingsFile =
|
|
10762
|
-
if (
|
|
10798
|
+
const settingsFile = join4(baseDir, "settings.json");
|
|
10799
|
+
if (existsSync4(settingsFile)) {
|
|
10763
10800
|
try {
|
|
10764
10801
|
const s = JSON.parse(readFileSync4(settingsFile, "utf-8"));
|
|
10765
10802
|
if (s.enabledPlugins)
|
|
@@ -10779,7 +10816,7 @@ function listInstancePlugins(configDir) {
|
|
|
10779
10816
|
return scanPluginsFromDir(configDir);
|
|
10780
10817
|
}
|
|
10781
10818
|
function isPluginsSymlinked(configDir) {
|
|
10782
|
-
const pluginsPath =
|
|
10819
|
+
const pluginsPath = join4(configDir, "plugins");
|
|
10783
10820
|
const st = lstatSafe(pluginsPath);
|
|
10784
10821
|
return st?.isSymbolicLink() ?? false;
|
|
10785
10822
|
}
|
|
@@ -10795,8 +10832,8 @@ function isClaudeCodeRunning(configDir) {
|
|
|
10795
10832
|
}
|
|
10796
10833
|
}
|
|
10797
10834
|
function readInstalledPlugins(pluginsDir) {
|
|
10798
|
-
const filePath =
|
|
10799
|
-
if (!
|
|
10835
|
+
const filePath = join4(pluginsDir, "installed_plugins.json");
|
|
10836
|
+
if (!existsSync4(filePath)) {
|
|
10800
10837
|
return { version: 2, plugins: {} };
|
|
10801
10838
|
}
|
|
10802
10839
|
try {
|
|
@@ -10806,16 +10843,16 @@ function readInstalledPlugins(pluginsDir) {
|
|
|
10806
10843
|
}
|
|
10807
10844
|
}
|
|
10808
10845
|
async function writeInstalledPlugins(pluginsDir, data) {
|
|
10809
|
-
await writeJsonFileAtomic(
|
|
10846
|
+
await writeJsonFileAtomic(join4(pluginsDir, "installed_plugins.json"), data);
|
|
10810
10847
|
}
|
|
10811
10848
|
async function addPluginToInstalledPlugins(configDir, pluginId) {
|
|
10812
|
-
const pluginsDir =
|
|
10849
|
+
const pluginsDir = join4(configDir, "plugins");
|
|
10813
10850
|
const data = readInstalledPlugins(pluginsDir);
|
|
10814
10851
|
const key = `${pluginId}@claude-plugins-official`;
|
|
10815
10852
|
if (!data.plugins[key]) {
|
|
10816
10853
|
data.plugins[key] = [];
|
|
10817
10854
|
}
|
|
10818
|
-
const cachePath =
|
|
10855
|
+
const cachePath = join4(configDir, MARKETPLACE_REL);
|
|
10819
10856
|
const entry = {
|
|
10820
10857
|
scope: "user",
|
|
10821
10858
|
installPath: cachePath,
|
|
@@ -10827,7 +10864,7 @@ async function addPluginToInstalledPlugins(configDir, pluginId) {
|
|
|
10827
10864
|
await writeInstalledPlugins(pluginsDir, data);
|
|
10828
10865
|
}
|
|
10829
10866
|
async function removePluginFromInstalledPlugins(configDir, pluginId) {
|
|
10830
|
-
const pluginsDir =
|
|
10867
|
+
const pluginsDir = join4(configDir, "plugins");
|
|
10831
10868
|
const data = readInstalledPlugins(pluginsDir);
|
|
10832
10869
|
const key = `${pluginId}@claude-plugins-official`;
|
|
10833
10870
|
delete data.plugins[key];
|
|
@@ -10837,7 +10874,7 @@ function estimatePluginSize(pluginPath) {
|
|
|
10837
10874
|
let total = 0;
|
|
10838
10875
|
try {
|
|
10839
10876
|
for (const entry of readdirSync2(pluginPath, { withFileTypes: true })) {
|
|
10840
|
-
const fullPath =
|
|
10877
|
+
const fullPath = join4(pluginPath, entry.name);
|
|
10841
10878
|
if (entry.isDirectory()) {
|
|
10842
10879
|
total += estimatePluginSize(fullPath);
|
|
10843
10880
|
} else {
|
|
@@ -10855,8 +10892,8 @@ function detectMcpCollisions(configDir, newPluginIds) {
|
|
|
10855
10892
|
const defaultDir = getDefaultClaudeDir();
|
|
10856
10893
|
for (const pluginId of newPluginIds) {
|
|
10857
10894
|
for (const subDir of ["plugins", "external_plugins"]) {
|
|
10858
|
-
const mcpFile =
|
|
10859
|
-
if (!
|
|
10895
|
+
const mcpFile = join4(defaultDir, MARKETPLACE_REL, subDir, pluginId, ".mcp.json");
|
|
10896
|
+
if (!existsSync4(mcpFile))
|
|
10860
10897
|
continue;
|
|
10861
10898
|
const newServers = readMcpJsonFile(mcpFile);
|
|
10862
10899
|
for (const name of Object.keys(newServers)) {
|
|
@@ -10875,10 +10912,10 @@ function detectMcpCollisions(configDir, newPluginIds) {
|
|
|
10875
10912
|
function validatePluginOperation(configDir, operation, pluginId) {
|
|
10876
10913
|
const errors = [];
|
|
10877
10914
|
const warnings = [];
|
|
10878
|
-
if (!
|
|
10915
|
+
if (!existsSync4(configDir)) {
|
|
10879
10916
|
errors.push("Instance config directory does not exist");
|
|
10880
10917
|
}
|
|
10881
|
-
if (
|
|
10918
|
+
if (existsSync4(configDir) && isPluginsSymlinked(configDir)) {
|
|
10882
10919
|
errors.push("Plugins directory is symlinked (auto-sync). Disable auto-sync first.");
|
|
10883
10920
|
}
|
|
10884
10921
|
if (operation === PluginAction.Install && pluginId) {
|
|
@@ -10893,7 +10930,7 @@ function validatePluginOperation(configDir, operation, pluginId) {
|
|
|
10893
10930
|
errors.push(`Plugin '${pluginId}' not installed in this instance`);
|
|
10894
10931
|
}
|
|
10895
10932
|
}
|
|
10896
|
-
if (operation === PluginAction.Install && pluginId &&
|
|
10933
|
+
if (operation === PluginAction.Install && pluginId && existsSync4(configDir)) {
|
|
10897
10934
|
const collisions = detectMcpCollisions(configDir, [pluginId]);
|
|
10898
10935
|
for (const c of collisions) {
|
|
10899
10936
|
warnings.push(`MCP server name collision: '${c.serverName}'`);
|
|
@@ -10904,27 +10941,27 @@ function validatePluginOperation(configDir, operation, pluginId) {
|
|
|
10904
10941
|
async function copySinglePlugin(targetConfigDir, pluginId, category) {
|
|
10905
10942
|
const defaultDir = getDefaultClaudeDir();
|
|
10906
10943
|
const subDir = category === PluginCategory.Internal ? "plugins" : "external_plugins";
|
|
10907
|
-
const sourcePlugin =
|
|
10908
|
-
const targetPlugin =
|
|
10909
|
-
if (!
|
|
10944
|
+
const sourcePlugin = join4(defaultDir, MARKETPLACE_REL, subDir, pluginId);
|
|
10945
|
+
const targetPlugin = join4(targetConfigDir, MARKETPLACE_REL, subDir, pluginId);
|
|
10946
|
+
if (!existsSync4(sourcePlugin)) {
|
|
10910
10947
|
throw new ClaudeMultiError(ErrorCode.PLUGIN_NOT_FOUND, `Plugin '${pluginId}' not found in default Claude`);
|
|
10911
10948
|
}
|
|
10912
|
-
const scaffoldDir =
|
|
10913
|
-
if (!
|
|
10949
|
+
const scaffoldDir = join4(targetConfigDir, MARKETPLACE_REL, subDir);
|
|
10950
|
+
if (!existsSync4(scaffoldDir)) {
|
|
10914
10951
|
await mkdir(scaffoldDir, { recursive: true });
|
|
10915
10952
|
}
|
|
10916
|
-
const marketplaceDir =
|
|
10917
|
-
if (!
|
|
10953
|
+
const marketplaceDir = join4(targetConfigDir, MARKETPLACE_REL);
|
|
10954
|
+
if (!existsSync4(marketplaceDir)) {
|
|
10918
10955
|
await mkdir(marketplaceDir, { recursive: true });
|
|
10919
10956
|
}
|
|
10920
10957
|
for (const metaFile of ["known_marketplaces.json", "blocklist.json"]) {
|
|
10921
|
-
const src =
|
|
10922
|
-
const tgt =
|
|
10923
|
-
if (
|
|
10958
|
+
const src = join4(defaultDir, MARKETPLACE_REL, metaFile);
|
|
10959
|
+
const tgt = join4(marketplaceDir, metaFile);
|
|
10960
|
+
if (existsSync4(src) && !existsSync4(tgt)) {
|
|
10924
10961
|
await copyFile(src, tgt);
|
|
10925
10962
|
}
|
|
10926
10963
|
}
|
|
10927
|
-
if (
|
|
10964
|
+
if (existsSync4(targetPlugin)) {
|
|
10928
10965
|
rmSync2(targetPlugin, { force: true, recursive: true });
|
|
10929
10966
|
}
|
|
10930
10967
|
await copyDirRecursive(sourcePlugin, targetPlugin);
|
|
@@ -10943,15 +10980,15 @@ async function copySelectedPlugins(targetConfigDir, selections) {
|
|
|
10943
10980
|
const defaultDir = getDefaultClaudeDir();
|
|
10944
10981
|
for (const sel of selections) {
|
|
10945
10982
|
const subDir = sel.category === PluginCategory.Internal ? "plugins" : "external_plugins";
|
|
10946
|
-
const source =
|
|
10947
|
-
if (!
|
|
10983
|
+
const source = join4(defaultDir, MARKETPLACE_REL, subDir, sel.id);
|
|
10984
|
+
if (!existsSync4(source)) {
|
|
10948
10985
|
throw new ClaudeMultiError(ErrorCode.PLUGIN_NOT_FOUND, `Plugin '${sel.id}' not found in default Claude`);
|
|
10949
10986
|
}
|
|
10950
10987
|
}
|
|
10951
10988
|
let totalSize = 0;
|
|
10952
10989
|
for (const sel of selections) {
|
|
10953
10990
|
const subDir = sel.category === PluginCategory.Internal ? "plugins" : "external_plugins";
|
|
10954
|
-
totalSize += estimatePluginSize(
|
|
10991
|
+
totalSize += estimatePluginSize(join4(defaultDir, MARKETPLACE_REL, subDir, sel.id));
|
|
10955
10992
|
}
|
|
10956
10993
|
if (totalSize > 104857600) {
|
|
10957
10994
|
throw new ClaudeMultiError(ErrorCode.PLUGIN_TOO_LARGE, `Selected plugins total ${(totalSize / 1024 / 1024).toFixed(1)}MB. Ensure sufficient disk space.`);
|
|
@@ -10966,8 +11003,8 @@ async function copySelectedPlugins(targetConfigDir, selections) {
|
|
|
10966
11003
|
for (const done of completed) {
|
|
10967
11004
|
try {
|
|
10968
11005
|
const subDir = done.category === PluginCategory.Internal ? "plugins" : "external_plugins";
|
|
10969
|
-
const targetPath =
|
|
10970
|
-
if (
|
|
11006
|
+
const targetPath = join4(targetConfigDir, MARKETPLACE_REL, subDir, done.id);
|
|
11007
|
+
if (existsSync4(targetPath)) {
|
|
10971
11008
|
rmSync2(targetPath, { force: true, recursive: true });
|
|
10972
11009
|
}
|
|
10973
11010
|
await removePluginFromInstalledPlugins(targetConfigDir, done.id);
|
|
@@ -10983,8 +11020,8 @@ async function removeSinglePlugin(configDir, pluginId, category) {
|
|
|
10983
11020
|
throw new ClaudeMultiError(ErrorCode.SYMLINK_CONFLICT, "Cannot remove plugins from a symlinked instance. Disable auto-sync first.");
|
|
10984
11021
|
}
|
|
10985
11022
|
const subDir = category === PluginCategory.Internal ? "plugins" : "external_plugins";
|
|
10986
|
-
const pluginPath =
|
|
10987
|
-
if (!
|
|
11023
|
+
const pluginPath = join4(configDir, MARKETPLACE_REL, subDir, pluginId);
|
|
11024
|
+
if (!existsSync4(pluginPath)) {
|
|
10988
11025
|
throw new ClaudeMultiError(ErrorCode.PLUGIN_NOT_FOUND, `Plugin '${pluginId}' not found in this instance`);
|
|
10989
11026
|
}
|
|
10990
11027
|
const backupPath = pluginPath + ".removing";
|
|
@@ -11007,16 +11044,16 @@ async function removeSinglePlugin(configDir, pluginId, category) {
|
|
|
11007
11044
|
}
|
|
11008
11045
|
function getMcpServersFromPlugins(configDir) {
|
|
11009
11046
|
const result = {};
|
|
11010
|
-
const basePlugins =
|
|
11047
|
+
const basePlugins = join4(configDir, MARKETPLACE_REL);
|
|
11011
11048
|
for (const subDir of ["plugins", "external_plugins"]) {
|
|
11012
|
-
const dir =
|
|
11013
|
-
if (!
|
|
11049
|
+
const dir = join4(basePlugins, subDir);
|
|
11050
|
+
if (!existsSync4(dir))
|
|
11014
11051
|
continue;
|
|
11015
11052
|
for (const entry of readdirSync2(dir, { withFileTypes: true })) {
|
|
11016
11053
|
if (!entry.isDirectory())
|
|
11017
11054
|
continue;
|
|
11018
|
-
const mcpFile =
|
|
11019
|
-
if (!
|
|
11055
|
+
const mcpFile = join4(dir, entry.name, ".mcp.json");
|
|
11056
|
+
if (!existsSync4(mcpFile))
|
|
11020
11057
|
continue;
|
|
11021
11058
|
const servers = readMcpJsonFile(mcpFile);
|
|
11022
11059
|
Object.assign(result, servers);
|
|
@@ -11051,6 +11088,7 @@ var init_config = __esm(() => {
|
|
|
11051
11088
|
init_json_file();
|
|
11052
11089
|
init_errors();
|
|
11053
11090
|
init_constants();
|
|
11091
|
+
init_env();
|
|
11054
11092
|
init_source();
|
|
11055
11093
|
SYNC_DIRS = ["plugins", "skills"];
|
|
11056
11094
|
});
|
|
@@ -33330,7 +33368,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
33330
33368
|
return 0;
|
|
33331
33369
|
};
|
|
33332
33370
|
var validate2 = function validate3(version) {
|
|
33333
|
-
return typeof version === "string" && /^[v\d]/.test(version) &&
|
|
33371
|
+
return typeof version === "string" && /^[v\d]/.test(version) && semver2.test(version);
|
|
33334
33372
|
};
|
|
33335
33373
|
var compare = function compare2(v1, v2, operator) {
|
|
33336
33374
|
assertValidOperator(operator);
|
|
@@ -33364,12 +33402,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
33364
33402
|
return false;
|
|
33365
33403
|
return true;
|
|
33366
33404
|
};
|
|
33367
|
-
var
|
|
33405
|
+
var semver2 = /^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\-]+(?:\.[\da-z\-]+)*))?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;
|
|
33368
33406
|
var validateAndParse = function validateAndParse2(version) {
|
|
33369
33407
|
if (typeof version !== "string") {
|
|
33370
33408
|
throw new TypeError("Invalid argument expected string");
|
|
33371
33409
|
}
|
|
33372
|
-
var match = version.match(
|
|
33410
|
+
var match = version.match(semver2);
|
|
33373
33411
|
if (!match) {
|
|
33374
33412
|
throw new Error("Invalid argument not valid semver ('".concat(version, "' received)"));
|
|
33375
33413
|
}
|
|
@@ -56046,6 +56084,18 @@ function useConfig() {
|
|
|
56046
56084
|
}
|
|
56047
56085
|
await reload();
|
|
56048
56086
|
}, [reload]);
|
|
56087
|
+
const syncTemplateEnv = import_react66.useCallback(async (instance) => {
|
|
56088
|
+
await syncProviderTemplateForInstance(instance);
|
|
56089
|
+
await reload();
|
|
56090
|
+
}, [reload]);
|
|
56091
|
+
const regenerateWrapper = import_react66.useCallback(async (instance) => {
|
|
56092
|
+
await createWrapper({
|
|
56093
|
+
name: instance.name,
|
|
56094
|
+
configDir: instance.configDir,
|
|
56095
|
+
binaryPath: instance.binaryPath
|
|
56096
|
+
});
|
|
56097
|
+
await reload();
|
|
56098
|
+
}, [reload]);
|
|
56049
56099
|
const migrationStatus = config ? getMigrationStatus(config) : null;
|
|
56050
56100
|
return {
|
|
56051
56101
|
config,
|
|
@@ -56056,6 +56106,8 @@ function useConfig() {
|
|
|
56056
56106
|
addInstance: addInstance2,
|
|
56057
56107
|
removeInstance: removeInstance2,
|
|
56058
56108
|
toggleAutoSync,
|
|
56109
|
+
syncTemplateEnv,
|
|
56110
|
+
regenerateWrapper,
|
|
56059
56111
|
migrationStatus,
|
|
56060
56112
|
instanceMigrationVersion: config?.instanceMigrationVersion,
|
|
56061
56113
|
getInstance,
|
|
@@ -56125,7 +56177,7 @@ var exports_AddInstance = {};
|
|
|
56125
56177
|
__export(exports_AddInstance, {
|
|
56126
56178
|
AddInstance: () => AddInstance
|
|
56127
56179
|
});
|
|
56128
|
-
import { join as
|
|
56180
|
+
import { join as join6 } from "node:path";
|
|
56129
56181
|
import { homedir as homedir3 } from "node:os";
|
|
56130
56182
|
function stepNumber(step) {
|
|
56131
56183
|
return STEP_FLOW.indexOf(step) + 1;
|
|
@@ -56169,6 +56221,9 @@ function reducer5(state, action) {
|
|
|
56169
56221
|
case "SET_ERROR":
|
|
56170
56222
|
return { ...state, error: action.error };
|
|
56171
56223
|
case "SELECT_PROVIDER":
|
|
56224
|
+
if (!action.provider || !providerHasRegions(action.provider)) {
|
|
56225
|
+
return { ...state, selectedProvider: action.provider, useProvider: action.useProvider, selectedRegion: null };
|
|
56226
|
+
}
|
|
56172
56227
|
return { ...state, selectedProvider: action.provider, useProvider: action.useProvider };
|
|
56173
56228
|
case "SET_REGION":
|
|
56174
56229
|
return { ...state, selectedRegion: action.region };
|
|
@@ -56291,34 +56346,37 @@ var import_react67, jsx_dev_runtime4, AddResult = ({
|
|
|
56291
56346
|
onChange: onSelect
|
|
56292
56347
|
}, undefined, false, undefined, this)
|
|
56293
56348
|
]
|
|
56294
|
-
}, undefined, true, undefined, this), ProviderRegionStep = ({ state, onSelect }) =>
|
|
56295
|
-
|
|
56296
|
-
|
|
56297
|
-
|
|
56298
|
-
|
|
56299
|
-
|
|
56300
|
-
|
|
56301
|
-
|
|
56302
|
-
|
|
56303
|
-
|
|
56304
|
-
|
|
56305
|
-
|
|
56306
|
-
|
|
56307
|
-
|
|
56308
|
-
|
|
56349
|
+
}, undefined, true, undefined, this), ProviderRegionStep = ({ state, onSelect }) => {
|
|
56350
|
+
const regions = state.selectedProvider ? getProviderRegions(state.selectedProvider) : undefined;
|
|
56351
|
+
return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
|
|
56352
|
+
flexDirection: "column",
|
|
56353
|
+
gap: 1,
|
|
56354
|
+
children: [
|
|
56355
|
+
/* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
|
|
56356
|
+
children: "Select your subscription region:"
|
|
56357
|
+
}, undefined, false, undefined, this),
|
|
56358
|
+
/* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
|
|
56359
|
+
borderStyle: "round",
|
|
56360
|
+
borderColor: "yellow",
|
|
56361
|
+
paddingX: 1,
|
|
56362
|
+
children: /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
|
|
56363
|
+
bold: true,
|
|
56364
|
+
color: "yellow",
|
|
56365
|
+
children: "Check your account console to confirm the correct region for your subscription."
|
|
56366
|
+
}, undefined, false, undefined, this)
|
|
56367
|
+
}, undefined, false, undefined, this),
|
|
56368
|
+
/* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Select, {
|
|
56369
|
+
options: regions ? Object.entries(regions).map(([key, val]) => ({
|
|
56370
|
+
label: `${val.label} — ${val.baseUrl}`,
|
|
56371
|
+
value: key
|
|
56372
|
+
})) : [],
|
|
56373
|
+
visibleOptionCount: 3,
|
|
56374
|
+
defaultValue: state.selectedRegion ?? undefined,
|
|
56375
|
+
onChange: onSelect
|
|
56309
56376
|
}, undefined, false, undefined, this)
|
|
56310
|
-
|
|
56311
|
-
|
|
56312
|
-
|
|
56313
|
-
label: `${val.label} — ${val.baseUrl}`,
|
|
56314
|
-
value: key
|
|
56315
|
-
})),
|
|
56316
|
-
visibleOptionCount: 3,
|
|
56317
|
-
defaultValue: state.selectedRegion ?? undefined,
|
|
56318
|
-
onChange: onSelect
|
|
56319
|
-
}, undefined, false, undefined, this)
|
|
56320
|
-
]
|
|
56321
|
-
}, undefined, true, undefined, this), ProviderApiKeyStep = ({ state, onSubmit }) => /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
|
|
56377
|
+
]
|
|
56378
|
+
}, undefined, true, undefined, this);
|
|
56379
|
+
}, ProviderApiKeyStep = ({ state, onSubmit }) => /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
|
|
56322
56380
|
flexDirection: "column",
|
|
56323
56381
|
gap: 1,
|
|
56324
56382
|
children: [
|
|
@@ -56345,7 +56403,7 @@ var import_react67, jsx_dev_runtime4, AddResult = ({
|
|
|
56345
56403
|
dimColor: true,
|
|
56346
56404
|
children: [
|
|
56347
56405
|
"Config: ",
|
|
56348
|
-
|
|
56406
|
+
join6(homedir3(), `.claude-${state.name}`)
|
|
56349
56407
|
]
|
|
56350
56408
|
}, undefined, true, undefined, this),
|
|
56351
56409
|
/* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
|
|
@@ -56475,7 +56533,7 @@ var import_react67, jsx_dev_runtime4, AddResult = ({
|
|
|
56475
56533
|
dispatch({ type: "SET_STEP", step: "creating" /* Creating */ });
|
|
56476
56534
|
dispatch({ type: "SET_ERROR", error: "" });
|
|
56477
56535
|
try {
|
|
56478
|
-
const cDir =
|
|
56536
|
+
const cDir = join6(homedir3(), `.claude-${state.name}`);
|
|
56479
56537
|
const bPath = cfg.getDefaultBinaryPath(state.name);
|
|
56480
56538
|
const instance = {
|
|
56481
56539
|
name: state.name,
|
|
@@ -56483,7 +56541,9 @@ var import_react67, jsx_dev_runtime4, AddResult = ({
|
|
|
56483
56541
|
binaryPath: bPath,
|
|
56484
56542
|
createdAt: new Date().toISOString(),
|
|
56485
56543
|
autoSync: sync,
|
|
56486
|
-
createdWithVersion: getClaudeMultiVersion()
|
|
56544
|
+
createdWithVersion: getClaudeMultiVersion(),
|
|
56545
|
+
...state.useProvider && state.selectedProvider ? { providerTemplate: state.selectedProvider } : {},
|
|
56546
|
+
...state.selectedRegion && state.useProvider && state.selectedProvider && providerHasRegions(state.selectedProvider) ? { providerRegion: state.selectedRegion } : {}
|
|
56487
56547
|
};
|
|
56488
56548
|
await cfg.addInstance(instance);
|
|
56489
56549
|
await Promise.all([
|
|
@@ -56717,10 +56777,11 @@ __export(exports_health, {
|
|
|
56717
56777
|
dismissIssue: () => dismissIssue,
|
|
56718
56778
|
dismissAllIssues: () => dismissAllIssues
|
|
56719
56779
|
});
|
|
56720
|
-
import { existsSync as
|
|
56721
|
-
import {
|
|
56780
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, renameSync as renameSync2, unlinkSync as unlinkSync2 } from "node:fs";
|
|
56781
|
+
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
56782
|
+
import { join as join7 } from "node:path";
|
|
56722
56783
|
function getHealthFile() {
|
|
56723
|
-
return
|
|
56784
|
+
return join7(getBaseDir(), ".claude-multi", "health-status.json");
|
|
56724
56785
|
}
|
|
56725
56786
|
function runHealthChecks(instances2, migrationStatus, instanceMigrationVersion) {
|
|
56726
56787
|
const now2 = new Date().toISOString();
|
|
@@ -56757,7 +56818,7 @@ function runHealthChecks(instances2, migrationStatus, instanceMigrationVersion)
|
|
|
56757
56818
|
});
|
|
56758
56819
|
}
|
|
56759
56820
|
for (const inst of instances2) {
|
|
56760
|
-
if (!
|
|
56821
|
+
if (!existsSync6(inst.configDir)) {
|
|
56761
56822
|
issues.push({
|
|
56762
56823
|
id: `configdir-missing-${inst.name}`,
|
|
56763
56824
|
severity: "error",
|
|
@@ -56773,7 +56834,7 @@ function runHealthChecks(instances2, migrationStatus, instanceMigrationVersion)
|
|
|
56773
56834
|
});
|
|
56774
56835
|
continue;
|
|
56775
56836
|
}
|
|
56776
|
-
if (!
|
|
56837
|
+
if (!existsSync6(inst.binaryPath)) {
|
|
56777
56838
|
issues.push({
|
|
56778
56839
|
id: `binary-missing-${inst.name}`,
|
|
56779
56840
|
severity: "warning",
|
|
@@ -56788,10 +56849,11 @@ function runHealthChecks(instances2, migrationStatus, instanceMigrationVersion)
|
|
|
56788
56849
|
resolutionHint: "Re-create the instance or run 'claude-multi sync'"
|
|
56789
56850
|
});
|
|
56790
56851
|
}
|
|
56791
|
-
const settingsFile =
|
|
56792
|
-
if (
|
|
56852
|
+
const settingsFile = join7(inst.configDir, "settings.json");
|
|
56853
|
+
if (existsSync6(settingsFile)) {
|
|
56854
|
+
let parsed = null;
|
|
56793
56855
|
try {
|
|
56794
|
-
JSON.parse(readFileSync6(settingsFile, "utf-8"));
|
|
56856
|
+
parsed = JSON.parse(readFileSync6(settingsFile, "utf-8"));
|
|
56795
56857
|
} catch {
|
|
56796
56858
|
issues.push({
|
|
56797
56859
|
id: `settings-corrupt-${inst.name}`,
|
|
@@ -56807,6 +56869,29 @@ function runHealthChecks(instances2, migrationStatus, instanceMigrationVersion)
|
|
|
56807
56869
|
resolutionHint: "Fix or delete the corrupted settings.json"
|
|
56808
56870
|
});
|
|
56809
56871
|
}
|
|
56872
|
+
if (parsed && inst.providerTemplate && providerHasRegions(inst.providerTemplate)) {
|
|
56873
|
+
const env3 = parsed.env;
|
|
56874
|
+
const actualUrl = env3?.ANTHROPIC_BASE_URL;
|
|
56875
|
+
const actualRegion = actualUrl ? detectRegionFromBaseUrl(actualUrl) : null;
|
|
56876
|
+
if (inst.providerRegion && actualRegion && inst.providerRegion !== actualRegion) {
|
|
56877
|
+
const providerRegions = getProviderRegions(inst.providerTemplate);
|
|
56878
|
+
const expectedUrl = providerRegions?.[inst.providerRegion]?.baseUrl;
|
|
56879
|
+
issues.push({
|
|
56880
|
+
id: `region-mismatch-${inst.name}`,
|
|
56881
|
+
severity: "warning",
|
|
56882
|
+
category: "settings",
|
|
56883
|
+
title: "Region URL mismatch",
|
|
56884
|
+
message: `Instance '${inst.name}' stored region is ${inst.providerRegion} but base URL points to ${actualRegion}`,
|
|
56885
|
+
detail: `Stored region: ${inst.providerRegion} (${expectedUrl})
|
|
56886
|
+
Actual URL: ${actualUrl}`,
|
|
56887
|
+
instanceName: inst.name,
|
|
56888
|
+
timestamp: now2,
|
|
56889
|
+
dismissed: false,
|
|
56890
|
+
resolved: false,
|
|
56891
|
+
resolutionHint: `Edit settings.json to set ANTHROPIC_BASE_URL to ${expectedUrl}, or run 'claude-multi doctor fix'`
|
|
56892
|
+
});
|
|
56893
|
+
}
|
|
56894
|
+
}
|
|
56810
56895
|
}
|
|
56811
56896
|
const symlinks = detectBrokenSymlinks(inst.configDir);
|
|
56812
56897
|
if (symlinks.broken.length > 0) {
|
|
@@ -56824,13 +56909,15 @@ function runHealthChecks(instances2, migrationStatus, instanceMigrationVersion)
|
|
|
56824
56909
|
resolutionHint: "Re-sync symlinks from the home screen"
|
|
56825
56910
|
});
|
|
56826
56911
|
}
|
|
56827
|
-
|
|
56912
|
+
const expectedClaudePath = tryGetClaudePath();
|
|
56913
|
+
if (existsSync6(inst.binaryPath) && expectedClaudePath) {
|
|
56828
56914
|
try {
|
|
56829
56915
|
const wrapperContent = readFileSync6(inst.binaryPath, "utf-8");
|
|
56830
56916
|
const shellMatch = wrapperContent.match(/exec\s+"([^"]+)"/);
|
|
56917
|
+
const cmdMatch = wrapperContent.match(/"([^"]+)"\s+%\*/);
|
|
56831
56918
|
const nodeMatch = wrapperContent.match(/spawn\("([^"]+)"/);
|
|
56832
|
-
const currentBin = shellMatch?.[1] ?? nodeMatch?.[1];
|
|
56833
|
-
if (currentBin && currentBin !==
|
|
56919
|
+
const currentBin = shellMatch?.[1] ?? cmdMatch?.[1] ?? nodeMatch?.[1];
|
|
56920
|
+
if (currentBin && currentBin !== expectedClaudePath) {
|
|
56834
56921
|
issues.push({
|
|
56835
56922
|
id: `wrong-claude-version-${inst.name}`,
|
|
56836
56923
|
severity: "error",
|
|
@@ -56838,7 +56925,7 @@ function runHealthChecks(instances2, migrationStatus, instanceMigrationVersion)
|
|
|
56838
56925
|
title: "Wrong Claude binary",
|
|
56839
56926
|
message: `Instance '${inst.name}' uses a Claude version that may break 3rd-party providers`,
|
|
56840
56927
|
detail: `Current: ${currentBin}
|
|
56841
|
-
Expected: ${
|
|
56928
|
+
Expected: ${expectedClaudePath}`,
|
|
56842
56929
|
instanceName: inst.name,
|
|
56843
56930
|
timestamp: now2,
|
|
56844
56931
|
dismissed: false,
|
|
@@ -56868,7 +56955,7 @@ Expected: ${PINNED_CLAUDE_BIN}`,
|
|
|
56868
56955
|
}
|
|
56869
56956
|
function loadHealthStatus() {
|
|
56870
56957
|
const healthFile = getHealthFile();
|
|
56871
|
-
if (!
|
|
56958
|
+
if (!existsSync6(healthFile)) {
|
|
56872
56959
|
return { lastChecked: "", issues: [] };
|
|
56873
56960
|
}
|
|
56874
56961
|
try {
|
|
@@ -56878,10 +56965,21 @@ function loadHealthStatus() {
|
|
|
56878
56965
|
}
|
|
56879
56966
|
}
|
|
56880
56967
|
function saveHealthStatus(status) {
|
|
56881
|
-
const dir =
|
|
56882
|
-
if (!
|
|
56883
|
-
|
|
56884
|
-
|
|
56968
|
+
const dir = join7(getBaseDir(), ".claude-multi");
|
|
56969
|
+
if (!existsSync6(dir))
|
|
56970
|
+
mkdirSync4(dir, { recursive: true });
|
|
56971
|
+
const healthFile = getHealthFile();
|
|
56972
|
+
const tmpPath = `${healthFile}.tmp.${randomBytes3(4).toString("hex")}`;
|
|
56973
|
+
try {
|
|
56974
|
+
writeFileSync3(tmpPath, JSON.stringify(status, null, 2), "utf-8");
|
|
56975
|
+
JSON.parse(readFileSync6(tmpPath, "utf-8"));
|
|
56976
|
+
renameSync2(tmpPath, healthFile);
|
|
56977
|
+
} catch (err) {
|
|
56978
|
+
try {
|
|
56979
|
+
unlinkSync2(tmpPath);
|
|
56980
|
+
} catch {}
|
|
56981
|
+
throw err;
|
|
56982
|
+
}
|
|
56885
56983
|
}
|
|
56886
56984
|
function dismissIssue(id) {
|
|
56887
56985
|
const status = loadHealthStatus();
|
|
@@ -56899,20 +56997,22 @@ function dismissAllIssues() {
|
|
|
56899
56997
|
saveHealthStatus(status);
|
|
56900
56998
|
}
|
|
56901
56999
|
function fixWrapperVersions(instances2) {
|
|
56902
|
-
|
|
57000
|
+
const expectedClaudePath = tryGetClaudePath();
|
|
57001
|
+
if (!expectedClaudePath)
|
|
56903
57002
|
return [];
|
|
56904
57003
|
const fixed = [];
|
|
56905
57004
|
for (const inst of instances2) {
|
|
56906
|
-
if (!
|
|
57005
|
+
if (!existsSync6(inst.binaryPath))
|
|
56907
57006
|
continue;
|
|
56908
57007
|
try {
|
|
56909
57008
|
const content = readFileSync6(inst.binaryPath, "utf-8");
|
|
56910
57009
|
const shellMatch = content.match(/exec\s+"([^"]+)"/);
|
|
57010
|
+
const cmdMatch = content.match(/"([^"]+)"\s+%\*/);
|
|
56911
57011
|
const nodeMatch = content.match(/spawn\("([^"]+)"/);
|
|
56912
|
-
const currentBin = shellMatch?.[1] ?? nodeMatch?.[1];
|
|
56913
|
-
if (!currentBin || currentBin ===
|
|
57012
|
+
const currentBin = shellMatch?.[1] ?? cmdMatch?.[1] ?? nodeMatch?.[1];
|
|
57013
|
+
if (!currentBin || currentBin === expectedClaudePath)
|
|
56914
57014
|
continue;
|
|
56915
|
-
const newContent = buildWrapperScript(inst,
|
|
57015
|
+
const newContent = buildWrapperScript(inst, expectedClaudePath);
|
|
56916
57016
|
if (content !== newContent) {
|
|
56917
57017
|
writeFileSync3(inst.binaryPath, newContent, { mode: 493 });
|
|
56918
57018
|
}
|
|
@@ -56928,6 +57028,7 @@ var init_health = __esm(() => {
|
|
|
56928
57028
|
init_version();
|
|
56929
57029
|
init_migration();
|
|
56930
57030
|
init_wrapper();
|
|
57031
|
+
init_templates();
|
|
56931
57032
|
});
|
|
56932
57033
|
|
|
56933
57034
|
// src/ink/components/Footer.tsx
|
|
@@ -57071,12 +57172,12 @@ var jsx_dev_runtime6, WarningBanner = ({
|
|
|
57071
57172
|
children: [
|
|
57072
57173
|
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
|
|
57073
57174
|
color: "red",
|
|
57074
|
-
children: " ⚠ Some instances
|
|
57175
|
+
children: " ⚠ Some instances have version issues. "
|
|
57075
57176
|
}, undefined, false, undefined, this),
|
|
57076
57177
|
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
|
|
57077
57178
|
color: "red",
|
|
57078
57179
|
bold: true,
|
|
57079
|
-
children: "Press ! to
|
|
57180
|
+
children: "Press ! to review and fix."
|
|
57080
57181
|
}, undefined, false, undefined, this)
|
|
57081
57182
|
]
|
|
57082
57183
|
}, undefined, true, undefined, this)
|
|
@@ -57348,7 +57449,110 @@ var init_InstanceSelectMenu = __esm(async () => {
|
|
|
57348
57449
|
jsx_dev_runtime9 = __toESM(require_jsx_dev_runtime(), 1);
|
|
57349
57450
|
});
|
|
57350
57451
|
|
|
57452
|
+
// src/ink/util/instance-diagnostics.ts
|
|
57453
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7 } from "node:fs";
|
|
57454
|
+
import { join as join8 } from "node:path";
|
|
57455
|
+
function tryResolveRegionalTemplate(template2, region) {
|
|
57456
|
+
if (!template2)
|
|
57457
|
+
return;
|
|
57458
|
+
try {
|
|
57459
|
+
const providerRegions = getProviderRegions(template2.name);
|
|
57460
|
+
if (providerRegions && region in providerRegions) {
|
|
57461
|
+
return resolveRegionTemplate(template2, region);
|
|
57462
|
+
}
|
|
57463
|
+
} catch {}
|
|
57464
|
+
return;
|
|
57465
|
+
}
|
|
57466
|
+
function detectTemplateMismatch(instance) {
|
|
57467
|
+
const providerName = instance.providerTemplate ?? detectProvider(instance.configDir);
|
|
57468
|
+
if (!providerName) {
|
|
57469
|
+
return { status: "unknown", providerName: null };
|
|
57470
|
+
}
|
|
57471
|
+
let template2 = getProviderTemplate(providerName);
|
|
57472
|
+
if (!template2) {
|
|
57473
|
+
return { status: "unknown", providerName };
|
|
57474
|
+
}
|
|
57475
|
+
const settingsFile = join8(instance.configDir, "settings.json");
|
|
57476
|
+
if (!existsSync7(settingsFile)) {
|
|
57477
|
+
return { status: "unknown", providerName };
|
|
57478
|
+
}
|
|
57479
|
+
let existingEnv = {};
|
|
57480
|
+
try {
|
|
57481
|
+
const raw = JSON.parse(readFileSync7(settingsFile, "utf-8"));
|
|
57482
|
+
existingEnv = raw.env ?? {};
|
|
57483
|
+
} catch {
|
|
57484
|
+
return { status: "unknown", providerName };
|
|
57485
|
+
}
|
|
57486
|
+
if (providerHasRegions(providerName)) {
|
|
57487
|
+
const existingUrl = existingEnv.ANTHROPIC_BASE_URL;
|
|
57488
|
+
const detectedRegion = existingUrl ? detectRegionFromBaseUrl(existingUrl) ?? instance.providerRegion : instance.providerRegion;
|
|
57489
|
+
if (detectedRegion) {
|
|
57490
|
+
const resolved = tryResolveRegionalTemplate(template2, detectedRegion);
|
|
57491
|
+
if (resolved) {
|
|
57492
|
+
template2 = resolved;
|
|
57493
|
+
}
|
|
57494
|
+
}
|
|
57495
|
+
}
|
|
57496
|
+
const templateEnv = template2.settings.env;
|
|
57497
|
+
for (const [key, expectedValue] of Object.entries(templateEnv)) {
|
|
57498
|
+
if (key === "ANTHROPIC_AUTH_TOKEN")
|
|
57499
|
+
continue;
|
|
57500
|
+
if (TUNABLE_ENV_VARS.has(key))
|
|
57501
|
+
continue;
|
|
57502
|
+
if (existingEnv[key] !== expectedValue) {
|
|
57503
|
+
return { status: "mismatch", providerName };
|
|
57504
|
+
}
|
|
57505
|
+
}
|
|
57506
|
+
return { status: "match", providerName };
|
|
57507
|
+
}
|
|
57508
|
+
function detectWrapperMismatch(instance) {
|
|
57509
|
+
if (!existsSync7(instance.binaryPath)) {
|
|
57510
|
+
return { status: "missing" };
|
|
57511
|
+
}
|
|
57512
|
+
const expected = generateWrapperScriptSafe({
|
|
57513
|
+
name: instance.name,
|
|
57514
|
+
configDir: instance.configDir,
|
|
57515
|
+
binaryPath: instance.binaryPath
|
|
57516
|
+
});
|
|
57517
|
+
if (expected === null) {
|
|
57518
|
+
return { status: "unknown" };
|
|
57519
|
+
}
|
|
57520
|
+
try {
|
|
57521
|
+
const current = readFileSync7(instance.binaryPath, "utf-8");
|
|
57522
|
+
return current === expected ? { status: "match" } : { status: "mismatch" };
|
|
57523
|
+
} catch {
|
|
57524
|
+
return { status: "unknown" };
|
|
57525
|
+
}
|
|
57526
|
+
}
|
|
57527
|
+
var init_instance_diagnostics = __esm(() => {
|
|
57528
|
+
init_templates();
|
|
57529
|
+
init_wrapper();
|
|
57530
|
+
init_env();
|
|
57531
|
+
});
|
|
57532
|
+
|
|
57351
57533
|
// src/ink/screens/ShowInstanceInfo.tsx
|
|
57534
|
+
function templateStatusLabel(status) {
|
|
57535
|
+
switch (status) {
|
|
57536
|
+
case "match":
|
|
57537
|
+
return "✓ up to date";
|
|
57538
|
+
case "mismatch":
|
|
57539
|
+
return "⚠ mismatch detected";
|
|
57540
|
+
case "unknown":
|
|
57541
|
+
return "? unknown";
|
|
57542
|
+
}
|
|
57543
|
+
}
|
|
57544
|
+
function wrapperStatusLabel(status) {
|
|
57545
|
+
switch (status) {
|
|
57546
|
+
case "match":
|
|
57547
|
+
return "✓ up to date";
|
|
57548
|
+
case "mismatch":
|
|
57549
|
+
return "⚠ mismatch detected";
|
|
57550
|
+
case "missing":
|
|
57551
|
+
return "✗ wrapper missing";
|
|
57552
|
+
case "unknown":
|
|
57553
|
+
return "? unknown";
|
|
57554
|
+
}
|
|
57555
|
+
}
|
|
57352
57556
|
var import_react69, jsx_dev_runtime10, DetailRow = ({
|
|
57353
57557
|
label,
|
|
57354
57558
|
value,
|
|
@@ -57382,19 +57586,74 @@ var import_react69, jsx_dev_runtime10, DetailRow = ({
|
|
|
57382
57586
|
}, undefined, false, undefined, this)
|
|
57383
57587
|
]
|
|
57384
57588
|
}, undefined, true, undefined, this);
|
|
57385
|
-
}, EMPTY_INFO, ShowInstanceInfo = ({ onBack }) => {
|
|
57386
|
-
const {
|
|
57589
|
+
}, EMPTY_INFO, ACTION_VALUES, ShowInstanceInfo = ({ onBack }) => {
|
|
57590
|
+
const { exit } = use_app_default();
|
|
57591
|
+
const { instances: instances2, listInstancePlugins: listInstancePlugins2, getInstanceMcpServers: getInstanceMcpServers2, syncTemplateEnv, regenerateWrapper } = useConfig();
|
|
57387
57592
|
const [step, setStep] = import_react69.useState("select");
|
|
57388
57593
|
const [selected, setSelected] = import_react69.useState(null);
|
|
57389
57594
|
const [infoData, setInfoData] = import_react69.useState(EMPTY_INFO);
|
|
57390
|
-
|
|
57391
|
-
|
|
57392
|
-
|
|
57393
|
-
|
|
57394
|
-
|
|
57395
|
-
|
|
57595
|
+
const [templateStatus, setTemplateStatus] = import_react69.useState("unknown");
|
|
57596
|
+
const [wrapperStatus, setWrapperStatus] = import_react69.useState("unknown");
|
|
57597
|
+
const [providerName, setProviderName] = import_react69.useState(null);
|
|
57598
|
+
const [actionResult, setActionResult] = import_react69.useState(null);
|
|
57599
|
+
const [executing, setExecuting] = import_react69.useState(false);
|
|
57600
|
+
const liveSelected = selected ? instances2.find((i) => i.name === selected.name) ?? selected : null;
|
|
57601
|
+
const runDiagnostics = import_react69.useCallback((inst) => {
|
|
57602
|
+
const tmpl = detectTemplateMismatch(inst);
|
|
57603
|
+
const wrap2 = detectWrapperMismatch(inst);
|
|
57604
|
+
setTemplateStatus(tmpl.status);
|
|
57605
|
+
setWrapperStatus(wrap2.status);
|
|
57606
|
+
setProviderName(tmpl.providerName);
|
|
57607
|
+
}, []);
|
|
57608
|
+
const loadInstanceInfo = import_react69.useCallback(async (inst) => {
|
|
57609
|
+
try {
|
|
57610
|
+
const plugins = listInstancePlugins2(inst.configDir);
|
|
57611
|
+
const mcpData = await getInstanceMcpServers2(inst.configDir);
|
|
57612
|
+
setInfoData({
|
|
57613
|
+
pluginCount: plugins.length,
|
|
57614
|
+
enabledCount: plugins.filter((p) => p.enabled).length,
|
|
57615
|
+
mcpPluginCount: Object.keys(mcpData.fromPlugins).length,
|
|
57616
|
+
mcpCustomCount: Object.keys(mcpData.fromSettings).length,
|
|
57617
|
+
mcpCount: Object.keys(mcpData.all).length
|
|
57618
|
+
});
|
|
57619
|
+
} catch {
|
|
57620
|
+
setInfoData(EMPTY_INFO);
|
|
57621
|
+
}
|
|
57622
|
+
}, [listInstancePlugins2, getInstanceMcpServers2]);
|
|
57623
|
+
use_input_default((input, key) => {
|
|
57624
|
+
if (executing)
|
|
57625
|
+
return;
|
|
57626
|
+
if (input === "q") {
|
|
57627
|
+
exit();
|
|
57628
|
+
return;
|
|
57629
|
+
}
|
|
57630
|
+
if (key.escape) {
|
|
57631
|
+
if (step === "info") {
|
|
57632
|
+
setStep("select");
|
|
57633
|
+
setSelected(null);
|
|
57634
|
+
} else if (step === "actions") {
|
|
57635
|
+
setStep("info");
|
|
57636
|
+
} else if (step === "result") {
|
|
57637
|
+
goToInfo();
|
|
57638
|
+
} else {
|
|
57639
|
+
onBack();
|
|
57640
|
+
}
|
|
57641
|
+
} else if (key.return) {
|
|
57642
|
+
if (step === "info") {
|
|
57643
|
+
setStep("actions");
|
|
57644
|
+
} else if (step === "result") {
|
|
57645
|
+
goToInfo();
|
|
57646
|
+
}
|
|
57396
57647
|
}
|
|
57397
57648
|
});
|
|
57649
|
+
const goToInfo = () => {
|
|
57650
|
+
const inst = liveSelected;
|
|
57651
|
+
if (inst) {
|
|
57652
|
+
runDiagnostics(inst);
|
|
57653
|
+
loadInstanceInfo(inst);
|
|
57654
|
+
}
|
|
57655
|
+
setStep("info");
|
|
57656
|
+
};
|
|
57398
57657
|
if (instances2.length === 0) {
|
|
57399
57658
|
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
57400
57659
|
flexDirection: "column",
|
|
@@ -57425,20 +57684,62 @@ var import_react69, jsx_dev_runtime10, DetailRow = ({
|
|
|
57425
57684
|
return;
|
|
57426
57685
|
setSelected(inst);
|
|
57427
57686
|
setStep("info");
|
|
57687
|
+
runDiagnostics(inst);
|
|
57688
|
+
await loadInstanceInfo(inst);
|
|
57689
|
+
};
|
|
57690
|
+
const handleAction = async (value) => {
|
|
57691
|
+
if (executing)
|
|
57692
|
+
return;
|
|
57693
|
+
if (value === ACTION_VALUES.Back || !selected) {
|
|
57694
|
+
setStep("info");
|
|
57695
|
+
return;
|
|
57696
|
+
}
|
|
57697
|
+
setActionResult(null);
|
|
57698
|
+
setExecuting(true);
|
|
57699
|
+
setStep("executing");
|
|
57428
57700
|
try {
|
|
57429
|
-
|
|
57430
|
-
|
|
57431
|
-
|
|
57432
|
-
|
|
57433
|
-
|
|
57434
|
-
|
|
57435
|
-
|
|
57436
|
-
|
|
57701
|
+
if (value === ACTION_VALUES.SyncTemplate) {
|
|
57702
|
+
await syncTemplateEnv(liveSelected ?? selected);
|
|
57703
|
+
setActionResult({ message: `Settings template updated for '${selected.name}'`, type: "success" });
|
|
57704
|
+
} else if (value === ACTION_VALUES.UpdateWrapper || value === ACTION_VALUES.OverrideWrapper) {
|
|
57705
|
+
await regenerateWrapper(liveSelected ?? selected);
|
|
57706
|
+
setActionResult({ message: `Alias wrapper regenerated for '${selected.name}'`, type: "success" });
|
|
57707
|
+
}
|
|
57708
|
+
} catch (err) {
|
|
57709
|
+
setActionResult({
|
|
57710
|
+
message: err instanceof Error ? err.message : String(err),
|
|
57711
|
+
type: "error"
|
|
57437
57712
|
});
|
|
57438
|
-
} catch {
|
|
57439
|
-
setInfoData(EMPTY_INFO);
|
|
57440
57713
|
}
|
|
57714
|
+
setExecuting(false);
|
|
57715
|
+
setStep("result");
|
|
57716
|
+
};
|
|
57717
|
+
const buildActionOptions = () => {
|
|
57718
|
+
const options = [];
|
|
57719
|
+
if (providerName) {
|
|
57720
|
+
options.push({
|
|
57721
|
+
label: `\uD83D\uDD04 Update settings template [${templateStatusLabel(templateStatus)}]`,
|
|
57722
|
+
value: ACTION_VALUES.SyncTemplate
|
|
57723
|
+
});
|
|
57724
|
+
}
|
|
57725
|
+
options.push({
|
|
57726
|
+
label: `\uD83D\uDD27 Update alias wrapper [${wrapperStatusLabel(wrapperStatus)}]`,
|
|
57727
|
+
value: ACTION_VALUES.UpdateWrapper
|
|
57728
|
+
});
|
|
57729
|
+
if (wrapperStatus === "mismatch" || wrapperStatus === "missing") {
|
|
57730
|
+
options.push({
|
|
57731
|
+
label: `\uD83D\uDD28 Override alias to standard`,
|
|
57732
|
+
value: ACTION_VALUES.OverrideWrapper
|
|
57733
|
+
});
|
|
57734
|
+
}
|
|
57735
|
+
options.push({ label: "← Back", value: ACTION_VALUES.Back });
|
|
57736
|
+
return options;
|
|
57441
57737
|
};
|
|
57738
|
+
const hasPlugins = infoData.pluginCount !== null;
|
|
57739
|
+
const hasMcp = infoData.mcpCount !== null;
|
|
57740
|
+
const hasProvider = providerName !== null;
|
|
57741
|
+
const lastRow = hasMcp ? "mcp" : hasPlugins ? "plugins" : hasProvider ? "provider" : "version";
|
|
57742
|
+
const displayInstance = liveSelected ?? selected;
|
|
57442
57743
|
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
57443
57744
|
flexDirection: "column",
|
|
57444
57745
|
width: "100",
|
|
@@ -57452,7 +57753,7 @@ var import_react69, jsx_dev_runtime10, DetailRow = ({
|
|
|
57452
57753
|
instances: instances2,
|
|
57453
57754
|
onSelect: handleInstanceSelect
|
|
57454
57755
|
}, undefined, false, undefined, this),
|
|
57455
|
-
step === "info" &&
|
|
57756
|
+
step === "info" && displayInstance && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
57456
57757
|
flexDirection: "column",
|
|
57457
57758
|
gap: 0,
|
|
57458
57759
|
children: [
|
|
@@ -57466,7 +57767,7 @@ var import_react69, jsx_dev_runtime10, DetailRow = ({
|
|
|
57466
57767
|
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
57467
57768
|
bold: true,
|
|
57468
57769
|
color: "cyan",
|
|
57469
|
-
children:
|
|
57770
|
+
children: displayInstance.name
|
|
57470
57771
|
}, undefined, false, undefined, this)
|
|
57471
57772
|
]
|
|
57472
57773
|
}, undefined, true, undefined, this),
|
|
@@ -57476,53 +57777,186 @@ var import_react69, jsx_dev_runtime10, DetailRow = ({
|
|
|
57476
57777
|
children: [
|
|
57477
57778
|
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(DetailRow, {
|
|
57478
57779
|
label: "Binary",
|
|
57479
|
-
value:
|
|
57780
|
+
value: displayInstance.binaryPath,
|
|
57480
57781
|
delay: 50
|
|
57481
57782
|
}, undefined, false, undefined, this),
|
|
57482
57783
|
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(DetailRow, {
|
|
57483
57784
|
label: "Config",
|
|
57484
|
-
value:
|
|
57785
|
+
value: displayInstance.configDir,
|
|
57485
57786
|
delay: 100
|
|
57486
57787
|
}, undefined, false, undefined, this),
|
|
57487
57788
|
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(DetailRow, {
|
|
57488
57789
|
label: "Created",
|
|
57489
|
-
value: new Date(
|
|
57790
|
+
value: new Date(displayInstance.createdAt).toLocaleString(),
|
|
57490
57791
|
delay: 150
|
|
57491
57792
|
}, undefined, false, undefined, this),
|
|
57492
57793
|
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(DetailRow, {
|
|
57493
57794
|
label: "Auto-sync",
|
|
57494
|
-
value:
|
|
57495
|
-
color:
|
|
57795
|
+
value: displayInstance.autoSync !== false ? "✓ Enabled" : "✗ Disabled",
|
|
57796
|
+
color: displayInstance.autoSync !== false ? "green" : "red",
|
|
57496
57797
|
delay: 200
|
|
57497
57798
|
}, undefined, false, undefined, this),
|
|
57498
57799
|
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(DetailRow, {
|
|
57499
57800
|
label: "Version",
|
|
57500
|
-
value:
|
|
57501
|
-
color:
|
|
57801
|
+
value: displayInstance.createdWithVersion === LEGACY_INSTANCE_VERSION ? "before version tracking" : displayInstance.createdWithVersion,
|
|
57802
|
+
color: displayInstance.createdWithVersion === LEGACY_INSTANCE_VERSION ? "yellow" : undefined,
|
|
57803
|
+
last: lastRow === "version",
|
|
57502
57804
|
delay: 250
|
|
57503
57805
|
}, undefined, false, undefined, this),
|
|
57504
|
-
|
|
57806
|
+
hasProvider && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(DetailRow, {
|
|
57807
|
+
label: "Provider",
|
|
57808
|
+
value: providerName,
|
|
57809
|
+
color: templateStatus === "match" ? undefined : templateStatus === "mismatch" ? "yellow" : undefined,
|
|
57810
|
+
last: lastRow === "provider",
|
|
57811
|
+
delay: 275
|
|
57812
|
+
}, undefined, false, undefined, this),
|
|
57813
|
+
hasPlugins && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(DetailRow, {
|
|
57505
57814
|
label: "Plugins",
|
|
57506
57815
|
value: `${infoData.pluginCount} installed, ${infoData.enabledCount} enabled`,
|
|
57816
|
+
last: lastRow === "plugins",
|
|
57507
57817
|
delay: 300
|
|
57508
57818
|
}, undefined, false, undefined, this),
|
|
57509
|
-
|
|
57819
|
+
hasMcp && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(DetailRow, {
|
|
57510
57820
|
label: "MCP Servers",
|
|
57511
57821
|
value: `${infoData.mcpCount} total (${infoData.mcpPluginCount} from plugins, ${infoData.mcpCustomCount} custom)`,
|
|
57512
|
-
last:
|
|
57822
|
+
last: lastRow === "mcp",
|
|
57513
57823
|
delay: 350
|
|
57514
57824
|
}, undefined, false, undefined, this)
|
|
57515
57825
|
]
|
|
57516
57826
|
}, undefined, true, undefined, this)
|
|
57517
57827
|
]
|
|
57518
57828
|
}, undefined, true, undefined, this),
|
|
57829
|
+
step === "actions" && displayInstance && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
57830
|
+
flexDirection: "column",
|
|
57831
|
+
gap: 1,
|
|
57832
|
+
children: [
|
|
57833
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
57834
|
+
gap: 1,
|
|
57835
|
+
children: [
|
|
57836
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
57837
|
+
color: "cyan",
|
|
57838
|
+
children: "●"
|
|
57839
|
+
}, undefined, false, undefined, this),
|
|
57840
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
57841
|
+
bold: true,
|
|
57842
|
+
color: "cyan",
|
|
57843
|
+
children: displayInstance.name
|
|
57844
|
+
}, undefined, false, undefined, this)
|
|
57845
|
+
]
|
|
57846
|
+
}, undefined, true, undefined, this),
|
|
57847
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
57848
|
+
marginTop: 1,
|
|
57849
|
+
children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
57850
|
+
bold: true,
|
|
57851
|
+
children: "Actions:"
|
|
57852
|
+
}, undefined, false, undefined, this)
|
|
57853
|
+
}, undefined, false, undefined, this),
|
|
57854
|
+
(() => {
|
|
57855
|
+
const actionOptions = buildActionOptions();
|
|
57856
|
+
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Select, {
|
|
57857
|
+
options: actionOptions,
|
|
57858
|
+
visibleOptionCount: actionOptions.length,
|
|
57859
|
+
onChange: handleAction
|
|
57860
|
+
}, undefined, false, undefined, this);
|
|
57861
|
+
})()
|
|
57862
|
+
]
|
|
57863
|
+
}, undefined, true, undefined, this),
|
|
57864
|
+
step === "executing" && displayInstance && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
57865
|
+
flexDirection: "column",
|
|
57866
|
+
gap: 1,
|
|
57867
|
+
children: [
|
|
57868
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
57869
|
+
gap: 1,
|
|
57870
|
+
children: [
|
|
57871
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
57872
|
+
color: "cyan",
|
|
57873
|
+
children: "●"
|
|
57874
|
+
}, undefined, false, undefined, this),
|
|
57875
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
57876
|
+
bold: true,
|
|
57877
|
+
color: "cyan",
|
|
57878
|
+
children: displayInstance.name
|
|
57879
|
+
}, undefined, false, undefined, this)
|
|
57880
|
+
]
|
|
57881
|
+
}, undefined, true, undefined, this),
|
|
57882
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
57883
|
+
marginTop: 1,
|
|
57884
|
+
children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Spinner, {
|
|
57885
|
+
label: "Updating..."
|
|
57886
|
+
}, undefined, false, undefined, this)
|
|
57887
|
+
}, undefined, false, undefined, this)
|
|
57888
|
+
]
|
|
57889
|
+
}, undefined, true, undefined, this),
|
|
57890
|
+
step === "result" && displayInstance && actionResult && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
57891
|
+
flexDirection: "column",
|
|
57892
|
+
gap: 1,
|
|
57893
|
+
children: [
|
|
57894
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
57895
|
+
gap: 1,
|
|
57896
|
+
children: [
|
|
57897
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
57898
|
+
color: "cyan",
|
|
57899
|
+
children: "●"
|
|
57900
|
+
}, undefined, false, undefined, this),
|
|
57901
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
57902
|
+
bold: true,
|
|
57903
|
+
color: "cyan",
|
|
57904
|
+
children: displayInstance.name
|
|
57905
|
+
}, undefined, false, undefined, this)
|
|
57906
|
+
]
|
|
57907
|
+
}, undefined, true, undefined, this),
|
|
57908
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
57909
|
+
marginTop: 1,
|
|
57910
|
+
children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(StatusBar, {
|
|
57911
|
+
message: actionResult.message,
|
|
57912
|
+
type: actionResult.type
|
|
57913
|
+
}, undefined, false, undefined, this)
|
|
57914
|
+
}, undefined, false, undefined, this)
|
|
57915
|
+
]
|
|
57916
|
+
}, undefined, true, undefined, this),
|
|
57519
57917
|
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
57520
57918
|
marginTop: 1,
|
|
57521
|
-
children:
|
|
57522
|
-
|
|
57523
|
-
|
|
57524
|
-
|
|
57525
|
-
|
|
57919
|
+
children: [
|
|
57920
|
+
step === "info" && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
57921
|
+
gap: 2,
|
|
57922
|
+
children: [
|
|
57923
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
57924
|
+
dimColor: true,
|
|
57925
|
+
children: "Enter for actions"
|
|
57926
|
+
}, undefined, false, undefined, this),
|
|
57927
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
57928
|
+
dimColor: true,
|
|
57929
|
+
children: "ESC to go back"
|
|
57930
|
+
}, undefined, false, undefined, this),
|
|
57931
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
57932
|
+
dimColor: true,
|
|
57933
|
+
children: "q quit"
|
|
57934
|
+
}, undefined, false, undefined, this)
|
|
57935
|
+
]
|
|
57936
|
+
}, undefined, true, undefined, this),
|
|
57937
|
+
step === "actions" && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
57938
|
+
dimColor: true,
|
|
57939
|
+
children: "↑↓ navigate │ Enter select │ ESC back │ q quit"
|
|
57940
|
+
}, undefined, false, undefined, this),
|
|
57941
|
+
step === "result" && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
57942
|
+
gap: 2,
|
|
57943
|
+
children: [
|
|
57944
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
57945
|
+
dimColor: true,
|
|
57946
|
+
children: "Enter/ESC to return"
|
|
57947
|
+
}, undefined, false, undefined, this),
|
|
57948
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
57949
|
+
dimColor: true,
|
|
57950
|
+
children: "q quit"
|
|
57951
|
+
}, undefined, false, undefined, this)
|
|
57952
|
+
]
|
|
57953
|
+
}, undefined, true, undefined, this),
|
|
57954
|
+
step === "select" && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
57955
|
+
dimColor: true,
|
|
57956
|
+
children: "ESC to go back │ q quit"
|
|
57957
|
+
}, undefined, false, undefined, this)
|
|
57958
|
+
]
|
|
57959
|
+
}, undefined, true, undefined, this)
|
|
57526
57960
|
]
|
|
57527
57961
|
}, undefined, true, undefined, this);
|
|
57528
57962
|
};
|
|
@@ -57530,10 +57964,12 @@ var init_ShowInstanceInfo = __esm(async () => {
|
|
|
57530
57964
|
init_useConfig();
|
|
57531
57965
|
init_useAnimations();
|
|
57532
57966
|
init_migration();
|
|
57967
|
+
init_instance_diagnostics();
|
|
57533
57968
|
await __promiseAll([
|
|
57534
57969
|
init_build2(),
|
|
57970
|
+
init_build3(),
|
|
57535
57971
|
init_Header(),
|
|
57536
|
-
|
|
57972
|
+
init_StatusBar(),
|
|
57537
57973
|
init_InstanceSelectMenu()
|
|
57538
57974
|
]);
|
|
57539
57975
|
import_react69 = __toESM(require_react(), 1);
|
|
@@ -57545,6 +57981,12 @@ var init_ShowInstanceInfo = __esm(async () => {
|
|
|
57545
57981
|
mcpPluginCount: null,
|
|
57546
57982
|
mcpCustomCount: null
|
|
57547
57983
|
};
|
|
57984
|
+
ACTION_VALUES = {
|
|
57985
|
+
SyncTemplate: "sync-template",
|
|
57986
|
+
UpdateWrapper: "update-wrapper",
|
|
57987
|
+
OverrideWrapper: "override-wrapper",
|
|
57988
|
+
Back: "back"
|
|
57989
|
+
};
|
|
57548
57990
|
});
|
|
57549
57991
|
|
|
57550
57992
|
// src/ink/screens/RemoveInstance.tsx
|
|
@@ -58965,61 +59407,8 @@ var init_ManageMcp = __esm(async () => {
|
|
|
58965
59407
|
};
|
|
58966
59408
|
});
|
|
58967
59409
|
|
|
58968
|
-
// src/ink/components/IssueCard.tsx
|
|
58969
|
-
var jsx_dev_runtime16, SEVERITY_ICONS, SEVERITY_COLORS, IssueCard = ({
|
|
58970
|
-
issue,
|
|
58971
|
-
index
|
|
58972
|
-
}) => {
|
|
58973
|
-
const visible = useFadeIn(index * 60 + 50);
|
|
58974
|
-
if (!visible)
|
|
58975
|
-
return null;
|
|
58976
|
-
const icon = SEVERITY_ICONS[issue.severity] ?? "•";
|
|
58977
|
-
const color = SEVERITY_COLORS[issue.severity] ?? "white";
|
|
58978
|
-
return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
|
|
58979
|
-
flexDirection: "column",
|
|
58980
|
-
marginLeft: 2,
|
|
58981
|
-
children: [
|
|
58982
|
-
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
|
|
58983
|
-
gap: 1,
|
|
58984
|
-
children: [
|
|
58985
|
-
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
58986
|
-
children: icon
|
|
58987
|
-
}, undefined, false, undefined, this),
|
|
58988
|
-
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
58989
|
-
bold: true,
|
|
58990
|
-
color,
|
|
58991
|
-
children: issue.title
|
|
58992
|
-
}, undefined, false, undefined, this)
|
|
58993
|
-
]
|
|
58994
|
-
}, undefined, true, undefined, this),
|
|
58995
|
-
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
|
|
58996
|
-
marginLeft: 2,
|
|
58997
|
-
children: /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
58998
|
-
dimColor: true,
|
|
58999
|
-
children: issue.message
|
|
59000
|
-
}, undefined, false, undefined, this)
|
|
59001
|
-
}, undefined, false, undefined, this)
|
|
59002
|
-
]
|
|
59003
|
-
}, undefined, true, undefined, this);
|
|
59004
|
-
};
|
|
59005
|
-
var init_IssueCard = __esm(async () => {
|
|
59006
|
-
init_useAnimations();
|
|
59007
|
-
await init_build2();
|
|
59008
|
-
jsx_dev_runtime16 = __toESM(require_jsx_dev_runtime(), 1);
|
|
59009
|
-
SEVERITY_ICONS = {
|
|
59010
|
-
error: "❌",
|
|
59011
|
-
warning: "⚠",
|
|
59012
|
-
info: "ℹ️"
|
|
59013
|
-
};
|
|
59014
|
-
SEVERITY_COLORS = {
|
|
59015
|
-
error: "red",
|
|
59016
|
-
warning: "yellow",
|
|
59017
|
-
info: "gray"
|
|
59018
|
-
};
|
|
59019
|
-
});
|
|
59020
|
-
|
|
59021
59410
|
// src/ink/screens/HealthScreen.tsx
|
|
59022
|
-
var import_react76,
|
|
59411
|
+
var import_react76, jsx_dev_runtime16, SEVERITY_ICONS, HealthScreen = ({
|
|
59023
59412
|
issues,
|
|
59024
59413
|
onDismiss,
|
|
59025
59414
|
onDismissAll,
|
|
@@ -59029,7 +59418,6 @@ var import_react76, jsx_dev_runtime17, HealthScreen = ({
|
|
|
59029
59418
|
}) => {
|
|
59030
59419
|
const [step, setStep] = import_react76.useState("list");
|
|
59031
59420
|
const [selectedIssue, setSelectedIssue] = import_react76.useState(null);
|
|
59032
|
-
const showActions = useFadeIn(100);
|
|
59033
59421
|
useNavigation(() => {
|
|
59034
59422
|
if (step === "detail") {
|
|
59035
59423
|
setStep("list");
|
|
@@ -59039,38 +59427,39 @@ var import_react76, jsx_dev_runtime17, HealthScreen = ({
|
|
|
59039
59427
|
}
|
|
59040
59428
|
});
|
|
59041
59429
|
use_input_default((input) => {
|
|
59042
|
-
if (step
|
|
59043
|
-
|
|
59044
|
-
|
|
59045
|
-
|
|
59046
|
-
|
|
59047
|
-
|
|
59048
|
-
|
|
59049
|
-
|
|
59050
|
-
|
|
59051
|
-
|
|
59052
|
-
|
|
59053
|
-
|
|
59054
|
-
|
|
59430
|
+
if (step === "list") {
|
|
59431
|
+
if (input === "D") {
|
|
59432
|
+
onDismissAll();
|
|
59433
|
+
} else if (input === "r") {
|
|
59434
|
+
onRetry();
|
|
59435
|
+
} else if (input === "f") {
|
|
59436
|
+
onFix();
|
|
59437
|
+
}
|
|
59438
|
+
} else if (step === "detail" && selectedIssue) {
|
|
59439
|
+
if (input === "d") {
|
|
59440
|
+
onDismiss(selectedIssue.id);
|
|
59441
|
+
setSelectedIssue(null);
|
|
59442
|
+
setStep("list");
|
|
59443
|
+
}
|
|
59055
59444
|
}
|
|
59056
59445
|
});
|
|
59057
59446
|
if (issues.length === 0) {
|
|
59058
|
-
return /* @__PURE__ */
|
|
59447
|
+
return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
|
|
59059
59448
|
flexDirection: "column",
|
|
59060
59449
|
width: "100",
|
|
59061
59450
|
paddingX: 2,
|
|
59062
59451
|
paddingY: 1,
|
|
59063
59452
|
children: [
|
|
59064
|
-
/* @__PURE__ */
|
|
59453
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Header, {
|
|
59065
59454
|
title: "\uD83D\uDC9A System Health"
|
|
59066
59455
|
}, undefined, false, undefined, this),
|
|
59067
|
-
/* @__PURE__ */
|
|
59456
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(StatusBar, {
|
|
59068
59457
|
message: "All systems healthy!",
|
|
59069
59458
|
type: "success"
|
|
59070
59459
|
}, undefined, false, undefined, this),
|
|
59071
|
-
/* @__PURE__ */
|
|
59460
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
|
|
59072
59461
|
marginTop: 1,
|
|
59073
|
-
children: /* @__PURE__ */
|
|
59462
|
+
children: /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59074
59463
|
dimColor: true,
|
|
59075
59464
|
children: "ESC to go back"
|
|
59076
59465
|
}, undefined, false, undefined, this)
|
|
@@ -59079,137 +59468,167 @@ var import_react76, jsx_dev_runtime17, HealthScreen = ({
|
|
|
59079
59468
|
}, undefined, true, undefined, this);
|
|
59080
59469
|
}
|
|
59081
59470
|
const hasVersionIssues = issues.some((i) => i.category === "version");
|
|
59082
|
-
|
|
59471
|
+
const handleIssueSelect = (value) => {
|
|
59472
|
+
const issue = issues.find((i) => i.id === value);
|
|
59473
|
+
if (issue) {
|
|
59474
|
+
setSelectedIssue(issue);
|
|
59475
|
+
setStep("detail");
|
|
59476
|
+
}
|
|
59477
|
+
};
|
|
59478
|
+
const issueOptions = issues.map((issue) => ({
|
|
59479
|
+
label: `${SEVERITY_ICONS[issue.severity] ?? "•"} ${issue.title}`,
|
|
59480
|
+
value: issue.id
|
|
59481
|
+
}));
|
|
59482
|
+
return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
|
|
59083
59483
|
flexDirection: "column",
|
|
59084
59484
|
width: "100",
|
|
59085
59485
|
paddingX: 2,
|
|
59086
59486
|
paddingY: 1,
|
|
59087
59487
|
children: [
|
|
59088
|
-
/* @__PURE__ */
|
|
59488
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Header, {
|
|
59089
59489
|
title: "⚠ System Health"
|
|
59090
59490
|
}, undefined, false, undefined, this),
|
|
59091
|
-
step === "list" && /* @__PURE__ */
|
|
59491
|
+
step === "list" && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
|
|
59092
59492
|
flexDirection: "column",
|
|
59093
59493
|
gap: 1,
|
|
59094
59494
|
children: [
|
|
59095
|
-
/* @__PURE__ */
|
|
59495
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59096
59496
|
bold: true,
|
|
59097
59497
|
children: [
|
|
59098
59498
|
issues.length,
|
|
59099
|
-
" issue(s) found:"
|
|
59499
|
+
" issue(s) found — select one to view:"
|
|
59100
59500
|
]
|
|
59101
59501
|
}, undefined, true, undefined, this),
|
|
59102
|
-
|
|
59103
|
-
|
|
59104
|
-
|
|
59105
|
-
|
|
59106
|
-
|
|
59502
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Select, {
|
|
59503
|
+
options: issueOptions,
|
|
59504
|
+
visibleOptionCount: issueOptions.length,
|
|
59505
|
+
onChange: handleIssueSelect
|
|
59506
|
+
}, undefined, false, undefined, this),
|
|
59507
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
|
|
59107
59508
|
marginTop: 1,
|
|
59108
59509
|
flexDirection: "column",
|
|
59109
59510
|
children: [
|
|
59110
|
-
hasVersionIssues && /* @__PURE__ */
|
|
59511
|
+
hasVersionIssues && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
|
|
59111
59512
|
marginBottom: 1,
|
|
59112
59513
|
children: [
|
|
59113
|
-
/* @__PURE__ */
|
|
59514
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59114
59515
|
color: "cyan",
|
|
59115
59516
|
bold: true,
|
|
59116
59517
|
children: "f"
|
|
59117
59518
|
}, undefined, false, undefined, this),
|
|
59118
|
-
/* @__PURE__ */
|
|
59519
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59119
59520
|
color: "cyan",
|
|
59120
59521
|
children: " fix wrappers "
|
|
59121
59522
|
}, undefined, false, undefined, this),
|
|
59122
|
-
/* @__PURE__ */
|
|
59523
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59123
59524
|
dimColor: true,
|
|
59124
59525
|
children: "│"
|
|
59125
59526
|
}, undefined, false, undefined, this)
|
|
59126
59527
|
]
|
|
59127
59528
|
}, undefined, true, undefined, this),
|
|
59128
|
-
/* @__PURE__ */
|
|
59529
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59129
59530
|
dimColor: true,
|
|
59130
|
-
children: "
|
|
59531
|
+
children: "D dismiss all │ r retry │ ESC back"
|
|
59131
59532
|
}, undefined, false, undefined, this)
|
|
59132
59533
|
]
|
|
59133
59534
|
}, undefined, true, undefined, this)
|
|
59134
59535
|
]
|
|
59135
59536
|
}, undefined, true, undefined, this),
|
|
59136
|
-
step === "detail" && selectedIssue && /* @__PURE__ */
|
|
59537
|
+
step === "detail" && selectedIssue && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
|
|
59137
59538
|
flexDirection: "column",
|
|
59138
59539
|
gap: 1,
|
|
59139
59540
|
children: [
|
|
59140
|
-
/* @__PURE__ */
|
|
59541
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59141
59542
|
bold: true,
|
|
59142
59543
|
children: selectedIssue.title
|
|
59143
59544
|
}, undefined, false, undefined, this),
|
|
59144
|
-
/* @__PURE__ */
|
|
59545
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
|
|
59145
59546
|
marginLeft: 2,
|
|
59146
59547
|
flexDirection: "column",
|
|
59147
59548
|
children: [
|
|
59148
|
-
/* @__PURE__ */
|
|
59549
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
|
|
59149
59550
|
gap: 1,
|
|
59150
59551
|
children: [
|
|
59151
|
-
/* @__PURE__ */
|
|
59552
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59152
59553
|
dimColor: true,
|
|
59153
59554
|
children: "├─"
|
|
59154
59555
|
}, undefined, false, undefined, this),
|
|
59155
|
-
/* @__PURE__ */
|
|
59556
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59156
59557
|
dimColor: true,
|
|
59157
59558
|
bold: true,
|
|
59158
59559
|
children: "Severity:"
|
|
59159
59560
|
}, undefined, false, undefined, this),
|
|
59160
|
-
/* @__PURE__ */
|
|
59561
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59161
59562
|
color: selectedIssue.severity === "error" ? "red" : "yellow",
|
|
59162
59563
|
children: selectedIssue.severity
|
|
59163
59564
|
}, undefined, false, undefined, this)
|
|
59164
59565
|
]
|
|
59165
59566
|
}, undefined, true, undefined, this),
|
|
59166
|
-
selectedIssue.instanceName && /* @__PURE__ */
|
|
59567
|
+
selectedIssue.instanceName && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
|
|
59167
59568
|
gap: 1,
|
|
59168
59569
|
children: [
|
|
59169
|
-
/* @__PURE__ */
|
|
59570
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59170
59571
|
dimColor: true,
|
|
59171
59572
|
children: "├─"
|
|
59172
59573
|
}, undefined, false, undefined, this),
|
|
59173
|
-
/* @__PURE__ */
|
|
59574
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59174
59575
|
dimColor: true,
|
|
59175
59576
|
bold: true,
|
|
59176
59577
|
children: "Instance:"
|
|
59177
59578
|
}, undefined, false, undefined, this),
|
|
59178
|
-
/* @__PURE__ */
|
|
59579
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59179
59580
|
children: selectedIssue.instanceName
|
|
59180
59581
|
}, undefined, false, undefined, this)
|
|
59181
59582
|
]
|
|
59182
59583
|
}, undefined, true, undefined, this),
|
|
59183
|
-
/* @__PURE__ */
|
|
59584
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
|
|
59184
59585
|
gap: 1,
|
|
59185
59586
|
children: [
|
|
59186
|
-
/* @__PURE__ */
|
|
59587
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59187
59588
|
dimColor: true,
|
|
59188
59589
|
children: "├─"
|
|
59189
59590
|
}, undefined, false, undefined, this),
|
|
59190
|
-
/* @__PURE__ */
|
|
59591
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59191
59592
|
dimColor: true,
|
|
59192
59593
|
bold: true,
|
|
59193
59594
|
children: "Detail:"
|
|
59194
59595
|
}, undefined, false, undefined, this),
|
|
59195
|
-
/* @__PURE__ */
|
|
59596
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59196
59597
|
children: selectedIssue.message
|
|
59197
59598
|
}, undefined, false, undefined, this)
|
|
59198
59599
|
]
|
|
59199
59600
|
}, undefined, true, undefined, this),
|
|
59200
|
-
selectedIssue.
|
|
59601
|
+
selectedIssue.detail && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
|
|
59201
59602
|
gap: 1,
|
|
59202
59603
|
children: [
|
|
59203
|
-
/* @__PURE__ */
|
|
59604
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59605
|
+
dimColor: true,
|
|
59606
|
+
children: "├─"
|
|
59607
|
+
}, undefined, false, undefined, this),
|
|
59608
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59609
|
+
dimColor: true,
|
|
59610
|
+
bold: true,
|
|
59611
|
+
children: "Info:"
|
|
59612
|
+
}, undefined, false, undefined, this),
|
|
59613
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59614
|
+
dimColor: true,
|
|
59615
|
+
children: selectedIssue.detail
|
|
59616
|
+
}, undefined, false, undefined, this)
|
|
59617
|
+
]
|
|
59618
|
+
}, undefined, true, undefined, this),
|
|
59619
|
+
selectedIssue.resolutionHint && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
|
|
59620
|
+
gap: 1,
|
|
59621
|
+
children: [
|
|
59622
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59204
59623
|
dimColor: true,
|
|
59205
59624
|
children: "└─"
|
|
59206
59625
|
}, undefined, false, undefined, this),
|
|
59207
|
-
/* @__PURE__ */
|
|
59626
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59208
59627
|
dimColor: true,
|
|
59209
59628
|
bold: true,
|
|
59210
59629
|
children: "Fix:"
|
|
59211
59630
|
}, undefined, false, undefined, this),
|
|
59212
|
-
/* @__PURE__ */
|
|
59631
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59213
59632
|
dimColor: true,
|
|
59214
59633
|
children: selectedIssue.resolutionHint
|
|
59215
59634
|
}, undefined, false, undefined, this)
|
|
@@ -59217,18 +59636,18 @@ var import_react76, jsx_dev_runtime17, HealthScreen = ({
|
|
|
59217
59636
|
}, undefined, true, undefined, this)
|
|
59218
59637
|
]
|
|
59219
59638
|
}, undefined, true, undefined, this),
|
|
59220
|
-
/* @__PURE__ */
|
|
59639
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
|
|
59221
59640
|
marginTop: 1,
|
|
59222
|
-
children: /* @__PURE__ */
|
|
59641
|
+
children: /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59223
59642
|
dimColor: true,
|
|
59224
59643
|
children: "d dismiss │ ESC back"
|
|
59225
59644
|
}, undefined, false, undefined, this)
|
|
59226
59645
|
}, undefined, false, undefined, this)
|
|
59227
59646
|
]
|
|
59228
59647
|
}, undefined, true, undefined, this),
|
|
59229
|
-
/* @__PURE__ */
|
|
59648
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
|
|
59230
59649
|
marginTop: 1,
|
|
59231
|
-
children: /* @__PURE__ */
|
|
59650
|
+
children: /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
|
|
59232
59651
|
dimColor: true,
|
|
59233
59652
|
children: "ESC to go back"
|
|
59234
59653
|
}, undefined, false, undefined, this)
|
|
@@ -59237,16 +59656,20 @@ var import_react76, jsx_dev_runtime17, HealthScreen = ({
|
|
|
59237
59656
|
}, undefined, true, undefined, this);
|
|
59238
59657
|
};
|
|
59239
59658
|
var init_HealthScreen = __esm(async () => {
|
|
59240
|
-
init_useAnimations();
|
|
59241
59659
|
await __promiseAll([
|
|
59242
59660
|
init_build2(),
|
|
59661
|
+
init_build3(),
|
|
59243
59662
|
init_Header(),
|
|
59244
59663
|
init_StatusBar(),
|
|
59245
|
-
init_IssueCard(),
|
|
59246
59664
|
init_useNavigation()
|
|
59247
59665
|
]);
|
|
59248
59666
|
import_react76 = __toESM(require_react(), 1);
|
|
59249
|
-
|
|
59667
|
+
jsx_dev_runtime16 = __toESM(require_jsx_dev_runtime(), 1);
|
|
59668
|
+
SEVERITY_ICONS = {
|
|
59669
|
+
error: "❌",
|
|
59670
|
+
warning: "⚠",
|
|
59671
|
+
info: "ℹ️"
|
|
59672
|
+
};
|
|
59250
59673
|
});
|
|
59251
59674
|
|
|
59252
59675
|
// src/ink/screens/UpdateScreen.tsx
|
|
@@ -59257,59 +59680,59 @@ function VersionCard({
|
|
|
59257
59680
|
hasUpdate,
|
|
59258
59681
|
failed
|
|
59259
59682
|
}) {
|
|
59260
|
-
return /* @__PURE__ */
|
|
59683
|
+
return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
59261
59684
|
flexDirection: "column",
|
|
59262
59685
|
marginTop: 1,
|
|
59263
59686
|
children: [
|
|
59264
|
-
/* @__PURE__ */
|
|
59265
|
-
children: /* @__PURE__ */
|
|
59687
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
59688
|
+
children: /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Text, {
|
|
59266
59689
|
bold: true,
|
|
59267
59690
|
children: label
|
|
59268
59691
|
}, undefined, false, undefined, this)
|
|
59269
59692
|
}, undefined, false, undefined, this),
|
|
59270
|
-
/* @__PURE__ */
|
|
59693
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
59271
59694
|
marginLeft: 2,
|
|
59272
59695
|
children: [
|
|
59273
|
-
/* @__PURE__ */
|
|
59696
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Text, {
|
|
59274
59697
|
dimColor: true,
|
|
59275
59698
|
children: "Current: "
|
|
59276
59699
|
}, undefined, false, undefined, this),
|
|
59277
|
-
/* @__PURE__ */
|
|
59700
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Text, {
|
|
59278
59701
|
color: failed ? "red" : hasUpdate ? "yellow" : "green",
|
|
59279
59702
|
children: current || (failed ? "check failed" : "not installed")
|
|
59280
59703
|
}, undefined, false, undefined, this)
|
|
59281
59704
|
]
|
|
59282
59705
|
}, undefined, true, undefined, this),
|
|
59283
|
-
/* @__PURE__ */
|
|
59706
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
59284
59707
|
marginLeft: 2,
|
|
59285
59708
|
children: [
|
|
59286
|
-
/* @__PURE__ */
|
|
59709
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Text, {
|
|
59287
59710
|
dimColor: true,
|
|
59288
59711
|
children: "Latest: "
|
|
59289
59712
|
}, undefined, false, undefined, this),
|
|
59290
|
-
/* @__PURE__ */
|
|
59713
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Text, {
|
|
59291
59714
|
bold: true,
|
|
59292
59715
|
children: latest || (failed ? "unreachable" : "unknown")
|
|
59293
59716
|
}, undefined, false, undefined, this)
|
|
59294
59717
|
]
|
|
59295
59718
|
}, undefined, true, undefined, this),
|
|
59296
|
-
failed && /* @__PURE__ */
|
|
59719
|
+
failed && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
59297
59720
|
marginLeft: 2,
|
|
59298
|
-
children: /* @__PURE__ */
|
|
59721
|
+
children: /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Text, {
|
|
59299
59722
|
color: "red",
|
|
59300
59723
|
children: "✗ Could not reach npm registry"
|
|
59301
59724
|
}, undefined, false, undefined, this)
|
|
59302
59725
|
}, undefined, false, undefined, this),
|
|
59303
|
-
!failed && hasUpdate && /* @__PURE__ */
|
|
59726
|
+
!failed && hasUpdate && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
59304
59727
|
marginLeft: 2,
|
|
59305
|
-
children: /* @__PURE__ */
|
|
59728
|
+
children: /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Text, {
|
|
59306
59729
|
color: "yellow",
|
|
59307
59730
|
children: "▲ Update available"
|
|
59308
59731
|
}, undefined, false, undefined, this)
|
|
59309
59732
|
}, undefined, false, undefined, this),
|
|
59310
|
-
!failed && !hasUpdate && current && /* @__PURE__ */
|
|
59733
|
+
!failed && !hasUpdate && current && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
59311
59734
|
marginLeft: 2,
|
|
59312
|
-
children: /* @__PURE__ */
|
|
59735
|
+
children: /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Text, {
|
|
59313
59736
|
color: "green",
|
|
59314
59737
|
children: "✓ Up to date"
|
|
59315
59738
|
}, undefined, false, undefined, this)
|
|
@@ -59317,7 +59740,7 @@ function VersionCard({
|
|
|
59317
59740
|
]
|
|
59318
59741
|
}, undefined, true, undefined, this);
|
|
59319
59742
|
}
|
|
59320
|
-
var import_react77,
|
|
59743
|
+
var import_react77, jsx_dev_runtime17, UpdateScreen = ({ onBack }) => {
|
|
59321
59744
|
const { exit } = use_app_default();
|
|
59322
59745
|
const fadeIn = useFadeIn();
|
|
59323
59746
|
const { error, success, setError, setSuccess, clear } = useMessage();
|
|
@@ -59390,41 +59813,41 @@ var import_react77, jsx_dev_runtime18, UpdateScreen = ({ onBack }) => {
|
|
|
59390
59813
|
return null;
|
|
59391
59814
|
if (step === "loading" || step === "check-failed") {
|
|
59392
59815
|
const isFailed = step === "check-failed";
|
|
59393
|
-
return /* @__PURE__ */
|
|
59816
|
+
return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
59394
59817
|
flexDirection: "column",
|
|
59395
59818
|
width: "100",
|
|
59396
59819
|
paddingX: 2,
|
|
59397
59820
|
paddingY: 1,
|
|
59398
59821
|
children: [
|
|
59399
|
-
/* @__PURE__ */
|
|
59822
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Header, {
|
|
59400
59823
|
title: "\uD83D\uDCE6 Updates"
|
|
59401
59824
|
}, undefined, false, undefined, this),
|
|
59402
|
-
isFailed ? /* @__PURE__ */
|
|
59825
|
+
isFailed ? /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(jsx_dev_runtime17.Fragment, {
|
|
59403
59826
|
children: [
|
|
59404
|
-
multiInfo && /* @__PURE__ */
|
|
59827
|
+
multiInfo && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(VersionCard, {
|
|
59405
59828
|
label: "claude-multi",
|
|
59406
59829
|
current: multiInfo.current || null,
|
|
59407
59830
|
latest: multiInfo.latest,
|
|
59408
59831
|
hasUpdate: multiInfo.updateAvailable,
|
|
59409
59832
|
failed: !multiInfo.current && !multiInfo.latest
|
|
59410
59833
|
}, undefined, false, undefined, this),
|
|
59411
|
-
claudeInfo && /* @__PURE__ */
|
|
59834
|
+
claudeInfo && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(VersionCard, {
|
|
59412
59835
|
label: "@anthropic-ai/claude-code",
|
|
59413
59836
|
current: claudeInfo.current,
|
|
59414
59837
|
latest: claudeInfo.latest,
|
|
59415
59838
|
hasUpdate: claudeInfo.updateAvailable,
|
|
59416
59839
|
failed: !claudeInfo.current && !claudeInfo.latest
|
|
59417
59840
|
}, undefined, false, undefined, this),
|
|
59418
|
-
error && /* @__PURE__ */
|
|
59841
|
+
error && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
59419
59842
|
marginTop: 1,
|
|
59420
|
-
children: /* @__PURE__ */
|
|
59843
|
+
children: /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(StatusBar, {
|
|
59421
59844
|
message: error,
|
|
59422
59845
|
type: "error"
|
|
59423
59846
|
}, undefined, false, undefined, this)
|
|
59424
59847
|
}, undefined, false, undefined, this),
|
|
59425
|
-
/* @__PURE__ */
|
|
59848
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
59426
59849
|
marginTop: 1,
|
|
59427
|
-
children: /* @__PURE__ */
|
|
59850
|
+
children: /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Select, {
|
|
59428
59851
|
options: [
|
|
59429
59852
|
{ label: "\uD83D\uDD04 Retry", value: "recheck" },
|
|
59430
59853
|
{ label: "↩️ Back to menu", value: "back" }
|
|
@@ -59442,9 +59865,9 @@ var import_react77, jsx_dev_runtime18, UpdateScreen = ({ onBack }) => {
|
|
|
59442
59865
|
}, undefined, false, undefined, this)
|
|
59443
59866
|
}, undefined, false, undefined, this)
|
|
59444
59867
|
]
|
|
59445
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */
|
|
59868
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
59446
59869
|
marginTop: 1,
|
|
59447
|
-
children: /* @__PURE__ */
|
|
59870
|
+
children: /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Spinner, {
|
|
59448
59871
|
label: "Checking for updates..."
|
|
59449
59872
|
}, undefined, false, undefined, this)
|
|
59450
59873
|
}, undefined, false, undefined, this)
|
|
@@ -59452,24 +59875,24 @@ var import_react77, jsx_dev_runtime18, UpdateScreen = ({ onBack }) => {
|
|
|
59452
59875
|
}, undefined, true, undefined, this);
|
|
59453
59876
|
}
|
|
59454
59877
|
if (step === "updating") {
|
|
59455
|
-
return /* @__PURE__ */
|
|
59878
|
+
return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
59456
59879
|
flexDirection: "column",
|
|
59457
59880
|
width: "100",
|
|
59458
59881
|
paddingX: 2,
|
|
59459
59882
|
paddingY: 1,
|
|
59460
59883
|
children: [
|
|
59461
|
-
/* @__PURE__ */
|
|
59884
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Header, {
|
|
59462
59885
|
title: "\uD83D\uDCE6 Updates"
|
|
59463
59886
|
}, undefined, false, undefined, this),
|
|
59464
|
-
/* @__PURE__ */
|
|
59887
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
59465
59888
|
marginTop: 1,
|
|
59466
|
-
children: /* @__PURE__ */
|
|
59889
|
+
children: /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Spinner, {
|
|
59467
59890
|
label: `Updating ${updatingTarget === "multi" ? "claude-multi" : "@anthropic-ai/claude-code"}...`
|
|
59468
59891
|
}, undefined, false, undefined, this)
|
|
59469
59892
|
}, undefined, false, undefined, this),
|
|
59470
|
-
/* @__PURE__ */
|
|
59893
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
59471
59894
|
marginTop: 1,
|
|
59472
|
-
children: /* @__PURE__ */
|
|
59895
|
+
children: /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Text, {
|
|
59473
59896
|
dimColor: true,
|
|
59474
59897
|
children: "Do not press ESC: update in progress"
|
|
59475
59898
|
}, undefined, false, undefined, this)
|
|
@@ -59488,44 +59911,44 @@ var import_react77, jsx_dev_runtime18, UpdateScreen = ({ onBack }) => {
|
|
|
59488
59911
|
}
|
|
59489
59912
|
actionOptions.push({ label: "\uD83D\uDD04 Re-check versions", value: "recheck" });
|
|
59490
59913
|
actionOptions.push({ label: "↩️ Back to menu", value: "back" });
|
|
59491
|
-
return /* @__PURE__ */
|
|
59914
|
+
return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
59492
59915
|
flexDirection: "column",
|
|
59493
59916
|
width: "100",
|
|
59494
59917
|
paddingX: 2,
|
|
59495
59918
|
paddingY: 1,
|
|
59496
59919
|
children: [
|
|
59497
|
-
/* @__PURE__ */
|
|
59920
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Header, {
|
|
59498
59921
|
title: "\uD83D\uDCE6 Updates"
|
|
59499
59922
|
}, undefined, false, undefined, this),
|
|
59500
|
-
/* @__PURE__ */
|
|
59923
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(VersionCard, {
|
|
59501
59924
|
label: "claude-multi",
|
|
59502
59925
|
current: multiInfo?.current ?? null,
|
|
59503
59926
|
latest: multiInfo?.latest ?? "",
|
|
59504
59927
|
hasUpdate: multiUpdate
|
|
59505
59928
|
}, undefined, false, undefined, this),
|
|
59506
|
-
/* @__PURE__ */
|
|
59929
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(VersionCard, {
|
|
59507
59930
|
label: "@anthropic-ai/claude-code",
|
|
59508
59931
|
current: claudeInfo?.current ?? null,
|
|
59509
59932
|
latest: claudeInfo?.latest ?? "",
|
|
59510
59933
|
hasUpdate: claudeUpdate
|
|
59511
59934
|
}, undefined, false, undefined, this),
|
|
59512
|
-
error && /* @__PURE__ */
|
|
59935
|
+
error && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
59513
59936
|
marginTop: 1,
|
|
59514
|
-
children: /* @__PURE__ */
|
|
59937
|
+
children: /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(StatusBar, {
|
|
59515
59938
|
message: error,
|
|
59516
59939
|
type: "error"
|
|
59517
59940
|
}, undefined, false, undefined, this)
|
|
59518
59941
|
}, undefined, false, undefined, this),
|
|
59519
|
-
success && /* @__PURE__ */
|
|
59942
|
+
success && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
59520
59943
|
marginTop: 1,
|
|
59521
|
-
children: /* @__PURE__ */
|
|
59944
|
+
children: /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(StatusBar, {
|
|
59522
59945
|
message: success,
|
|
59523
59946
|
type: "success"
|
|
59524
59947
|
}, undefined, false, undefined, this)
|
|
59525
59948
|
}, undefined, false, undefined, this),
|
|
59526
|
-
/* @__PURE__ */
|
|
59949
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
59527
59950
|
marginTop: 1,
|
|
59528
|
-
children: /* @__PURE__ */
|
|
59951
|
+
children: /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Select, {
|
|
59529
59952
|
options: actionOptions,
|
|
59530
59953
|
onChange: (value) => {
|
|
59531
59954
|
if (value === "back") {
|
|
@@ -59543,7 +59966,7 @@ var import_react77, jsx_dev_runtime18, UpdateScreen = ({ onBack }) => {
|
|
|
59543
59966
|
}
|
|
59544
59967
|
}, undefined, false, undefined, this)
|
|
59545
59968
|
}, undefined, false, undefined, this),
|
|
59546
|
-
/* @__PURE__ */
|
|
59969
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Footer, {}, undefined, false, undefined, this)
|
|
59547
59970
|
]
|
|
59548
59971
|
}, undefined, true, undefined, this);
|
|
59549
59972
|
};
|
|
@@ -59559,7 +59982,7 @@ var init_UpdateScreen = __esm(async () => {
|
|
|
59559
59982
|
init_Footer()
|
|
59560
59983
|
]);
|
|
59561
59984
|
import_react77 = __toESM(require_react(), 1);
|
|
59562
|
-
|
|
59985
|
+
jsx_dev_runtime17 = __toESM(require_jsx_dev_runtime(), 1);
|
|
59563
59986
|
});
|
|
59564
59987
|
|
|
59565
59988
|
// src/ink/App.tsx
|
|
@@ -59567,75 +59990,59 @@ var exports_App = {};
|
|
|
59567
59990
|
__export(exports_App, {
|
|
59568
59991
|
App: () => App2
|
|
59569
59992
|
});
|
|
59570
|
-
|
|
59571
|
-
import { existsSync as existsSync8 } from "node:fs";
|
|
59572
|
-
var import_react78, jsx_dev_runtime19, GoodbyeScreen = () => {
|
|
59993
|
+
var import_react78, jsx_dev_runtime18, GoodbyeScreen = () => {
|
|
59573
59994
|
const msg = useTypewriter("\uD83D\uDC4B Goodbye!", 40);
|
|
59574
|
-
return /* @__PURE__ */
|
|
59995
|
+
return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
|
|
59575
59996
|
paddingX: 2,
|
|
59576
59997
|
paddingY: 1,
|
|
59577
|
-
children: /* @__PURE__ */
|
|
59998
|
+
children: /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
|
|
59578
59999
|
dimColor: true,
|
|
59579
60000
|
children: msg
|
|
59580
60001
|
}, undefined, false, undefined, this)
|
|
59581
60002
|
}, undefined, false, undefined, this);
|
|
59582
|
-
}, DoctorResultScreen = ({ fixedCount, migratedCount,
|
|
60003
|
+
}, DoctorResultScreen = ({ fixedCount, migratedCount, onBack }) => {
|
|
59583
60004
|
useNavigation(onBack);
|
|
59584
|
-
return /* @__PURE__ */
|
|
60005
|
+
return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
|
|
59585
60006
|
flexDirection: "column",
|
|
59586
60007
|
width: "100",
|
|
59587
60008
|
paddingX: 2,
|
|
59588
60009
|
paddingY: 1,
|
|
59589
60010
|
children: [
|
|
59590
|
-
/* @__PURE__ */
|
|
59591
|
-
title: "
|
|
60011
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Header, {
|
|
60012
|
+
title: "Doctor Fix"
|
|
59592
60013
|
}, undefined, false, undefined, this),
|
|
59593
|
-
|
|
59594
|
-
children: [
|
|
59595
|
-
/* @__PURE__ */ jsx_dev_runtime19.jsxDEV(StatusBar, {
|
|
59596
|
-
message: "Failed to install pinned Claude binary",
|
|
59597
|
-
type: "error"
|
|
59598
|
-
}, undefined, false, undefined, this),
|
|
59599
|
-
/* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
|
|
59600
|
-
marginTop: 1,
|
|
59601
|
-
children: /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
|
|
59602
|
-
dimColor: true,
|
|
59603
|
-
children: "Check your network connection and try again."
|
|
59604
|
-
}, undefined, false, undefined, this)
|
|
59605
|
-
}, undefined, false, undefined, this)
|
|
59606
|
-
]
|
|
59607
|
-
}, undefined, true, undefined, this) : fixedCount > 0 || migratedCount > 0 ? /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(jsx_dev_runtime19.Fragment, {
|
|
60014
|
+
fixedCount > 0 || migratedCount > 0 ? /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(jsx_dev_runtime18.Fragment, {
|
|
59608
60015
|
children: [
|
|
59609
|
-
fixedCount > 0 && /* @__PURE__ */
|
|
60016
|
+
fixedCount > 0 && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(jsx_dev_runtime18.Fragment, {
|
|
59610
60017
|
children: [
|
|
59611
|
-
/* @__PURE__ */
|
|
59612
|
-
message: `Fixed ${fixedCount} wrapper(s) to use
|
|
60018
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV(StatusBar, {
|
|
60019
|
+
message: `Fixed ${fixedCount} wrapper(s) to use global Claude binary`,
|
|
59613
60020
|
type: "success"
|
|
59614
60021
|
}, undefined, false, undefined, this),
|
|
59615
|
-
/* @__PURE__ */
|
|
60022
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
|
|
59616
60023
|
marginTop: 1,
|
|
59617
|
-
children: /* @__PURE__ */
|
|
60024
|
+
children: /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
|
|
59618
60025
|
dimColor: true,
|
|
59619
|
-
children: "All
|
|
60026
|
+
children: "All instances now use the globally installed Claude binary."
|
|
59620
60027
|
}, undefined, false, undefined, this)
|
|
59621
60028
|
}, undefined, false, undefined, this)
|
|
59622
60029
|
]
|
|
59623
60030
|
}, undefined, true, undefined, this),
|
|
59624
|
-
migratedCount > 0 && /* @__PURE__ */
|
|
60031
|
+
migratedCount > 0 && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
|
|
59625
60032
|
marginTop: fixedCount > 0 ? 1 : 0,
|
|
59626
|
-
children: /* @__PURE__ */
|
|
60033
|
+
children: /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(StatusBar, {
|
|
59627
60034
|
message: `Migrated ${migratedCount} instance(s) to v${getClaudeMultiVersion()}`,
|
|
59628
60035
|
type: "success"
|
|
59629
60036
|
}, undefined, false, undefined, this)
|
|
59630
60037
|
}, undefined, false, undefined, this)
|
|
59631
60038
|
]
|
|
59632
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */
|
|
60039
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(StatusBar, {
|
|
59633
60040
|
message: "All wrappers already use the correct Claude version",
|
|
59634
60041
|
type: "info"
|
|
59635
60042
|
}, undefined, false, undefined, this),
|
|
59636
|
-
/* @__PURE__ */
|
|
60043
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
|
|
59637
60044
|
marginTop: 1,
|
|
59638
|
-
children: /* @__PURE__ */
|
|
60045
|
+
children: /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
|
|
59639
60046
|
dimColor: true,
|
|
59640
60047
|
children: "ESC to go back"
|
|
59641
60048
|
}, undefined, false, undefined, this)
|
|
@@ -59646,9 +60053,9 @@ var import_react78, jsx_dev_runtime19, GoodbyeScreen = () => {
|
|
|
59646
60053
|
const visible = useFadeIn(100);
|
|
59647
60054
|
if (!visible || instances2.length === 0)
|
|
59648
60055
|
return null;
|
|
59649
|
-
return /* @__PURE__ */
|
|
60056
|
+
return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
|
|
59650
60057
|
marginBottom: 1,
|
|
59651
|
-
children: /* @__PURE__ */
|
|
60058
|
+
children: /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
|
|
59652
60059
|
dimColor: true,
|
|
59653
60060
|
children: [
|
|
59654
60061
|
instances2.length,
|
|
@@ -59660,23 +60067,15 @@ var import_react78, jsx_dev_runtime19, GoodbyeScreen = () => {
|
|
|
59660
60067
|
}, undefined, false, undefined, this);
|
|
59661
60068
|
}, App2 = () => {
|
|
59662
60069
|
const { exit } = use_app_default();
|
|
59663
|
-
const { instances: instances2, loading, migrationStatus, instanceMigrationVersion } = useConfig();
|
|
60070
|
+
const { instances: instances2, loading, migrationStatus, instanceMigrationVersion, reload } = useConfig();
|
|
59664
60071
|
const { issues, dismiss, dismissAll, retry } = useHealthCheck(instances2, migrationStatus, instanceMigrationVersion);
|
|
59665
60072
|
const [screen, setScreen] = import_react78.useState("menu");
|
|
59666
60073
|
const [menuKey, setMenuKey] = import_react78.useState(0);
|
|
59667
|
-
const [ccVersion] = import_react78.useState(() => {
|
|
59668
|
-
try {
|
|
59669
|
-
const output = execSync3("claude --version 2>/dev/null", { encoding: "utf-8", timeout: 5000 }).trim();
|
|
59670
|
-
return output.split(" ")[0] || null;
|
|
59671
|
-
} catch {
|
|
59672
|
-
return null;
|
|
59673
|
-
}
|
|
59674
|
-
});
|
|
59675
60074
|
const [doctorResult, setDoctorResult] = import_react78.useState({
|
|
59676
60075
|
fixedCount: 0,
|
|
59677
|
-
migratedCount: 0
|
|
59678
|
-
installFailed: false
|
|
60076
|
+
migratedCount: 0
|
|
59679
60077
|
});
|
|
60078
|
+
const [doctorRunning, setDoctorRunning] = import_react78.useState(false);
|
|
59680
60079
|
use_input_default((input, key) => {
|
|
59681
60080
|
if (screen !== "menu")
|
|
59682
60081
|
return;
|
|
@@ -59688,10 +60087,10 @@ var import_react78, jsx_dev_runtime19, GoodbyeScreen = () => {
|
|
|
59688
60087
|
}
|
|
59689
60088
|
});
|
|
59690
60089
|
if (loading) {
|
|
59691
|
-
return /* @__PURE__ */
|
|
60090
|
+
return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
|
|
59692
60091
|
paddingX: 2,
|
|
59693
60092
|
paddingY: 1,
|
|
59694
|
-
children: /* @__PURE__ */
|
|
60093
|
+
children: /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Spinner, {
|
|
59695
60094
|
label: "Loading..."
|
|
59696
60095
|
}, undefined, false, undefined, this)
|
|
59697
60096
|
}, undefined, false, undefined, this);
|
|
@@ -59701,45 +60100,35 @@ var import_react78, jsx_dev_runtime19, GoodbyeScreen = () => {
|
|
|
59701
60100
|
setMenuKey((k) => k + 1);
|
|
59702
60101
|
};
|
|
59703
60102
|
const handleDoctorFix = async () => {
|
|
59704
|
-
|
|
59705
|
-
|
|
60103
|
+
if (doctorRunning)
|
|
60104
|
+
return;
|
|
60105
|
+
setDoctorRunning(true);
|
|
60106
|
+
try {
|
|
60107
|
+
const fixed = fixWrapperVersions(instances2);
|
|
60108
|
+
let migrated = 0;
|
|
59706
60109
|
try {
|
|
59707
|
-
|
|
59708
|
-
|
|
59709
|
-
|
|
59710
|
-
|
|
59711
|
-
|
|
59712
|
-
|
|
59713
|
-
|
|
59714
|
-
|
|
59715
|
-
installPinnedClaude();
|
|
59716
|
-
} catch {
|
|
59717
|
-
installFailed = true;
|
|
60110
|
+
const fullConfig = await loadConfig();
|
|
60111
|
+
if (needsInstanceMigration(fullConfig)) {
|
|
60112
|
+
const before2 = fullConfig.instanceMigrationVersion;
|
|
60113
|
+
const migratedConfig = await runInstanceMigrations(fullConfig);
|
|
60114
|
+
if (migratedConfig.instanceMigrationVersion !== before2) {
|
|
60115
|
+
await saveConfigAtomic(migratedConfig);
|
|
60116
|
+
migrated = fullConfig.instances.length;
|
|
60117
|
+
}
|
|
59718
60118
|
}
|
|
59719
|
-
}
|
|
60119
|
+
} catch {}
|
|
60120
|
+
setDoctorResult({ fixedCount: fixed.length, migratedCount: migrated });
|
|
60121
|
+
await reload();
|
|
60122
|
+
setScreen("doctor-result");
|
|
60123
|
+
} finally {
|
|
60124
|
+
setDoctorRunning(false);
|
|
59720
60125
|
}
|
|
59721
|
-
const fixed = installFailed ? [] : fixWrapperVersions(instances2);
|
|
59722
|
-
let migrated = 0;
|
|
59723
|
-
try {
|
|
59724
|
-
const fullConfig = await loadConfig();
|
|
59725
|
-
if (needsInstanceMigration(fullConfig)) {
|
|
59726
|
-
const before2 = fullConfig.instanceMigrationVersion;
|
|
59727
|
-
const migratedConfig = await runInstanceMigrations(fullConfig);
|
|
59728
|
-
if (migratedConfig.instanceMigrationVersion !== before2) {
|
|
59729
|
-
await saveConfigAtomic(migratedConfig);
|
|
59730
|
-
migrated = fullConfig.instances.length;
|
|
59731
|
-
}
|
|
59732
|
-
}
|
|
59733
|
-
} catch {}
|
|
59734
|
-
setDoctorResult({ fixedCount: fixed.length, migratedCount: migrated, installFailed });
|
|
59735
|
-
retry();
|
|
59736
|
-
setScreen("doctor-result");
|
|
59737
60126
|
};
|
|
59738
60127
|
if (screen === "goodbye") {
|
|
59739
|
-
return /* @__PURE__ */
|
|
60128
|
+
return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(GoodbyeScreen, {}, undefined, false, undefined, this);
|
|
59740
60129
|
}
|
|
59741
60130
|
if (screen === "health") {
|
|
59742
|
-
return /* @__PURE__ */
|
|
60131
|
+
return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(HealthScreen, {
|
|
59743
60132
|
issues,
|
|
59744
60133
|
onDismiss: dismiss,
|
|
59745
60134
|
onDismissAll: dismissAll,
|
|
@@ -59749,17 +60138,16 @@ var import_react78, jsx_dev_runtime19, GoodbyeScreen = () => {
|
|
|
59749
60138
|
}, undefined, false, undefined, this);
|
|
59750
60139
|
}
|
|
59751
60140
|
if (screen === "doctor-result") {
|
|
59752
|
-
return /* @__PURE__ */
|
|
60141
|
+
return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(DoctorResultScreen, {
|
|
59753
60142
|
fixedCount: doctorResult.fixedCount,
|
|
59754
60143
|
migratedCount: doctorResult.migratedCount,
|
|
59755
|
-
installFailed: doctorResult.installFailed,
|
|
59756
60144
|
onBack: goToMenu
|
|
59757
60145
|
}, undefined, false, undefined, this);
|
|
59758
60146
|
}
|
|
59759
60147
|
if (screen !== "menu") {
|
|
59760
60148
|
const ScreenComponent = SCREEN_MAP[screen];
|
|
59761
60149
|
if (ScreenComponent) {
|
|
59762
|
-
return /* @__PURE__ */
|
|
60150
|
+
return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(ScreenComponent, {
|
|
59763
60151
|
onBack: goToMenu
|
|
59764
60152
|
}, undefined, false, undefined, this);
|
|
59765
60153
|
}
|
|
@@ -59790,44 +60178,26 @@ var import_react78, jsx_dev_runtime19, GoodbyeScreen = () => {
|
|
|
59790
60178
|
{ label: "\uD83D\uDCE6 Check for updates", value: "update" },
|
|
59791
60179
|
{ label: "\uD83D\uDEAA Exit", value: "exit" }
|
|
59792
60180
|
];
|
|
59793
|
-
return /* @__PURE__ */
|
|
60181
|
+
return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
|
|
59794
60182
|
flexDirection: "column",
|
|
59795
60183
|
width: "100",
|
|
59796
60184
|
paddingX: 2,
|
|
59797
60185
|
paddingY: 1,
|
|
59798
60186
|
children: [
|
|
59799
|
-
/* @__PURE__ */
|
|
60187
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Header, {
|
|
59800
60188
|
title: "\uD83E\uDD16 Claude Multi",
|
|
59801
60189
|
subtitle: "Interactive Mode"
|
|
59802
60190
|
}, undefined, false, undefined, this),
|
|
59803
|
-
/* @__PURE__ */
|
|
60191
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV(WarningBanner, {
|
|
59804
60192
|
issueCount: issues.length,
|
|
59805
60193
|
errorCount,
|
|
59806
60194
|
warningCount,
|
|
59807
60195
|
hasVersionIssues
|
|
59808
60196
|
}, undefined, false, undefined, this),
|
|
59809
|
-
|
|
59810
|
-
marginBottom: 1,
|
|
59811
|
-
children: [
|
|
59812
|
-
/* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
|
|
59813
|
-
color: "red",
|
|
59814
|
-
bold: true,
|
|
59815
|
-
children: [
|
|
59816
|
-
"⚠ Claude Code v",
|
|
59817
|
-
ccVersion,
|
|
59818
|
-
" does not work with 3rd-party APIs. "
|
|
59819
|
-
]
|
|
59820
|
-
}, undefined, true, undefined, this),
|
|
59821
|
-
/* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
|
|
59822
|
-
color: "red",
|
|
59823
|
-
children: "Run 'claude-multi doctor fix' to install a compatible version."
|
|
59824
|
-
}, undefined, false, undefined, this)
|
|
59825
|
-
]
|
|
59826
|
-
}, undefined, true, undefined, this),
|
|
59827
|
-
/* @__PURE__ */ jsx_dev_runtime19.jsxDEV(InstanceLine, {
|
|
60197
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV(InstanceLine, {
|
|
59828
60198
|
instances: instances2
|
|
59829
60199
|
}, undefined, false, undefined, this),
|
|
59830
|
-
/* @__PURE__ */
|
|
60200
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Select, {
|
|
59831
60201
|
options: menuOptions,
|
|
59832
60202
|
visibleOptionCount: menuOptions.length,
|
|
59833
60203
|
onChange: async (value) => {
|
|
@@ -59843,7 +60213,7 @@ var import_react78, jsx_dev_runtime19, GoodbyeScreen = () => {
|
|
|
59843
60213
|
}
|
|
59844
60214
|
}
|
|
59845
60215
|
}, menuKey, false, undefined, this),
|
|
59846
|
-
/* @__PURE__ */
|
|
60216
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Footer, {
|
|
59847
60217
|
showHealthHint: issues.length > 0
|
|
59848
60218
|
}, undefined, false, undefined, this)
|
|
59849
60219
|
]
|
|
@@ -59851,7 +60221,6 @@ var import_react78, jsx_dev_runtime19, GoodbyeScreen = () => {
|
|
|
59851
60221
|
}, SCREEN_MAP;
|
|
59852
60222
|
var init_App2 = __esm(async () => {
|
|
59853
60223
|
init_version();
|
|
59854
|
-
init_paths();
|
|
59855
60224
|
init_useConfig();
|
|
59856
60225
|
init_useHealthCheck();
|
|
59857
60226
|
init_useAnimations();
|
|
@@ -59878,7 +60247,7 @@ var init_App2 = __esm(async () => {
|
|
|
59878
60247
|
init_UpdateScreen()
|
|
59879
60248
|
]);
|
|
59880
60249
|
import_react78 = __toESM(require_react(), 1);
|
|
59881
|
-
|
|
60250
|
+
jsx_dev_runtime18 = __toESM(require_jsx_dev_runtime(), 1);
|
|
59882
60251
|
SCREEN_MAP = {
|
|
59883
60252
|
add: AddInstance,
|
|
59884
60253
|
list: ListInstances,
|
|
@@ -59919,7 +60288,7 @@ init_errors();
|
|
|
59919
60288
|
init_constants();
|
|
59920
60289
|
var import_prompts = __toESM(require_prompts3(), 1);
|
|
59921
60290
|
import { homedir as homedir4 } from "node:os";
|
|
59922
|
-
import { join as join9 } from "node:path";
|
|
60291
|
+
import { join as join9, dirname as dirname5, delimiter } from "node:path";
|
|
59923
60292
|
function exitWithCode(code) {
|
|
59924
60293
|
process.exit(code);
|
|
59925
60294
|
}
|
|
@@ -59956,6 +60325,7 @@ program2.command("add <name>").description("Add a new Claude Code instance").opt
|
|
|
59956
60325
|
let providerTemplate = null;
|
|
59957
60326
|
let apiKey = "";
|
|
59958
60327
|
let autoSync = !options.manual;
|
|
60328
|
+
let providerRegion;
|
|
59959
60329
|
if (options.provider) {
|
|
59960
60330
|
providerTemplate = getProviderTemplate(options.provider);
|
|
59961
60331
|
if (!providerTemplate) {
|
|
@@ -59970,12 +60340,19 @@ program2.command("add <name>").description("Add a new Claude Code instance").opt
|
|
|
59970
60340
|
useProviderTemplate = true;
|
|
59971
60341
|
if (providerHasRegions(providerTemplate.name)) {
|
|
59972
60342
|
const region = options.region || "cn";
|
|
60343
|
+
if (!options.region) {
|
|
60344
|
+
const regions = getProviderRegions(providerTemplate.name);
|
|
60345
|
+
console.log(source_default.yellow(`⚠ No --region specified, defaulting to cn. Available: ${regions ? Object.keys(regions).join(", ") : "cn"}`));
|
|
60346
|
+
}
|
|
60347
|
+
providerRegion = region;
|
|
59973
60348
|
try {
|
|
59974
60349
|
providerTemplate = resolveRegionTemplate(providerTemplate, region);
|
|
59975
60350
|
} catch (err) {
|
|
59976
60351
|
console.error(source_default.red(`✗ ${toMessage(err)}`));
|
|
59977
60352
|
exitWithCode(1);
|
|
59978
60353
|
}
|
|
60354
|
+
} else if (options.region) {
|
|
60355
|
+
console.log(source_default.yellow(`⚠ --region is ignored for non-regional provider '${providerTemplate.name}'`));
|
|
59979
60356
|
}
|
|
59980
60357
|
}
|
|
59981
60358
|
if (options.copySettings || options.copyAll || options.copyMcp || options.skipPrompts || options.provider) {
|
|
@@ -60040,7 +60417,9 @@ Found existing Claude Code configuration at ~/.claude`));
|
|
|
60040
60417
|
binaryPath,
|
|
60041
60418
|
createdAt: new Date().toISOString(),
|
|
60042
60419
|
autoSync,
|
|
60043
|
-
createdWithVersion: getClaudeMultiVersion()
|
|
60420
|
+
createdWithVersion: getClaudeMultiVersion(),
|
|
60421
|
+
...useProviderTemplate && providerTemplate ? { providerTemplate: providerTemplate.name } : {},
|
|
60422
|
+
...providerRegion ? { providerRegion } : {}
|
|
60044
60423
|
};
|
|
60045
60424
|
await addInstance(instance);
|
|
60046
60425
|
try {
|
|
@@ -60080,9 +60459,9 @@ Found existing Claude Code configuration at ~/.claude`));
|
|
|
60080
60459
|
console.log(source_default.gray(` Binary: ${binaryPath}`));
|
|
60081
60460
|
console.log(source_default.gray(` Config: ${configDir}`));
|
|
60082
60461
|
console.log();
|
|
60083
|
-
const binDir =
|
|
60462
|
+
const binDir = dirname5(binaryPath);
|
|
60084
60463
|
const pathEnv = process.env.PATH || "";
|
|
60085
|
-
const isInPath = pathEnv.split(
|
|
60464
|
+
const isInPath = pathEnv.split(delimiter).some((p) => p === binDir);
|
|
60086
60465
|
if (!isInPath) {
|
|
60087
60466
|
console.log(source_default.yellow(`⚠ Warning: ${binDir} is not in your PATH`));
|
|
60088
60467
|
console.log(source_default.gray(`Add to PATH by running:`));
|
|
@@ -60136,6 +60515,10 @@ program2.command("list").alias("ls").description("List all Claude Code instances
|
|
|
60136
60515
|
console.log(source_default.gray(` Binary: ${instance.binaryPath}`));
|
|
60137
60516
|
console.log(source_default.gray(` Config: ${instance.configDir}`));
|
|
60138
60517
|
console.log(source_default.gray(` Created: ${new Date(instance.createdAt).toLocaleString()}`));
|
|
60518
|
+
if (instance.providerTemplate) {
|
|
60519
|
+
const region = instance.providerRegion ? ` (${instance.providerRegion})` : "";
|
|
60520
|
+
console.log(source_default.gray(` Provider: ${instance.providerTemplate}${region}`));
|
|
60521
|
+
}
|
|
60139
60522
|
const autoSyncStatus = instance.autoSync !== false ? source_default.green("on") : source_default.yellow("off");
|
|
60140
60523
|
console.log(source_default.gray(` Auto-sync: ${autoSyncStatus}`));
|
|
60141
60524
|
console.log(source_default.gray(` Version: ${formatVersionLabel(instance.createdWithVersion)}`));
|
|
@@ -60157,6 +60540,10 @@ program2.command("info <name>").description("Show details about a specific insta
|
|
|
60157
60540
|
const autoSyncStatus = instance.autoSync !== false ? source_default.green("✓ Enabled") : source_default.yellow("✗ Disabled");
|
|
60158
60541
|
console.log(`${source_default.gray("Auto-sync:")} ${autoSyncStatus}`);
|
|
60159
60542
|
console.log(`${source_default.gray("Version:")} ${formatVersionLabel(instance.createdWithVersion)}`);
|
|
60543
|
+
if (instance.providerTemplate) {
|
|
60544
|
+
const region = instance.providerRegion ? ` (${instance.providerRegion})` : "";
|
|
60545
|
+
console.log(`${source_default.gray("Provider:")} ${instance.providerTemplate}${region}`);
|
|
60546
|
+
}
|
|
60160
60547
|
} catch (error) {
|
|
60161
60548
|
console.error(source_default.red(`✗ Error: ${toMessage(error)}`));
|
|
60162
60549
|
exitWithCode(1);
|
|
@@ -60232,17 +60619,13 @@ program2.command("doctor").description("Diagnose and fix common issues").argumen
|
|
|
60232
60619
|
const [
|
|
60233
60620
|
instances2,
|
|
60234
60621
|
{ runHealthChecks: runHealthChecks2, fixWrapperVersions: fixWrapperVersions2 },
|
|
60235
|
-
{
|
|
60236
|
-
{ PINNED_CLAUDE_BIN: PINNED_CLAUDE_BIN2 },
|
|
60237
|
-
{ installPinnedClaude: installPinnedClaude2, getPinnedBinaryVersion: getPinnedBinaryVersion2, isThirdPartyApiBroken: isThirdPartyApiBroken2, COMPATIBLE_CLAUDE_VERSION: COMPATIBLE_CLAUDE_VERSION2 },
|
|
60622
|
+
{ tryGetClaudePath: tryGetClaudePath2 },
|
|
60238
60623
|
{ needsInstanceMigration: needsInstanceMigration2, runInstanceMigrations: runInstanceMigrations2 },
|
|
60239
60624
|
{ loadConfig: loadConfig2, saveConfigAtomic: saveConfigAtomic2 }
|
|
60240
60625
|
] = await Promise.all([
|
|
60241
60626
|
listInstances(),
|
|
60242
60627
|
Promise.resolve().then(() => (init_health(), exports_health)),
|
|
60243
|
-
|
|
60244
|
-
Promise.resolve().then(() => (init_paths(), exports_paths)),
|
|
60245
|
-
Promise.resolve().then(() => (init_version(), exports_version)),
|
|
60628
|
+
Promise.resolve().then(() => (init_wrapper(), exports_wrapper)),
|
|
60246
60629
|
Promise.resolve().then(() => (init_migration(), exports_migration)),
|
|
60247
60630
|
Promise.resolve().then(() => (init_config(), exports_config))
|
|
60248
60631
|
]);
|
|
@@ -60250,23 +60633,15 @@ program2.command("doctor").description("Diagnose and fix common issues").argumen
|
|
|
60250
60633
|
console.log(source_default.bold(`
|
|
60251
60634
|
\uD83D\uDD27 Doctor Fix
|
|
60252
60635
|
`));
|
|
60253
|
-
|
|
60254
|
-
|
|
60255
|
-
|
|
60256
|
-
|
|
60257
|
-
} else {
|
|
60258
|
-
const pinnedVer = getPinnedBinaryVersion2();
|
|
60259
|
-
const needsReinstall = !pinnedVer || isThirdPartyApiBroken2(pinnedVer) || pinnedVer !== COMPATIBLE_CLAUDE_VERSION2;
|
|
60260
|
-
if (needsReinstall) {
|
|
60261
|
-
const reason = !pinnedVer ? "version unknown" : isThirdPartyApiBroken2(pinnedVer) ? "incompatible" : "outdated";
|
|
60262
|
-
console.log(source_default.yellow(`Pinned binary is ${pinnedVer ? `v${pinnedVer}` : reason}. Reinstalling v${COMPATIBLE_CLAUDE_VERSION2}...`));
|
|
60263
|
-
installPinnedClaude2();
|
|
60264
|
-
console.log(source_default.green(`✓ Reinstalled pinned Claude v${COMPATIBLE_CLAUDE_VERSION2}`));
|
|
60265
|
-
}
|
|
60636
|
+
const claudePath = tryGetClaudePath2();
|
|
60637
|
+
if (!claudePath) {
|
|
60638
|
+
console.error(source_default.red("Claude Code not found in PATH. Please install it first."));
|
|
60639
|
+
process.exit(1);
|
|
60266
60640
|
}
|
|
60641
|
+
console.log(source_default.gray(`Using claude at: ${claudePath}`));
|
|
60267
60642
|
const fixed = fixWrapperVersions2(instances2);
|
|
60268
60643
|
if (fixed.length > 0) {
|
|
60269
|
-
console.log(source_default.green(`✓ Fixed ${fixed.length} wrapper(s) to use
|
|
60644
|
+
console.log(source_default.green(`✓ Fixed ${fixed.length} wrapper(s) to use resolved Claude version:`));
|
|
60270
60645
|
for (const name of fixed) {
|
|
60271
60646
|
console.log(source_default.gray(` • ${name}`));
|
|
60272
60647
|
}
|