claudish 6.6.2 → 6.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -13645,10 +13645,22 @@ function validateSessionPath(sessionPath) {
|
|
|
13645
13645
|
}
|
|
13646
13646
|
return resolved;
|
|
13647
13647
|
}
|
|
13648
|
+
function isSentinelModel(model) {
|
|
13649
|
+
const lower = model.toLowerCase();
|
|
13650
|
+
if (SENTINEL_MODELS.has(lower))
|
|
13651
|
+
return true;
|
|
13652
|
+
if (lower.startsWith("claude-"))
|
|
13653
|
+
return true;
|
|
13654
|
+
return false;
|
|
13655
|
+
}
|
|
13648
13656
|
function setupSession(sessionPath, models, input) {
|
|
13649
13657
|
if (models.length === 0) {
|
|
13650
13658
|
throw new Error("At least one model is required");
|
|
13651
13659
|
}
|
|
13660
|
+
const sentinels = models.filter(isSentinelModel);
|
|
13661
|
+
if (sentinels.length > 0) {
|
|
13662
|
+
throw new Error(`Invalid model(s) for team run: ${sentinels.join(", ")}. ` + `These are Claude Code agent selectors, not external model IDs. ` + `Use real external models (e.g., "gemini-2.0-flash", "gpt-4o", "or@deepseek/deepseek-r1"). ` + `For Claude models, use a Task agent instead of the team tool.`);
|
|
13663
|
+
}
|
|
13652
13664
|
mkdirSync(join(sessionPath, "work"), { recursive: true });
|
|
13653
13665
|
mkdirSync(join(sessionPath, "errors"), { recursive: true });
|
|
13654
13666
|
if (input !== undefined) {
|
|
@@ -13976,7 +13988,16 @@ function formatVerdict(verdict, sessionPath) {
|
|
|
13976
13988
|
}
|
|
13977
13989
|
return output;
|
|
13978
13990
|
}
|
|
13979
|
-
var
|
|
13991
|
+
var SENTINEL_MODELS;
|
|
13992
|
+
var init_team_orchestrator = __esm(() => {
|
|
13993
|
+
SENTINEL_MODELS = new Set([
|
|
13994
|
+
"internal",
|
|
13995
|
+
"default",
|
|
13996
|
+
"opus",
|
|
13997
|
+
"sonnet",
|
|
13998
|
+
"haiku"
|
|
13999
|
+
]);
|
|
14000
|
+
});
|
|
13980
14001
|
|
|
13981
14002
|
// src/channel/scrollback-buffer.ts
|
|
13982
14003
|
class ScrollbackBuffer {
|
|
@@ -23231,6 +23252,21 @@ var init_provider_definitions = __esm(() => {
|
|
|
23231
23252
|
isLocal: true,
|
|
23232
23253
|
description: "Local MLX (mlx@)"
|
|
23233
23254
|
},
|
|
23255
|
+
{
|
|
23256
|
+
name: "deepseek",
|
|
23257
|
+
displayName: "DeepSeek",
|
|
23258
|
+
transport: "openai",
|
|
23259
|
+
baseUrl: "",
|
|
23260
|
+
apiPath: "",
|
|
23261
|
+
apiKeyEnvVar: "",
|
|
23262
|
+
apiKeyDescription: "DeepSeek (auto-routed via OpenRouter)",
|
|
23263
|
+
apiKeyUrl: "",
|
|
23264
|
+
shortcuts: ["ds"],
|
|
23265
|
+
shortestPrefix: "ds",
|
|
23266
|
+
legacyPrefixes: [],
|
|
23267
|
+
nativeModelPatterns: [{ pattern: /^deepseek\//i }, { pattern: /^deepseek-/i }],
|
|
23268
|
+
description: "DeepSeek (auto-routed via OpenRouter)"
|
|
23269
|
+
},
|
|
23234
23270
|
{
|
|
23235
23271
|
name: "qwen",
|
|
23236
23272
|
displayName: "Qwen",
|
|
@@ -24785,75 +24821,156 @@ var init_static_fallback = __esm(() => {
|
|
|
24785
24821
|
minimax: "minimax",
|
|
24786
24822
|
openrouter: "openrouter",
|
|
24787
24823
|
ollamacloud: "meta-llama",
|
|
24788
|
-
qwen: "qwen"
|
|
24824
|
+
qwen: "qwen",
|
|
24825
|
+
deepseek: "deepseek",
|
|
24826
|
+
grok: "x-ai"
|
|
24789
24827
|
};
|
|
24790
24828
|
});
|
|
24791
24829
|
|
|
24792
24830
|
// src/providers/catalog-resolvers/openrouter.ts
|
|
24793
|
-
import { readFileSync as readFileSync6, existsSync as existsSync8 } from "fs";
|
|
24831
|
+
import { readFileSync as readFileSync6, existsSync as existsSync8, writeFileSync as writeFileSync8, mkdirSync as mkdirSync8 } from "fs";
|
|
24794
24832
|
import { join as join10 } from "path";
|
|
24795
24833
|
import { homedir as homedir9 } from "os";
|
|
24796
24834
|
|
|
24797
24835
|
class OpenRouterCatalogResolver {
|
|
24798
24836
|
provider = "openrouter";
|
|
24799
24837
|
resolveSync(userInput) {
|
|
24838
|
+
const entries = this._getEntries();
|
|
24800
24839
|
if (userInput.includes("/")) {
|
|
24801
|
-
|
|
24802
|
-
|
|
24803
|
-
|
|
24804
|
-
|
|
24840
|
+
if (entries) {
|
|
24841
|
+
for (const entry of entries) {
|
|
24842
|
+
for (const src of Object.values(entry.sources)) {
|
|
24843
|
+
if (src.externalId === userInput)
|
|
24844
|
+
return userInput;
|
|
24845
|
+
}
|
|
24846
|
+
}
|
|
24805
24847
|
}
|
|
24806
24848
|
return userInput;
|
|
24807
24849
|
}
|
|
24808
|
-
|
|
24809
|
-
|
|
24850
|
+
if (entries) {
|
|
24851
|
+
const byModelId = entries.find((e) => e.modelId === userInput);
|
|
24852
|
+
if (byModelId) {
|
|
24853
|
+
const orId = this._getOpenRouterExternalId(byModelId);
|
|
24854
|
+
if (orId)
|
|
24855
|
+
return orId;
|
|
24856
|
+
}
|
|
24857
|
+
const byAlias = entries.find((e) => e.aliases.includes(userInput));
|
|
24858
|
+
if (byAlias) {
|
|
24859
|
+
const orId = this._getOpenRouterExternalId(byAlias);
|
|
24860
|
+
if (orId)
|
|
24861
|
+
return orId;
|
|
24862
|
+
}
|
|
24863
|
+
for (const entry of entries) {
|
|
24864
|
+
for (const src of Object.values(entry.sources)) {
|
|
24865
|
+
if (src.externalId === userInput) {
|
|
24866
|
+
const orId = this._getOpenRouterExternalId(entry);
|
|
24867
|
+
if (orId)
|
|
24868
|
+
return orId;
|
|
24869
|
+
}
|
|
24870
|
+
}
|
|
24871
|
+
}
|
|
24810
24872
|
const suffix = `/${userInput}`;
|
|
24811
|
-
const
|
|
24812
|
-
|
|
24813
|
-
|
|
24873
|
+
for (const entry of entries) {
|
|
24874
|
+
const orId = this._getOpenRouterExternalId(entry);
|
|
24875
|
+
if (orId && orId.endsWith(suffix))
|
|
24876
|
+
return orId;
|
|
24877
|
+
}
|
|
24814
24878
|
const lowerSuffix = `/${userInput.toLowerCase()}`;
|
|
24815
|
-
const
|
|
24816
|
-
|
|
24817
|
-
|
|
24879
|
+
for (const entry of entries) {
|
|
24880
|
+
const orId = this._getOpenRouterExternalId(entry);
|
|
24881
|
+
if (orId && orId.toLowerCase().endsWith(lowerSuffix))
|
|
24882
|
+
return orId;
|
|
24883
|
+
}
|
|
24818
24884
|
}
|
|
24819
24885
|
return staticOpenRouterFallback(userInput);
|
|
24820
24886
|
}
|
|
24821
24887
|
async warmCache() {
|
|
24822
|
-
|
|
24823
|
-
|
|
24824
|
-
|
|
24825
|
-
|
|
24826
|
-
return;
|
|
24827
|
-
}
|
|
24828
|
-
const models = await ensureOpenRouterModelsLoaded();
|
|
24829
|
-
if (models.length > 0) {
|
|
24830
|
-
_memCache = models;
|
|
24831
|
-
}
|
|
24832
|
-
} catch {}
|
|
24888
|
+
if (!_warmPromise) {
|
|
24889
|
+
_warmPromise = this._fetchAndCache();
|
|
24890
|
+
}
|
|
24891
|
+
await _warmPromise;
|
|
24833
24892
|
}
|
|
24834
24893
|
isCacheWarm() {
|
|
24835
24894
|
return _memCache !== null && _memCache.length > 0;
|
|
24836
24895
|
}
|
|
24837
|
-
|
|
24896
|
+
async ensureReady(timeoutMs) {
|
|
24897
|
+
if (this.isCacheWarm())
|
|
24898
|
+
return;
|
|
24899
|
+
if (!_warmPromise) {
|
|
24900
|
+
_warmPromise = this._fetchAndCache();
|
|
24901
|
+
}
|
|
24902
|
+
await Promise.race([
|
|
24903
|
+
_warmPromise,
|
|
24904
|
+
new Promise((resolve2) => setTimeout(resolve2, timeoutMs))
|
|
24905
|
+
]);
|
|
24906
|
+
}
|
|
24907
|
+
_getOpenRouterExternalId(entry) {
|
|
24908
|
+
const orSource = entry.sources["openrouter-api"];
|
|
24909
|
+
if (orSource?.externalId)
|
|
24910
|
+
return orSource.externalId;
|
|
24911
|
+
for (const src of Object.values(entry.sources)) {
|
|
24912
|
+
if (src.externalId.includes("/"))
|
|
24913
|
+
return src.externalId;
|
|
24914
|
+
}
|
|
24915
|
+
return null;
|
|
24916
|
+
}
|
|
24917
|
+
_getEntries() {
|
|
24838
24918
|
if (_memCache)
|
|
24839
24919
|
return _memCache;
|
|
24840
|
-
|
|
24841
|
-
if (existsSync8(diskPath)) {
|
|
24920
|
+
if (existsSync8(DISK_CACHE_PATH)) {
|
|
24842
24921
|
try {
|
|
24843
|
-
const data = JSON.parse(readFileSync6(
|
|
24922
|
+
const data = JSON.parse(readFileSync6(DISK_CACHE_PATH, "utf-8"));
|
|
24923
|
+
if (data.version === 2 && Array.isArray(data.entries) && data.entries.length > 0) {
|
|
24924
|
+
_memCache = data.entries;
|
|
24925
|
+
return _memCache;
|
|
24926
|
+
}
|
|
24844
24927
|
if (Array.isArray(data.models) && data.models.length > 0) {
|
|
24845
|
-
_memCache = data.models
|
|
24928
|
+
_memCache = data.models.map((m) => ({
|
|
24929
|
+
modelId: m.id.includes("/") ? m.id.split("/").slice(1).join("/") : m.id,
|
|
24930
|
+
aliases: [],
|
|
24931
|
+
sources: { "openrouter-api": { externalId: m.id } }
|
|
24932
|
+
}));
|
|
24846
24933
|
return _memCache;
|
|
24847
24934
|
}
|
|
24848
24935
|
} catch {}
|
|
24849
24936
|
}
|
|
24850
24937
|
return null;
|
|
24851
24938
|
}
|
|
24939
|
+
async _fetchAndCache() {
|
|
24940
|
+
try {
|
|
24941
|
+
const response = await fetch(FIREBASE_CATALOG_URL, {
|
|
24942
|
+
signal: AbortSignal.timeout(8000)
|
|
24943
|
+
});
|
|
24944
|
+
if (!response.ok) {
|
|
24945
|
+
throw new Error(`Firebase catalog returned ${response.status}`);
|
|
24946
|
+
}
|
|
24947
|
+
const data = await response.json();
|
|
24948
|
+
if (!Array.isArray(data.models) || data.models.length === 0)
|
|
24949
|
+
return;
|
|
24950
|
+
_memCache = data.models;
|
|
24951
|
+
const backwardCompatModels = [];
|
|
24952
|
+
for (const entry of data.models) {
|
|
24953
|
+
const orSource = entry.sources["openrouter-api"];
|
|
24954
|
+
if (orSource?.externalId) {
|
|
24955
|
+
backwardCompatModels.push({ id: orSource.externalId });
|
|
24956
|
+
}
|
|
24957
|
+
}
|
|
24958
|
+
const cacheDir = join10(homedir9(), ".claudish");
|
|
24959
|
+
mkdirSync8(cacheDir, { recursive: true });
|
|
24960
|
+
const diskData = {
|
|
24961
|
+
version: 2,
|
|
24962
|
+
lastUpdated: new Date().toISOString(),
|
|
24963
|
+
entries: data.models,
|
|
24964
|
+
models: backwardCompatModels
|
|
24965
|
+
};
|
|
24966
|
+
writeFileSync8(DISK_CACHE_PATH, JSON.stringify(diskData), "utf-8");
|
|
24967
|
+
} catch {}
|
|
24968
|
+
}
|
|
24852
24969
|
}
|
|
24853
|
-
var _memCache = null;
|
|
24970
|
+
var FIREBASE_CATALOG_URL = "https://us-central1-claudish-6da10.cloudfunctions.net/queryModels?status=active&catalog=slim&limit=1000", DISK_CACHE_PATH, _memCache = null, _warmPromise = null;
|
|
24854
24971
|
var init_openrouter2 = __esm(() => {
|
|
24855
|
-
init_model_loader();
|
|
24856
24972
|
init_static_fallback();
|
|
24973
|
+
DISK_CACHE_PATH = join10(homedir9(), ".claudish", "all-models.json");
|
|
24857
24974
|
});
|
|
24858
24975
|
|
|
24859
24976
|
// src/providers/catalog-resolvers/litellm.ts
|
|
@@ -24906,6 +25023,10 @@ class LiteLLMCatalogResolver {
|
|
|
24906
25023
|
isCacheWarm() {
|
|
24907
25024
|
return _memCache2 !== null && _memCache2.length > 0;
|
|
24908
25025
|
}
|
|
25026
|
+
async ensureReady(_timeoutMs) {
|
|
25027
|
+
if (!this.isCacheWarm())
|
|
25028
|
+
await this.warmCache();
|
|
25029
|
+
}
|
|
24909
25030
|
_getModelIds() {
|
|
24910
25031
|
if (_memCache2)
|
|
24911
25032
|
return _memCache2;
|
|
@@ -24956,6 +25077,12 @@ function logResolution(userInput, result, quiet = false) {
|
|
|
24956
25077
|
`);
|
|
24957
25078
|
}
|
|
24958
25079
|
}
|
|
25080
|
+
async function ensureCatalogReady(provider, timeoutMs = 5000) {
|
|
25081
|
+
const resolver = getResolver(provider);
|
|
25082
|
+
if (!resolver || resolver.isCacheWarm())
|
|
25083
|
+
return;
|
|
25084
|
+
await resolver.ensureReady(timeoutMs);
|
|
25085
|
+
}
|
|
24959
25086
|
async function warmAllCatalogs(providers) {
|
|
24960
25087
|
const targets = providers ? [...RESOLVER_REGISTRY.entries()].filter(([k]) => providers.includes(k)) : [...RESOLVER_REGISTRY.entries()];
|
|
24961
25088
|
await Promise.allSettled(targets.map(([, r]) => r.warmCache()));
|
|
@@ -25104,8 +25231,8 @@ async function warmZenModelCache() {
|
|
|
25104
25231
|
if (models.length === 0)
|
|
25105
25232
|
return;
|
|
25106
25233
|
const cacheDir = join12(homedir11(), ".claudish");
|
|
25107
|
-
const { mkdirSync:
|
|
25108
|
-
|
|
25234
|
+
const { mkdirSync: mkdirSync9, writeFileSync: writeSync } = await import("fs");
|
|
25235
|
+
mkdirSync9(cacheDir, { recursive: true });
|
|
25109
25236
|
writeSync(join12(cacheDir, "zen-models.json"), JSON.stringify({ models, fetchedAt: new Date().toISOString() }));
|
|
25110
25237
|
}
|
|
25111
25238
|
function readZenGoModelCacheSync() {
|
|
@@ -25141,8 +25268,8 @@ async function warmZenGoModelCache() {
|
|
|
25141
25268
|
if (models.length === 0)
|
|
25142
25269
|
return;
|
|
25143
25270
|
const cacheDir = join12(homedir11(), ".claudish");
|
|
25144
|
-
const { mkdirSync:
|
|
25145
|
-
|
|
25271
|
+
const { mkdirSync: mkdirSync9, writeFileSync: writeSync } = await import("fs");
|
|
25272
|
+
mkdirSync9(cacheDir, { recursive: true });
|
|
25146
25273
|
writeSync(join12(cacheDir, "zen-go-models.json"), JSON.stringify({ models, fetchedAt: new Date().toISOString() }));
|
|
25147
25274
|
}
|
|
25148
25275
|
function hasProviderCredentials(provider) {
|
|
@@ -25179,7 +25306,7 @@ function getFallbackChain(modelName, nativeProvider) {
|
|
|
25179
25306
|
displayName: sub.displayName
|
|
25180
25307
|
});
|
|
25181
25308
|
}
|
|
25182
|
-
if (nativeProvider !== "unknown" && nativeProvider !== "qwen" && nativeProvider !== "native-anthropic") {
|
|
25309
|
+
if (nativeProvider !== "unknown" && nativeProvider !== "qwen" && nativeProvider !== "deepseek" && nativeProvider !== "native-anthropic") {
|
|
25183
25310
|
if (hasProviderCredentials(nativeProvider)) {
|
|
25184
25311
|
const prefix = PROVIDER_TO_PREFIX[nativeProvider] || nativeProvider;
|
|
25185
25312
|
routes.push({
|
|
@@ -25618,7 +25745,7 @@ var init_provider_resolver = __esm(() => {
|
|
|
25618
25745
|
});
|
|
25619
25746
|
|
|
25620
25747
|
// src/services/pricing-cache.ts
|
|
25621
|
-
import { readFileSync as readFileSync9, writeFileSync as
|
|
25748
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync9, existsSync as existsSync12, mkdirSync as mkdirSync9, statSync as statSync2 } from "fs";
|
|
25622
25749
|
import { homedir as homedir13 } from "os";
|
|
25623
25750
|
import { join as join14 } from "path";
|
|
25624
25751
|
function getDynamicPricingSync(provider, modelName) {
|
|
@@ -25702,12 +25829,12 @@ function loadDiskCache() {
|
|
|
25702
25829
|
}
|
|
25703
25830
|
function saveDiskCache() {
|
|
25704
25831
|
try {
|
|
25705
|
-
|
|
25832
|
+
mkdirSync9(CACHE_DIR, { recursive: true });
|
|
25706
25833
|
const data = {};
|
|
25707
25834
|
for (const [key, pricing] of pricingMap) {
|
|
25708
25835
|
data[key] = pricing;
|
|
25709
25836
|
}
|
|
25710
|
-
|
|
25837
|
+
writeFileSync9(CACHE_FILE, JSON.stringify(data), "utf-8");
|
|
25711
25838
|
} catch (error2) {
|
|
25712
25839
|
log(`[PricingCache] Error saving disk cache: ${error2}`);
|
|
25713
25840
|
}
|
|
@@ -26284,8 +26411,8 @@ Details: ${e.message}`);
|
|
|
26284
26411
|
const credPath = this.getCredentialsPath();
|
|
26285
26412
|
const claudishDir = join15(homedir14(), ".claudish");
|
|
26286
26413
|
if (!existsSync13(claudishDir)) {
|
|
26287
|
-
const { mkdirSync:
|
|
26288
|
-
|
|
26414
|
+
const { mkdirSync: mkdirSync10 } = __require("fs");
|
|
26415
|
+
mkdirSync10(claudishDir, { recursive: true });
|
|
26289
26416
|
}
|
|
26290
26417
|
const fd = openSync(credPath, "w", 384);
|
|
26291
26418
|
try {
|
|
@@ -27142,8 +27269,8 @@ Details: ${e.message}`);
|
|
|
27142
27269
|
const credPath = this.getCredentialsPath();
|
|
27143
27270
|
const claudishDir = join16(homedir15(), ".claudish");
|
|
27144
27271
|
if (!existsSync14(claudishDir)) {
|
|
27145
|
-
const { mkdirSync:
|
|
27146
|
-
|
|
27272
|
+
const { mkdirSync: mkdirSync10 } = __require("fs");
|
|
27273
|
+
mkdirSync10(claudishDir, { recursive: true });
|
|
27147
27274
|
}
|
|
27148
27275
|
const fd = openSync2(credPath, "w", 384);
|
|
27149
27276
|
try {
|
|
@@ -27459,8 +27586,8 @@ class KimiOAuth {
|
|
|
27459
27586
|
const deviceIdPath = this.getDeviceIdPath();
|
|
27460
27587
|
const claudishDir = join18(homedir17(), ".claudish");
|
|
27461
27588
|
if (!existsSync16(claudishDir)) {
|
|
27462
|
-
const { mkdirSync:
|
|
27463
|
-
|
|
27589
|
+
const { mkdirSync: mkdirSync10 } = __require("fs");
|
|
27590
|
+
mkdirSync10(claudishDir, { recursive: true });
|
|
27464
27591
|
}
|
|
27465
27592
|
if (existsSync16(deviceIdPath)) {
|
|
27466
27593
|
try {
|
|
@@ -27743,8 +27870,8 @@ Waiting for authorization...`);
|
|
|
27743
27870
|
const credPath = this.getCredentialsPath();
|
|
27744
27871
|
const claudishDir = join18(homedir17(), ".claudish");
|
|
27745
27872
|
if (!existsSync16(claudishDir)) {
|
|
27746
|
-
const { mkdirSync:
|
|
27747
|
-
|
|
27873
|
+
const { mkdirSync: mkdirSync10 } = __require("fs");
|
|
27874
|
+
mkdirSync10(claudishDir, { recursive: true });
|
|
27748
27875
|
}
|
|
27749
27876
|
const fd = openSync3(credPath, "w", 384);
|
|
27750
27877
|
try {
|
|
@@ -28980,7 +29107,7 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
|
|
|
28980
29107
|
}
|
|
28981
29108
|
return "auto-route";
|
|
28982
29109
|
};
|
|
28983
|
-
const getHandlerForRequest = (requestedModel) => {
|
|
29110
|
+
const getHandlerForRequest = async (requestedModel) => {
|
|
28984
29111
|
if (monitorMode)
|
|
28985
29112
|
return nativeHandler;
|
|
28986
29113
|
let target = requestedModel;
|
|
@@ -29005,6 +29132,7 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
|
|
|
29005
29132
|
{
|
|
29006
29133
|
const parsedTarget = parseModelSpec(target);
|
|
29007
29134
|
if (parsedTarget.provider === "openrouter" || parsedTarget.provider === "litellm") {
|
|
29135
|
+
await ensureCatalogReady(parsedTarget.provider, 5000);
|
|
29008
29136
|
const resolution = resolveModelNameSync(parsedTarget.model, parsedTarget.provider);
|
|
29009
29137
|
logResolution(parsedTarget.model, resolution, options.quiet);
|
|
29010
29138
|
if (resolution.wasResolved) {
|
|
@@ -29019,6 +29147,7 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
|
|
|
29019
29147
|
if (fallbackHandlerCache.has(cacheKey2)) {
|
|
29020
29148
|
return fallbackHandlerCache.get(cacheKey2);
|
|
29021
29149
|
}
|
|
29150
|
+
await ensureCatalogReady("openrouter", 5000);
|
|
29022
29151
|
const matchedEntries = customRoutingRules ? matchRoutingRule(parsedForFallback.model, customRoutingRules) : null;
|
|
29023
29152
|
const chain = matchedEntries ? buildRoutingChain(matchedEntries, parsedForFallback.model) : getFallbackChain(parsedForFallback.model, parsedForFallback.provider);
|
|
29024
29153
|
if (chain.length > 0) {
|
|
@@ -29078,7 +29207,7 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
|
|
|
29078
29207
|
try {
|
|
29079
29208
|
const body = await c.req.json();
|
|
29080
29209
|
const reqModel = body.model || "claude-3-opus-20240229";
|
|
29081
|
-
const handler = getHandlerForRequest(reqModel);
|
|
29210
|
+
const handler = await getHandlerForRequest(reqModel);
|
|
29082
29211
|
if (handler instanceof NativeHandler) {
|
|
29083
29212
|
const headers = { "Content-Type": "application/json" };
|
|
29084
29213
|
if (anthropicApiKey)
|
|
@@ -29100,7 +29229,7 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
|
|
|
29100
29229
|
app.post("/v1/messages", async (c) => {
|
|
29101
29230
|
try {
|
|
29102
29231
|
const body = await c.req.json();
|
|
29103
|
-
const handler = getHandlerForRequest(body.model);
|
|
29232
|
+
const handler = await getHandlerForRequest(body.model);
|
|
29104
29233
|
return handler.handle(c, body);
|
|
29105
29234
|
} catch (e) {
|
|
29106
29235
|
log(`[Proxy] Error: ${e}`);
|
|
@@ -29189,7 +29318,7 @@ var exports_mcp_server = {};
|
|
|
29189
29318
|
__export(exports_mcp_server, {
|
|
29190
29319
|
startMcpServer: () => startMcpServer
|
|
29191
29320
|
});
|
|
29192
|
-
import { readFileSync as readFileSync17, existsSync as existsSync20, writeFileSync as
|
|
29321
|
+
import { readFileSync as readFileSync17, existsSync as existsSync20, writeFileSync as writeFileSync10, mkdirSync as mkdirSync10, readdirSync as readdirSync3 } from "fs";
|
|
29193
29322
|
import { join as join22, dirname as dirname2 } from "path";
|
|
29194
29323
|
import { homedir as homedir21 } from "os";
|
|
29195
29324
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
@@ -29221,8 +29350,8 @@ async function loadAllModels(forceRefresh = false) {
|
|
|
29221
29350
|
throw new Error(`API returned ${response.status}`);
|
|
29222
29351
|
const data = await response.json();
|
|
29223
29352
|
const models = data.data || [];
|
|
29224
|
-
|
|
29225
|
-
|
|
29353
|
+
mkdirSync10(CLAUDISH_CACHE_DIR, { recursive: true });
|
|
29354
|
+
writeFileSync10(ALL_MODELS_CACHE_PATH, JSON.stringify({ lastUpdated: new Date().toISOString(), models }), "utf-8");
|
|
29226
29355
|
return models;
|
|
29227
29356
|
} catch {
|
|
29228
29357
|
if (existsSync20(ALL_MODELS_CACHE_PATH)) {
|
|
@@ -29620,7 +29749,7 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
29620
29749
|
models: {
|
|
29621
29750
|
type: "array",
|
|
29622
29751
|
items: { type: "string" },
|
|
29623
|
-
description: "
|
|
29752
|
+
description: "External model IDs to run (required for 'run' and 'run-and-judge' modes). " + "Do NOT pass 'internal', 'default', 'opus', 'sonnet', 'haiku', or 'claude-*' model IDs \u2014 " + "those are Claude Code agent selectors and must be handled via Task agents instead."
|
|
29624
29753
|
},
|
|
29625
29754
|
judges: {
|
|
29626
29755
|
type: "array",
|
|
@@ -32698,9 +32827,9 @@ __export(exports_cli, {
|
|
|
32698
32827
|
});
|
|
32699
32828
|
import {
|
|
32700
32829
|
readFileSync as readFileSync18,
|
|
32701
|
-
writeFileSync as
|
|
32830
|
+
writeFileSync as writeFileSync11,
|
|
32702
32831
|
existsSync as existsSync21,
|
|
32703
|
-
mkdirSync as
|
|
32832
|
+
mkdirSync as mkdirSync11,
|
|
32704
32833
|
copyFileSync,
|
|
32705
32834
|
readdirSync as readdirSync4,
|
|
32706
32835
|
unlinkSync as unlinkSync6
|
|
@@ -32773,12 +32902,12 @@ async function parseArgs(args) {
|
|
|
32773
32902
|
}
|
|
32774
32903
|
try {
|
|
32775
32904
|
const fileConfig = loadConfig();
|
|
32776
|
-
if (fileConfig.diagMode && ["auto", "
|
|
32905
|
+
if (fileConfig.diagMode && ["auto", "logfile", "off"].includes(fileConfig.diagMode)) {
|
|
32777
32906
|
config3.diagMode = fileConfig.diagMode;
|
|
32778
32907
|
}
|
|
32779
32908
|
} catch {}
|
|
32780
32909
|
const envDiagMode = process.env[ENV.CLAUDISH_DIAG_MODE]?.toLowerCase();
|
|
32781
|
-
if (envDiagMode && ["auto", "
|
|
32910
|
+
if (envDiagMode && ["auto", "logfile", "off"].includes(envDiagMode)) {
|
|
32782
32911
|
config3.diagMode = envDiagMode;
|
|
32783
32912
|
}
|
|
32784
32913
|
let i = 0;
|
|
@@ -32927,7 +33056,7 @@ async function parseArgs(args) {
|
|
|
32927
33056
|
config3.noLogs = true;
|
|
32928
33057
|
} else if (arg === "--diag-mode" && i + 1 < args.length) {
|
|
32929
33058
|
const mode = args[++i].toLowerCase();
|
|
32930
|
-
if (["auto", "
|
|
33059
|
+
if (["auto", "logfile", "off"].includes(mode)) {
|
|
32931
33060
|
config3.diagMode = mode;
|
|
32932
33061
|
}
|
|
32933
33062
|
} else if (arg === "--") {
|
|
@@ -33050,8 +33179,8 @@ async function searchAndPrintModels(query, forceUpdate) {
|
|
|
33050
33179
|
throw new Error(`API returned ${response.status}`);
|
|
33051
33180
|
const data = await response.json();
|
|
33052
33181
|
models = data.data;
|
|
33053
|
-
|
|
33054
|
-
|
|
33182
|
+
mkdirSync11(CLAUDISH_CACHE_DIR2, { recursive: true });
|
|
33183
|
+
writeFileSync11(ALL_MODELS_JSON_PATH, JSON.stringify({
|
|
33055
33184
|
lastUpdated: new Date().toISOString(),
|
|
33056
33185
|
models
|
|
33057
33186
|
}), "utf-8");
|
|
@@ -33223,8 +33352,8 @@ async function printAllModels(jsonOutput, forceUpdate) {
|
|
|
33223
33352
|
throw new Error(`API returned ${response.status}`);
|
|
33224
33353
|
const data = await response.json();
|
|
33225
33354
|
models = data.data;
|
|
33226
|
-
|
|
33227
|
-
|
|
33355
|
+
mkdirSync11(CLAUDISH_CACHE_DIR2, { recursive: true });
|
|
33356
|
+
writeFileSync11(ALL_MODELS_JSON_PATH, JSON.stringify({
|
|
33228
33357
|
lastUpdated: new Date().toISOString(),
|
|
33229
33358
|
models
|
|
33230
33359
|
}), "utf-8");
|
|
@@ -33501,8 +33630,8 @@ async function updateModelsFromOpenRouter() {
|
|
|
33501
33630
|
source: "https://openrouter.ai/models?categories=programming&fmt=cards&order=top-weekly",
|
|
33502
33631
|
models: recommendations
|
|
33503
33632
|
};
|
|
33504
|
-
|
|
33505
|
-
|
|
33633
|
+
mkdirSync11(CLAUDISH_CACHE_DIR2, { recursive: true });
|
|
33634
|
+
writeFileSync11(CACHED_MODELS_PATH, JSON.stringify(updatedData, null, 2), "utf-8");
|
|
33506
33635
|
console.error(`\u2705 Updated ${recommendations.length} models (last updated: ${updatedData.lastUpdated})`);
|
|
33507
33636
|
} catch (error2) {
|
|
33508
33637
|
console.error(`\u274C Failed to update models: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
@@ -33861,7 +33990,7 @@ OPTIONS:
|
|
|
33861
33990
|
--port <port> Proxy server port (default: random)
|
|
33862
33991
|
-d, --debug Enable debug logging to file (logs/claudish_*.log)
|
|
33863
33992
|
--no-logs Disable always-on structural logging (~/.claudish/logs/)
|
|
33864
|
-
--diag-mode <mode> Diagnostic output: auto (default),
|
|
33993
|
+
--diag-mode <mode> Diagnostic output: auto (default), logfile, off
|
|
33865
33994
|
Also: CLAUDISH_DIAG_MODE env var or "diagMode" in config.json
|
|
33866
33995
|
--log-level <level> Log verbosity: debug (full), info (truncated), minimal (labels only)
|
|
33867
33996
|
-q, --quiet Suppress [claudish] log messages (default in single-shot mode)
|
|
@@ -34152,15 +34281,15 @@ async function initializeClaudishSkill() {
|
|
|
34152
34281
|
}
|
|
34153
34282
|
try {
|
|
34154
34283
|
if (!existsSync21(claudeDir)) {
|
|
34155
|
-
|
|
34284
|
+
mkdirSync11(claudeDir, { recursive: true });
|
|
34156
34285
|
console.log("\uD83D\uDCC1 Created .claude/ directory");
|
|
34157
34286
|
}
|
|
34158
34287
|
if (!existsSync21(skillsDir)) {
|
|
34159
|
-
|
|
34288
|
+
mkdirSync11(skillsDir, { recursive: true });
|
|
34160
34289
|
console.log("\uD83D\uDCC1 Created .claude/skills/ directory");
|
|
34161
34290
|
}
|
|
34162
34291
|
if (!existsSync21(claudishSkillDir)) {
|
|
34163
|
-
|
|
34292
|
+
mkdirSync11(claudishSkillDir, { recursive: true });
|
|
34164
34293
|
console.log("\uD83D\uDCC1 Created .claude/skills/claudish-usage/ directory");
|
|
34165
34294
|
}
|
|
34166
34295
|
copyFileSync(sourceSkillPath, skillFile);
|
|
@@ -34340,7 +34469,7 @@ async function fetchGLMCodingModels() {
|
|
|
34340
34469
|
return [];
|
|
34341
34470
|
}
|
|
34342
34471
|
}
|
|
34343
|
-
var __filename4, __dirname4, VERSION = "6.
|
|
34472
|
+
var __filename4, __dirname4, VERSION = "6.7.0", CACHE_MAX_AGE_DAYS2 = 2, CLAUDISH_CACHE_DIR2, BUNDLED_MODELS_PATH, CACHED_MODELS_PATH, ALL_MODELS_JSON_PATH;
|
|
34344
34473
|
var init_cli = __esm(() => {
|
|
34345
34474
|
init_config();
|
|
34346
34475
|
init_model_loader();
|
|
@@ -34371,7 +34500,7 @@ __export(exports_update_checker, {
|
|
|
34371
34500
|
checkForUpdates: () => checkForUpdates
|
|
34372
34501
|
});
|
|
34373
34502
|
import { execSync } from "child_process";
|
|
34374
|
-
import { existsSync as existsSync22, mkdirSync as
|
|
34503
|
+
import { existsSync as existsSync22, mkdirSync as mkdirSync12, readFileSync as readFileSync19, unlinkSync as unlinkSync7, writeFileSync as writeFileSync12 } from "fs";
|
|
34375
34504
|
import { homedir as homedir23, platform as platform2, tmpdir } from "os";
|
|
34376
34505
|
import { join as join24 } from "path";
|
|
34377
34506
|
import { createInterface as createInterface2 } from "readline";
|
|
@@ -34392,7 +34521,7 @@ function getCacheFilePath() {
|
|
|
34392
34521
|
}
|
|
34393
34522
|
try {
|
|
34394
34523
|
if (!existsSync22(cacheDir)) {
|
|
34395
|
-
|
|
34524
|
+
mkdirSync12(cacheDir, { recursive: true });
|
|
34396
34525
|
}
|
|
34397
34526
|
return join24(cacheDir, "update-check.json");
|
|
34398
34527
|
} catch {
|
|
@@ -34418,7 +34547,7 @@ function writeCache(latestVersion) {
|
|
|
34418
34547
|
lastCheck: Date.now(),
|
|
34419
34548
|
latestVersion
|
|
34420
34549
|
};
|
|
34421
|
-
|
|
34550
|
+
writeFileSync12(cachePath, JSON.stringify(data), "utf-8");
|
|
34422
34551
|
} catch {}
|
|
34423
34552
|
}
|
|
34424
34553
|
function isCacheValid(cache) {
|
|
@@ -34694,7 +34823,7 @@ __export(exports_model_selector, {
|
|
|
34694
34823
|
promptForApiKey: () => promptForApiKey,
|
|
34695
34824
|
confirmAction: () => confirmAction
|
|
34696
34825
|
});
|
|
34697
|
-
import { readFileSync as readFileSync20, writeFileSync as
|
|
34826
|
+
import { readFileSync as readFileSync20, writeFileSync as writeFileSync13, existsSync as existsSync23, mkdirSync as mkdirSync13 } from "fs";
|
|
34698
34827
|
import { join as join25, dirname as dirname4 } from "path";
|
|
34699
34828
|
import { homedir as homedir24 } from "os";
|
|
34700
34829
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
@@ -34732,8 +34861,8 @@ async function fetchAllModels(forceUpdate = false) {
|
|
|
34732
34861
|
throw new Error(`API returned ${response.status}`);
|
|
34733
34862
|
const data = await response.json();
|
|
34734
34863
|
const models = data.data;
|
|
34735
|
-
|
|
34736
|
-
|
|
34864
|
+
mkdirSync13(CLAUDISH_CACHE_DIR3, { recursive: true });
|
|
34865
|
+
writeFileSync13(ALL_MODELS_JSON_PATH2, JSON.stringify({
|
|
34737
34866
|
lastUpdated: new Date().toISOString(),
|
|
34738
34867
|
models
|
|
34739
34868
|
}), "utf-8");
|
|
@@ -36613,7 +36742,7 @@ import os from "os";
|
|
|
36613
36742
|
import path from "path";
|
|
36614
36743
|
import { EventEmitter as EventEmitter3 } from "events";
|
|
36615
36744
|
import { dlopen, toArrayBuffer as toArrayBuffer4, JSCallback, ptr as ptr4 } from "bun:ffi";
|
|
36616
|
-
import { existsSync as existsSync25, writeFileSync as
|
|
36745
|
+
import { existsSync as existsSync25, writeFileSync as writeFileSync14 } from "fs";
|
|
36617
36746
|
import { EventEmitter as EventEmitter4 } from "events";
|
|
36618
36747
|
import { toArrayBuffer, ptr } from "bun:ffi";
|
|
36619
36748
|
import { ptr as ptr2, toArrayBuffer as toArrayBuffer2 } from "bun:ffi";
|
|
@@ -41959,7 +42088,7 @@ function convertToDebugSymbols(symbols) {
|
|
|
41959
42088
|
if (env.OTUI_DEBUG_FFI && globalFFILogPath) {
|
|
41960
42089
|
const logPath = globalFFILogPath;
|
|
41961
42090
|
const writeSync4 = (msg) => {
|
|
41962
|
-
|
|
42091
|
+
writeFileSync14(logPath, msg + `
|
|
41963
42092
|
`, { flag: "a" });
|
|
41964
42093
|
};
|
|
41965
42094
|
Object.entries(symbols).forEach(([key, value]) => {
|
|
@@ -95525,10 +95654,10 @@ import { spawn as spawn3 } from "child_process";
|
|
|
95525
95654
|
import {
|
|
95526
95655
|
appendFileSync,
|
|
95527
95656
|
existsSync as existsSync26,
|
|
95528
|
-
mkdirSync as
|
|
95657
|
+
mkdirSync as mkdirSync14,
|
|
95529
95658
|
readFileSync as readFileSync21,
|
|
95530
95659
|
unlinkSync as unlinkSync8,
|
|
95531
|
-
writeFileSync as
|
|
95660
|
+
writeFileSync as writeFileSync15
|
|
95532
95661
|
} from "fs";
|
|
95533
95662
|
import { dirname as dirname6, join as join27 } from "path";
|
|
95534
95663
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
@@ -95541,7 +95670,7 @@ function formatElapsed(ms) {
|
|
|
95541
95670
|
const rem = s % 60;
|
|
95542
95671
|
return `${m2}m ${rem}s`;
|
|
95543
95672
|
}
|
|
95544
|
-
function
|
|
95673
|
+
function findMagmuxBinary() {
|
|
95545
95674
|
const thisFile = fileURLToPath6(import.meta.url);
|
|
95546
95675
|
const thisDir = dirname6(thisFile);
|
|
95547
95676
|
const pkgRoot = join27(thisDir, "..");
|
|
@@ -95549,40 +95678,17 @@ function findMultiplexerBinary() {
|
|
|
95549
95678
|
const arch = process.arch;
|
|
95550
95679
|
const builtMagmux = join27(pkgRoot, "native", "magmux", "magmux");
|
|
95551
95680
|
if (existsSync26(builtMagmux))
|
|
95552
|
-
return
|
|
95681
|
+
return builtMagmux;
|
|
95553
95682
|
const bundledMagmux = join27(pkgRoot, "native", "magmux", `magmux-${platform3}-${arch}`);
|
|
95554
95683
|
if (existsSync26(bundledMagmux))
|
|
95555
|
-
return
|
|
95684
|
+
return bundledMagmux;
|
|
95556
95685
|
try {
|
|
95557
95686
|
const result = execSync3("which magmux", { encoding: "utf-8" }).trim();
|
|
95558
95687
|
if (result)
|
|
95559
|
-
return
|
|
95560
|
-
} catch {}
|
|
95561
|
-
const builtMtm = join27(pkgRoot, "native", "mtm", "mtm");
|
|
95562
|
-
if (existsSync26(builtMtm))
|
|
95563
|
-
return { path: builtMtm, kind: "mtm" };
|
|
95564
|
-
const bundledMtm = join27(pkgRoot, "native", "mtm", `mtm-${platform3}-${arch}`);
|
|
95565
|
-
if (existsSync26(bundledMtm))
|
|
95566
|
-
return { path: bundledMtm, kind: "mtm" };
|
|
95567
|
-
try {
|
|
95568
|
-
const result = execSync3("which mtm", { encoding: "utf-8" }).trim();
|
|
95569
|
-
if (result && isMtmForkWithGrid(result))
|
|
95570
|
-
return { path: result, kind: "mtm" };
|
|
95688
|
+
return result;
|
|
95571
95689
|
} catch {}
|
|
95572
|
-
throw new Error(`
|
|
95573
|
-
|
|
95574
|
-
` + " # or: cd packages/cli/native/mtm && make");
|
|
95575
|
-
}
|
|
95576
|
-
function isMtmForkWithGrid(binPath) {
|
|
95577
|
-
try {
|
|
95578
|
-
const output = execSync3(`"${binPath}" --help 2>&1 || true`, {
|
|
95579
|
-
encoding: "utf-8",
|
|
95580
|
-
timeout: 2000
|
|
95581
|
-
});
|
|
95582
|
-
return output.includes("-g ");
|
|
95583
|
-
} catch {
|
|
95584
|
-
return false;
|
|
95585
|
-
}
|
|
95690
|
+
throw new Error(`magmux not found. Install it:
|
|
95691
|
+
brew install MadAppGang/tap/magmux`);
|
|
95586
95692
|
}
|
|
95587
95693
|
function renderGridStatusBar(counts) {
|
|
95588
95694
|
const elapsed = formatElapsed(counts.elapsedMs);
|
|
@@ -95650,7 +95756,7 @@ function pollStatus(state) {
|
|
|
95650
95756
|
else
|
|
95651
95757
|
failed++;
|
|
95652
95758
|
} else {
|
|
95653
|
-
if (elapsedMs > timeoutMs) {
|
|
95759
|
+
if (!state.interactive && elapsedMs > timeoutMs) {
|
|
95654
95760
|
const newState = {
|
|
95655
95761
|
...current,
|
|
95656
95762
|
state: "TIMEOUT",
|
|
@@ -95675,7 +95781,7 @@ function pollStatus(state) {
|
|
|
95675
95781
|
}
|
|
95676
95782
|
}
|
|
95677
95783
|
if (changed) {
|
|
95678
|
-
|
|
95784
|
+
writeFileSync15(statusPath, JSON.stringify(statusCache, null, 2), "utf-8");
|
|
95679
95785
|
}
|
|
95680
95786
|
const total = anonIds.length;
|
|
95681
95787
|
const allDone = done + failed >= total;
|
|
@@ -95696,8 +95802,9 @@ function pollStatus(state) {
|
|
|
95696
95802
|
}
|
|
95697
95803
|
async function runWithGrid(sessionPath, models, input, opts) {
|
|
95698
95804
|
const timeoutMs = (opts?.timeout ?? 300) * 1000;
|
|
95805
|
+
const interactive = opts?.interactive ?? false;
|
|
95699
95806
|
const manifest = setupSession(sessionPath, models, input);
|
|
95700
|
-
|
|
95807
|
+
mkdirSync14(join27(sessionPath, "errors"), { recursive: true });
|
|
95701
95808
|
for (const anonId of Object.keys(manifest.models)) {
|
|
95702
95809
|
const stale = join27(sessionPath, "work", anonId, ".exit-code");
|
|
95703
95810
|
try {
|
|
@@ -95711,6 +95818,9 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
95711
95818
|
const exitCodeFile = join27(sessionPath, "work", anonId, ".exit-code");
|
|
95712
95819
|
const model = manifest.models[anonId].model;
|
|
95713
95820
|
const paneIndex = Object.keys(manifest.models).indexOf(anonId);
|
|
95821
|
+
if (interactive) {
|
|
95822
|
+
return `claudish --model ${model} --dangerously-skip-permissions '${prompt}'`;
|
|
95823
|
+
}
|
|
95714
95824
|
return [
|
|
95715
95825
|
`claudish --model ${model} -y -v '${prompt}' 2>${errorLog};`,
|
|
95716
95826
|
`_ec=$?; echo $_ec > ${exitCodeFile};`,
|
|
@@ -95726,10 +95836,10 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
95726
95836
|
`exec sleep 86400`
|
|
95727
95837
|
].join(" ");
|
|
95728
95838
|
});
|
|
95729
|
-
|
|
95839
|
+
writeFileSync15(gridfilePath, gridLines.join(`
|
|
95730
95840
|
`) + `
|
|
95731
95841
|
`, "utf-8");
|
|
95732
|
-
const
|
|
95842
|
+
const magmuxPath = findMagmuxBinary();
|
|
95733
95843
|
const statusbarPath = join27(sessionPath, "statusbar.txt");
|
|
95734
95844
|
const statusPath = join27(sessionPath, "status.json");
|
|
95735
95845
|
const statusCache = JSON.parse(readFileSync21(statusPath, "utf-8"));
|
|
@@ -95752,18 +95862,17 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
95752
95862
|
startTime,
|
|
95753
95863
|
timeoutMs,
|
|
95754
95864
|
statusbarPath,
|
|
95755
|
-
completedAtMs: null
|
|
95865
|
+
completedAtMs: null,
|
|
95866
|
+
interactive
|
|
95756
95867
|
};
|
|
95757
95868
|
const pollInterval = setInterval(() => {
|
|
95758
95869
|
pollStatus(pollState);
|
|
95759
95870
|
}, 500);
|
|
95760
95871
|
const spawnArgs = ["-g", gridfilePath, "-S", statusbarPath];
|
|
95761
|
-
if (
|
|
95762
|
-
spawnArgs.push("-t", "xterm-256color");
|
|
95763
|
-
} else {
|
|
95872
|
+
if (!interactive) {
|
|
95764
95873
|
spawnArgs.push("-w");
|
|
95765
95874
|
}
|
|
95766
|
-
const proc = spawn3(
|
|
95875
|
+
const proc = spawn3(magmuxPath, spawnArgs, {
|
|
95767
95876
|
stdio: "inherit",
|
|
95768
95877
|
env: { ...process.env }
|
|
95769
95878
|
});
|
|
@@ -95823,7 +95932,7 @@ Options (run / run-and-judge):
|
|
|
95823
95932
|
--models <a,b,...> Comma-separated model IDs to run
|
|
95824
95933
|
--input <text> Task prompt (or create input.md in --path beforehand)
|
|
95825
95934
|
--timeout <secs> Timeout per model in seconds (default: 300)
|
|
95826
|
-
--grid Show all models in
|
|
95935
|
+
--grid Show all models in a magmux grid with live output + status bar
|
|
95827
95936
|
|
|
95828
95937
|
Options (judge / run-and-judge):
|
|
95829
95938
|
--judges <a,b,...> Comma-separated judge model IDs (default: same as runners)
|
|
@@ -95840,11 +95949,13 @@ Examples:
|
|
|
95840
95949
|
`);
|
|
95841
95950
|
}
|
|
95842
95951
|
async function teamCommand(args) {
|
|
95843
|
-
|
|
95844
|
-
if (!subcommand || hasFlag(args, "--help") || hasFlag(args, "-h")) {
|
|
95952
|
+
if (hasFlag(args, "--help") || hasFlag(args, "-h")) {
|
|
95845
95953
|
printHelp2();
|
|
95846
95954
|
process.exit(0);
|
|
95847
95955
|
}
|
|
95956
|
+
const firstArg = args[0] ?? "";
|
|
95957
|
+
const legacySubs = ["run", "judge", "run-and-judge", "status"];
|
|
95958
|
+
const subcommand = legacySubs.includes(firstArg) ? firstArg : "run";
|
|
95848
95959
|
const rawSessionPath = getFlag(args, "--path") ?? ".";
|
|
95849
95960
|
let sessionPath;
|
|
95850
95961
|
try {
|
|
@@ -95855,22 +95966,36 @@ async function teamCommand(args) {
|
|
|
95855
95966
|
}
|
|
95856
95967
|
const modelsRaw = getFlag(args, "--models");
|
|
95857
95968
|
const judgesRaw = getFlag(args, "--judges");
|
|
95858
|
-
const
|
|
95969
|
+
const mode = getFlag(args, "--mode") ?? "default";
|
|
95859
95970
|
const timeoutStr = getFlag(args, "--timeout");
|
|
95860
95971
|
const timeout = timeoutStr ? parseInt(timeoutStr, 10) : 300;
|
|
95972
|
+
let input = getFlag(args, "--input");
|
|
95973
|
+
if (!input) {
|
|
95974
|
+
const flagsWithValues = ["--models", "--judges", "--mode", "--path", "--timeout", "--input"];
|
|
95975
|
+
const positionals = args.filter((a, i) => {
|
|
95976
|
+
if (legacySubs.includes(a) && i === 0)
|
|
95977
|
+
return false;
|
|
95978
|
+
if (a.startsWith("--"))
|
|
95979
|
+
return false;
|
|
95980
|
+
const prev = args[i - 1];
|
|
95981
|
+
if (prev && flagsWithValues.includes(prev))
|
|
95982
|
+
return false;
|
|
95983
|
+
return true;
|
|
95984
|
+
});
|
|
95985
|
+
if (positionals.length > 0)
|
|
95986
|
+
input = positionals.join(" ");
|
|
95987
|
+
}
|
|
95861
95988
|
const models = modelsRaw ? modelsRaw.split(",").map((m2) => m2.trim()).filter(Boolean) : [];
|
|
95862
95989
|
const judges = judgesRaw ? judgesRaw.split(",").map((m2) => m2.trim()).filter(Boolean) : undefined;
|
|
95990
|
+
const effectiveMode = hasFlag(args, "--interactive") ? "interactive" : hasFlag(args, "--grid") ? "default" : mode;
|
|
95863
95991
|
switch (subcommand) {
|
|
95864
95992
|
case "run": {
|
|
95865
95993
|
if (models.length === 0) {
|
|
95866
|
-
console.error("Error: --models is required
|
|
95994
|
+
console.error("Error: --models is required");
|
|
95995
|
+
printHelp2();
|
|
95867
95996
|
process.exit(1);
|
|
95868
95997
|
}
|
|
95869
|
-
if (
|
|
95870
|
-
const { runWithGrid: runWithGrid2 } = await Promise.resolve().then(() => (init_team_grid(), exports_team_grid));
|
|
95871
|
-
const gridStatus = await runWithGrid2(sessionPath, models, input ?? "", { timeout });
|
|
95872
|
-
printStatus(gridStatus);
|
|
95873
|
-
} else {
|
|
95998
|
+
if (effectiveMode === "json") {
|
|
95874
95999
|
setupSession(sessionPath, models, input);
|
|
95875
96000
|
const runStatus = await runModels(sessionPath, {
|
|
95876
96001
|
timeout,
|
|
@@ -95880,17 +96005,22 @@ async function teamCommand(args) {
|
|
|
95880
96005
|
}
|
|
95881
96006
|
});
|
|
95882
96007
|
printStatus(runStatus);
|
|
96008
|
+
} else {
|
|
96009
|
+
const { runWithGrid: runWithGrid2 } = await Promise.resolve().then(() => (init_team_grid(), exports_team_grid));
|
|
96010
|
+
const interactive = effectiveMode === "interactive";
|
|
96011
|
+
const gridStatus = await runWithGrid2(sessionPath, models, input ?? "", { timeout, interactive });
|
|
96012
|
+
printStatus(gridStatus);
|
|
95883
96013
|
}
|
|
95884
96014
|
break;
|
|
95885
96015
|
}
|
|
95886
96016
|
case "judge": {
|
|
95887
|
-
|
|
96017
|
+
await judgeResponses(sessionPath, { judges });
|
|
95888
96018
|
console.log(readFileSync22(join28(sessionPath, "verdict.md"), "utf-8"));
|
|
95889
96019
|
break;
|
|
95890
96020
|
}
|
|
95891
96021
|
case "run-and-judge": {
|
|
95892
96022
|
if (models.length === 0) {
|
|
95893
|
-
console.error("Error: --models is required
|
|
96023
|
+
console.error("Error: --models is required");
|
|
95894
96024
|
process.exit(1);
|
|
95895
96025
|
}
|
|
95896
96026
|
setupSession(sessionPath, models, input);
|
|
@@ -95907,15 +96037,10 @@ async function teamCommand(args) {
|
|
|
95907
96037
|
break;
|
|
95908
96038
|
}
|
|
95909
96039
|
case "status": {
|
|
95910
|
-
const
|
|
95911
|
-
printStatus(
|
|
96040
|
+
const statusResult = getStatus(sessionPath);
|
|
96041
|
+
printStatus(statusResult);
|
|
95912
96042
|
break;
|
|
95913
96043
|
}
|
|
95914
|
-
default: {
|
|
95915
|
-
console.error(`Unknown team subcommand: ${subcommand}`);
|
|
95916
|
-
printHelp2();
|
|
95917
|
-
process.exit(1);
|
|
95918
|
-
}
|
|
95919
96044
|
}
|
|
95920
96045
|
}
|
|
95921
96046
|
var init_team_cli = __esm(() => {
|
|
@@ -95929,7 +96054,7 @@ __export(exports_claude_runner, {
|
|
|
95929
96054
|
checkClaudeInstalled: () => checkClaudeInstalled
|
|
95930
96055
|
});
|
|
95931
96056
|
import { spawn as spawn4 } from "child_process";
|
|
95932
|
-
import { writeFileSync as
|
|
96057
|
+
import { writeFileSync as writeFileSync16, unlinkSync as unlinkSync9, mkdirSync as mkdirSync15, existsSync as existsSync28, readFileSync as readFileSync23 } from "fs";
|
|
95933
96058
|
import { tmpdir as tmpdir2, homedir as homedir25 } from "os";
|
|
95934
96059
|
import { join as join29 } from "path";
|
|
95935
96060
|
function hasNativeAnthropicMapping(config3) {
|
|
@@ -96038,14 +96163,14 @@ process.stdin.on('end', () => {
|
|
|
96038
96163
|
}
|
|
96039
96164
|
});
|
|
96040
96165
|
`;
|
|
96041
|
-
|
|
96166
|
+
writeFileSync16(scriptPath, script, "utf-8");
|
|
96042
96167
|
return scriptPath;
|
|
96043
96168
|
}
|
|
96044
96169
|
function createTempSettingsFile(modelDisplay, port) {
|
|
96045
96170
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
|
|
96046
96171
|
const claudishDir = join29(homeDir, ".claudish");
|
|
96047
96172
|
try {
|
|
96048
|
-
|
|
96173
|
+
mkdirSync15(claudishDir, { recursive: true });
|
|
96049
96174
|
} catch {}
|
|
96050
96175
|
const timestamp = Date.now();
|
|
96051
96176
|
const tempPath = join29(claudishDir, `settings-${timestamp}.json`);
|
|
@@ -96071,7 +96196,7 @@ function createTempSettingsFile(modelDisplay, port) {
|
|
|
96071
96196
|
padding: 0
|
|
96072
96197
|
};
|
|
96073
96198
|
const settings = { statusLine };
|
|
96074
|
-
|
|
96199
|
+
writeFileSync16(tempPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
96075
96200
|
return { path: tempPath, statusLine };
|
|
96076
96201
|
}
|
|
96077
96202
|
function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine) {
|
|
@@ -96089,7 +96214,7 @@ function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine) {
|
|
|
96089
96214
|
userSettings = JSON.parse(rawUserSettings);
|
|
96090
96215
|
}
|
|
96091
96216
|
userSettings.statusLine = statusLine;
|
|
96092
|
-
|
|
96217
|
+
writeFileSync16(tempSettingsPath, JSON.stringify(userSettings, null, 2), "utf-8");
|
|
96093
96218
|
} catch {
|
|
96094
96219
|
if (!config3.quiet) {
|
|
96095
96220
|
console.warn(`[claudish] Warning: could not merge user settings: ${userSettingsValue}`);
|
|
@@ -96097,7 +96222,7 @@ function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine) {
|
|
|
96097
96222
|
}
|
|
96098
96223
|
config3.claudeArgs.splice(idx, 2);
|
|
96099
96224
|
}
|
|
96100
|
-
async function runClaudeWithProxy(config3, proxyUrl, onCleanup
|
|
96225
|
+
async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
|
|
96101
96226
|
const hasProfileMappings = config3.modelOpus || config3.modelSonnet || config3.modelHaiku || config3.modelSubagent;
|
|
96102
96227
|
const modelId = config3.model || (hasProfileMappings || config3.monitor ? undefined : "unknown");
|
|
96103
96228
|
const portMatch = proxyUrl.match(/:(\d+)/);
|
|
@@ -96184,28 +96309,20 @@ Or set CLAUDE_PATH to your custom installation:`);
|
|
|
96184
96309
|
}
|
|
96185
96310
|
const needsShell = isWindows2() && claudeBinary.endsWith(".cmd");
|
|
96186
96311
|
const spawnCommand = needsShell ? `"${claudeBinary}"` : claudeBinary;
|
|
96187
|
-
|
|
96188
|
-
|
|
96189
|
-
|
|
96190
|
-
|
|
96191
|
-
|
|
96192
|
-
|
|
96193
|
-
|
|
96194
|
-
|
|
96195
|
-
|
|
96196
|
-
stdio: "inherit",
|
|
96197
|
-
shell: needsShell
|
|
96198
|
-
});
|
|
96199
|
-
setupSignalHandlers(proc, tempSettingsPath, config3.quiet, onCleanup);
|
|
96200
|
-
exitCode = await new Promise((resolve4) => {
|
|
96201
|
-
proc.on("exit", (code) => {
|
|
96202
|
-
resolve4(code ?? 1);
|
|
96203
|
-
});
|
|
96312
|
+
const proc = spawn4(spawnCommand, claudeArgs, {
|
|
96313
|
+
env: env2,
|
|
96314
|
+
stdio: "inherit",
|
|
96315
|
+
shell: needsShell
|
|
96316
|
+
});
|
|
96317
|
+
setupSignalHandlers(proc, tempSettingsPath, config3.quiet, onCleanup);
|
|
96318
|
+
const exitCode = await new Promise((resolve4) => {
|
|
96319
|
+
proc.on("exit", (code) => {
|
|
96320
|
+
resolve4(code ?? 1);
|
|
96204
96321
|
});
|
|
96205
|
-
|
|
96206
|
-
|
|
96207
|
-
|
|
96208
|
-
}
|
|
96322
|
+
});
|
|
96323
|
+
try {
|
|
96324
|
+
unlinkSync9(tempSettingsPath);
|
|
96325
|
+
} catch {}
|
|
96209
96326
|
return exitCode;
|
|
96210
96327
|
}
|
|
96211
96328
|
function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
|
|
@@ -96309,20 +96426,16 @@ var init_claude_runner = __esm(() => {
|
|
|
96309
96426
|
var exports_diag_output = {};
|
|
96310
96427
|
__export(exports_diag_output, {
|
|
96311
96428
|
createDiagOutput: () => createDiagOutput,
|
|
96312
|
-
TmuxDiagOutput: () => TmuxDiagOutput,
|
|
96313
|
-
OpentUiDiagOutput: () => OpentUiDiagOutput,
|
|
96314
96429
|
NullDiagOutput: () => NullDiagOutput,
|
|
96315
|
-
MtmDiagOutput: () => MtmDiagOutput,
|
|
96316
96430
|
LogFileDiagOutput: () => LogFileDiagOutput
|
|
96317
96431
|
});
|
|
96318
|
-
import { createWriteStream as createWriteStream3, mkdirSync as
|
|
96319
|
-
import { execFileSync } from "child_process";
|
|
96432
|
+
import { createWriteStream as createWriteStream3, mkdirSync as mkdirSync16, writeFileSync as writeFileSync17, unlinkSync as unlinkSync10 } from "fs";
|
|
96320
96433
|
import { homedir as homedir26 } from "os";
|
|
96321
96434
|
import { join as join30 } from "path";
|
|
96322
96435
|
function getClaudishDir() {
|
|
96323
96436
|
const dir = join30(homedir26(), ".claudish");
|
|
96324
96437
|
try {
|
|
96325
|
-
|
|
96438
|
+
mkdirSync16(dir, { recursive: true });
|
|
96326
96439
|
} catch {}
|
|
96327
96440
|
return dir;
|
|
96328
96441
|
}
|
|
@@ -96336,7 +96449,7 @@ class LogFileDiagOutput {
|
|
|
96336
96449
|
constructor() {
|
|
96337
96450
|
this.logPath = getDiagLogPath();
|
|
96338
96451
|
try {
|
|
96339
|
-
|
|
96452
|
+
writeFileSync17(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
|
|
96340
96453
|
`);
|
|
96341
96454
|
} catch {}
|
|
96342
96455
|
this.stream = createWriteStream3(this.logPath, { flags: "a" });
|
|
@@ -96363,30 +96476,6 @@ class LogFileDiagOutput {
|
|
|
96363
96476
|
}
|
|
96364
96477
|
}
|
|
96365
96478
|
|
|
96366
|
-
class MtmDiagOutput {
|
|
96367
|
-
runner;
|
|
96368
|
-
constructor(runner) {
|
|
96369
|
-
this.runner = runner;
|
|
96370
|
-
}
|
|
96371
|
-
write(msg) {
|
|
96372
|
-
this.runner.write(msg);
|
|
96373
|
-
}
|
|
96374
|
-
cleanup() {}
|
|
96375
|
-
}
|
|
96376
|
-
|
|
96377
|
-
class OpentUiDiagOutput {
|
|
96378
|
-
inner;
|
|
96379
|
-
constructor(runner) {
|
|
96380
|
-
this.inner = new MtmDiagOutput(runner);
|
|
96381
|
-
}
|
|
96382
|
-
write(msg) {
|
|
96383
|
-
this.inner.write(msg);
|
|
96384
|
-
}
|
|
96385
|
-
cleanup() {
|
|
96386
|
-
this.inner.cleanup();
|
|
96387
|
-
}
|
|
96388
|
-
}
|
|
96389
|
-
|
|
96390
96479
|
class NullDiagOutput {
|
|
96391
96480
|
write(_msg) {}
|
|
96392
96481
|
cleanup() {}
|
|
@@ -96399,389 +96488,22 @@ function createDiagOutput(options) {
|
|
|
96399
96488
|
if (mode === "off") {
|
|
96400
96489
|
return new NullDiagOutput;
|
|
96401
96490
|
}
|
|
96402
|
-
const mtmRunner = options.mtmRunner ?? options.ptyRunner ?? null;
|
|
96403
|
-
if (mode === "pty" || mode === "auto") {
|
|
96404
|
-
if (mtmRunner) {
|
|
96405
|
-
return new MtmDiagOutput(mtmRunner);
|
|
96406
|
-
}
|
|
96407
|
-
if (mode === "pty") {
|
|
96408
|
-
return new LogFileDiagOutput;
|
|
96409
|
-
}
|
|
96410
|
-
}
|
|
96411
|
-
if (mode === "tmux" || mode === "auto") {
|
|
96412
|
-
if (process.env.TMUX) {
|
|
96413
|
-
return new TmuxDiagOutput;
|
|
96414
|
-
}
|
|
96415
|
-
if (mode === "tmux") {
|
|
96416
|
-
return new LogFileDiagOutput;
|
|
96417
|
-
}
|
|
96418
|
-
}
|
|
96419
96491
|
return new LogFileDiagOutput;
|
|
96420
96492
|
}
|
|
96421
|
-
var
|
|
96422
|
-
var init_diag_output = __esm(() => {
|
|
96423
|
-
TmuxDiagOutput = class TmuxDiagOutput extends LogFileDiagOutput {
|
|
96424
|
-
paneId = null;
|
|
96425
|
-
constructor() {
|
|
96426
|
-
super();
|
|
96427
|
-
this.openTmuxPane();
|
|
96428
|
-
}
|
|
96429
|
-
openTmuxPane() {
|
|
96430
|
-
try {
|
|
96431
|
-
const targetPane = process.env.TMUX_PANE || "";
|
|
96432
|
-
const args = ["split-window", "-v", "-l", "5", "-d", "-P", "-F", "#{pane_id}"];
|
|
96433
|
-
if (targetPane) {
|
|
96434
|
-
args.push("-t", targetPane);
|
|
96435
|
-
}
|
|
96436
|
-
args.push("tail", "-f", this.logPath);
|
|
96437
|
-
const output = execFileSync("tmux", args, {
|
|
96438
|
-
encoding: "utf-8",
|
|
96439
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
96440
|
-
});
|
|
96441
|
-
this.paneId = output.trim();
|
|
96442
|
-
} catch {
|
|
96443
|
-
this.paneId = null;
|
|
96444
|
-
}
|
|
96445
|
-
}
|
|
96446
|
-
cleanup() {
|
|
96447
|
-
if (this.paneId) {
|
|
96448
|
-
try {
|
|
96449
|
-
execFileSync("tmux", ["kill-pane", "-t", this.paneId], {
|
|
96450
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
96451
|
-
});
|
|
96452
|
-
} catch {}
|
|
96453
|
-
this.paneId = null;
|
|
96454
|
-
}
|
|
96455
|
-
super.cleanup();
|
|
96456
|
-
}
|
|
96457
|
-
};
|
|
96458
|
-
});
|
|
96459
|
-
|
|
96460
|
-
// src/pty-diag-runner.ts
|
|
96461
|
-
var exports_pty_diag_runner = {};
|
|
96462
|
-
__export(exports_pty_diag_runner, {
|
|
96463
|
-
tryCreatePtyRunner: () => tryCreatePtyRunner,
|
|
96464
|
-
tryCreateMtmRunner: () => tryCreateMtmRunner,
|
|
96465
|
-
PtyDiagRunner: () => MtmDiagRunner,
|
|
96466
|
-
MtmDiagRunner: () => MtmDiagRunner
|
|
96467
|
-
});
|
|
96468
|
-
import { spawn as spawn5 } from "child_process";
|
|
96469
|
-
import {
|
|
96470
|
-
appendFileSync as appendFileSync2,
|
|
96471
|
-
createWriteStream as createWriteStream4,
|
|
96472
|
-
existsSync as existsSync29,
|
|
96473
|
-
mkdirSync as mkdirSync16,
|
|
96474
|
-
readFileSync as readFileSync24,
|
|
96475
|
-
unlinkSync as unlinkSync11
|
|
96476
|
-
} from "fs";
|
|
96477
|
-
import { homedir as homedir27 } from "os";
|
|
96478
|
-
import { dirname as dirname7, join as join31 } from "path";
|
|
96479
|
-
import { execSync as execSync4 } from "child_process";
|
|
96480
|
-
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
96481
|
-
|
|
96482
|
-
class MtmDiagRunner {
|
|
96483
|
-
mtmProc = null;
|
|
96484
|
-
logPath;
|
|
96485
|
-
statusPath;
|
|
96486
|
-
logStream = null;
|
|
96487
|
-
constructor() {
|
|
96488
|
-
const dir = join31(homedir27(), ".claudish");
|
|
96489
|
-
try {
|
|
96490
|
-
mkdirSync16(dir, { recursive: true });
|
|
96491
|
-
} catch {}
|
|
96492
|
-
this.logPath = join31(dir, `diag-${process.pid}.log`);
|
|
96493
|
-
this.statusPath = join31(dir, `status-${process.pid}.txt`);
|
|
96494
|
-
this.logStream = createWriteStream4(this.logPath, { flags: "w" });
|
|
96495
|
-
this.logStream.on("error", () => {});
|
|
96496
|
-
}
|
|
96497
|
-
async run(claudeCommand, claudeArgs, env2) {
|
|
96498
|
-
const mtmBin = this.findMtmBinary();
|
|
96499
|
-
const quotedArgs = claudeArgs.map((a) => shellQuote(a)).join(" ");
|
|
96500
|
-
const claudeCmd = `${shellQuote(claudeCommand)} ${quotedArgs}`;
|
|
96501
|
-
const mergedEnv = { ...process.env, ...env2 };
|
|
96502
|
-
this.mtmProc = spawn5(mtmBin, ["-t", "xterm-256color", "-e", claudeCmd, "-S", this.statusPath, "-L", this.logPath], {
|
|
96503
|
-
stdio: "inherit",
|
|
96504
|
-
env: mergedEnv
|
|
96505
|
-
});
|
|
96506
|
-
const exitCode = await new Promise((resolve4) => {
|
|
96507
|
-
this.mtmProc.on("exit", (code) => {
|
|
96508
|
-
resolve4(code ?? 1);
|
|
96509
|
-
});
|
|
96510
|
-
this.mtmProc.on("error", (err) => {
|
|
96511
|
-
if (this.logStream) {
|
|
96512
|
-
try {
|
|
96513
|
-
this.logStream.write(`[mtm] spawn error: ${err.message}
|
|
96514
|
-
`);
|
|
96515
|
-
} catch {}
|
|
96516
|
-
}
|
|
96517
|
-
resolve4(1);
|
|
96518
|
-
});
|
|
96519
|
-
});
|
|
96520
|
-
this.cleanup();
|
|
96521
|
-
return exitCode;
|
|
96522
|
-
}
|
|
96523
|
-
write(msg) {
|
|
96524
|
-
if (!this.logStream)
|
|
96525
|
-
return;
|
|
96526
|
-
const timestamp = new Date().toISOString();
|
|
96527
|
-
try {
|
|
96528
|
-
this.logStream.write(`[${timestamp}] ${msg}
|
|
96529
|
-
`);
|
|
96530
|
-
} catch {}
|
|
96531
|
-
const parsed = parseLogMessage(msg);
|
|
96532
|
-
if (parsed.isError) {
|
|
96533
|
-
this.errorCount++;
|
|
96534
|
-
this.lastError = parsed.short;
|
|
96535
|
-
if (parsed.provider)
|
|
96536
|
-
this.provider = parsed.provider;
|
|
96537
|
-
}
|
|
96538
|
-
if (msg.includes("HANDLER STARTED") || msg.includes("=== Request")) {
|
|
96539
|
-
this.requestCount++;
|
|
96540
|
-
}
|
|
96541
|
-
const rtMatch = msg.match(/(\d+)ms\b/);
|
|
96542
|
-
if (rtMatch && msg.includes("Response")) {
|
|
96543
|
-
const ms = parseInt(rtMatch[1], 10);
|
|
96544
|
-
this.roundtripSamples.push(ms);
|
|
96545
|
-
if (this.roundtripSamples.length > 20)
|
|
96546
|
-
this.roundtripSamples.shift();
|
|
96547
|
-
this.avgRoundtripMs = Math.round(this.roundtripSamples.reduce((a, b2) => a + b2, 0) / this.roundtripSamples.length);
|
|
96548
|
-
}
|
|
96549
|
-
if (msg.includes("Format:") || msg.includes("Transport:") || msg.includes("Translator:")) {
|
|
96550
|
-
const parts = msg.split(":").slice(1).join(":").trim();
|
|
96551
|
-
if (parts)
|
|
96552
|
-
this.adapters = parts;
|
|
96553
|
-
}
|
|
96554
|
-
if (msg.includes("Auth refreshed") && msg.includes("tier:")) {
|
|
96555
|
-
const tierMatch = msg.match(/tier:\s*(.+)$/);
|
|
96556
|
-
if (tierMatch)
|
|
96557
|
-
this.provider = tierMatch[1].trim();
|
|
96558
|
-
}
|
|
96559
|
-
if (msg.includes("[Fallback]") && msg.includes("succeeded")) {
|
|
96560
|
-
const fbMatch = msg.match(/\[Fallback\]\s+(\S+)\s+succeeded/);
|
|
96561
|
-
if (fbMatch)
|
|
96562
|
-
this.provider = fbMatch[1];
|
|
96563
|
-
}
|
|
96564
|
-
if (msg.includes("Rate limited") && msg.includes("retrying")) {
|
|
96565
|
-
this.lastError = msg.replace(/.*\]\s*/, "").substring(0, 60);
|
|
96566
|
-
}
|
|
96567
|
-
this.refreshStatusBar();
|
|
96568
|
-
}
|
|
96569
|
-
modelName = "";
|
|
96570
|
-
provider = "";
|
|
96571
|
-
port = "";
|
|
96572
|
-
quotaRemaining;
|
|
96573
|
-
tokenPollTimer = null;
|
|
96574
|
-
lastError = "";
|
|
96575
|
-
errorCount = 0;
|
|
96576
|
-
requestCount = 0;
|
|
96577
|
-
totalCost = 0;
|
|
96578
|
-
avgRoundtripMs = 0;
|
|
96579
|
-
roundtripSamples = [];
|
|
96580
|
-
adapters = "";
|
|
96581
|
-
setPort(port) {
|
|
96582
|
-
this.port = String(port);
|
|
96583
|
-
this.tokenPollTimer = setInterval(() => {
|
|
96584
|
-
const changed = this.readTokenFile();
|
|
96585
|
-
if (changed)
|
|
96586
|
-
this.refreshStatusBar();
|
|
96587
|
-
}, 3000);
|
|
96588
|
-
}
|
|
96589
|
-
setModel(name) {
|
|
96590
|
-
this.modelName = name.includes("/") ? name.split("/").pop() : name;
|
|
96591
|
-
if (name.includes("@")) {
|
|
96592
|
-
this.provider = name.split("@")[0];
|
|
96593
|
-
} else if (name.includes("/")) {
|
|
96594
|
-
this.provider = name.split("/")[0];
|
|
96595
|
-
}
|
|
96596
|
-
}
|
|
96597
|
-
readTokenFile() {
|
|
96598
|
-
if (!this.port)
|
|
96599
|
-
return false;
|
|
96600
|
-
try {
|
|
96601
|
-
const tokPath = join31(homedir27(), ".claudish", `tokens-${this.port}.json`);
|
|
96602
|
-
const tok = JSON.parse(readFileSync24(tokPath, "utf-8"));
|
|
96603
|
-
let changed = false;
|
|
96604
|
-
if (typeof tok.quota_remaining === "number" && tok.quota_remaining !== this.quotaRemaining) {
|
|
96605
|
-
this.quotaRemaining = tok.quota_remaining;
|
|
96606
|
-
changed = true;
|
|
96607
|
-
}
|
|
96608
|
-
if (tok.provider_name && tok.provider_name !== this.provider) {
|
|
96609
|
-
this.provider = tok.provider_name;
|
|
96610
|
-
changed = true;
|
|
96611
|
-
}
|
|
96612
|
-
return changed;
|
|
96613
|
-
} catch {
|
|
96614
|
-
return false;
|
|
96615
|
-
}
|
|
96616
|
-
}
|
|
96617
|
-
refreshStatusBar() {
|
|
96618
|
-
this.readTokenFile();
|
|
96619
|
-
const bar = renderStatusBar({
|
|
96620
|
-
model: this.modelName,
|
|
96621
|
-
provider: this.provider,
|
|
96622
|
-
errorCount: this.errorCount,
|
|
96623
|
-
lastError: this.lastError,
|
|
96624
|
-
requestCount: this.requestCount,
|
|
96625
|
-
avgRoundtripMs: this.avgRoundtripMs,
|
|
96626
|
-
quotaRemaining: this.quotaRemaining
|
|
96627
|
-
});
|
|
96628
|
-
try {
|
|
96629
|
-
appendFileSync2(this.statusPath, bar + `
|
|
96630
|
-
`);
|
|
96631
|
-
} catch {}
|
|
96632
|
-
}
|
|
96633
|
-
getLogPath() {
|
|
96634
|
-
return this.logPath;
|
|
96635
|
-
}
|
|
96636
|
-
cleanup() {
|
|
96637
|
-
if (this.tokenPollTimer) {
|
|
96638
|
-
clearInterval(this.tokenPollTimer);
|
|
96639
|
-
this.tokenPollTimer = null;
|
|
96640
|
-
}
|
|
96641
|
-
if (this.logStream) {
|
|
96642
|
-
try {
|
|
96643
|
-
this.logStream.end();
|
|
96644
|
-
} catch {}
|
|
96645
|
-
this.logStream = null;
|
|
96646
|
-
}
|
|
96647
|
-
try {
|
|
96648
|
-
unlinkSync11(this.logPath);
|
|
96649
|
-
} catch {}
|
|
96650
|
-
try {
|
|
96651
|
-
unlinkSync11(this.statusPath);
|
|
96652
|
-
} catch {}
|
|
96653
|
-
if (this.mtmProc) {
|
|
96654
|
-
try {
|
|
96655
|
-
this.mtmProc.kill();
|
|
96656
|
-
} catch {}
|
|
96657
|
-
this.mtmProc = null;
|
|
96658
|
-
}
|
|
96659
|
-
}
|
|
96660
|
-
findMtmBinary() {
|
|
96661
|
-
const thisFile = fileURLToPath7(import.meta.url);
|
|
96662
|
-
const thisDir = dirname7(thisFile);
|
|
96663
|
-
const platform3 = process.platform;
|
|
96664
|
-
const arch = process.arch;
|
|
96665
|
-
const pkgRoot = join31(thisDir, "..");
|
|
96666
|
-
const bundledPlatform = join31(pkgRoot, "native", "mtm", `mtm-${platform3}-${arch}`);
|
|
96667
|
-
if (existsSync29(bundledPlatform))
|
|
96668
|
-
return bundledPlatform;
|
|
96669
|
-
const builtDev = join31(pkgRoot, "native", "mtm", "mtm");
|
|
96670
|
-
if (existsSync29(builtDev))
|
|
96671
|
-
return builtDev;
|
|
96672
|
-
try {
|
|
96673
|
-
const result = execSync4("which mtm", { encoding: "utf-8" }).trim();
|
|
96674
|
-
if (result && this.isMtmFork(result))
|
|
96675
|
-
return result;
|
|
96676
|
-
} catch {}
|
|
96677
|
-
throw new Error("mtm binary not found. Build it with: cd packages/cli/native/mtm && make");
|
|
96678
|
-
}
|
|
96679
|
-
isMtmFork(binPath) {
|
|
96680
|
-
try {
|
|
96681
|
-
const output = execSync4(`"${binPath}" --help 2>&1 || true`, {
|
|
96682
|
-
encoding: "utf-8",
|
|
96683
|
-
timeout: 2000
|
|
96684
|
-
});
|
|
96685
|
-
return output.includes("-e ");
|
|
96686
|
-
} catch {
|
|
96687
|
-
return false;
|
|
96688
|
-
}
|
|
96689
|
-
}
|
|
96690
|
-
}
|
|
96691
|
-
function shellQuote(s) {
|
|
96692
|
-
return "'" + s.replace(/'/g, "'\\''") + "'";
|
|
96693
|
-
}
|
|
96694
|
-
function renderStatusBar(state) {
|
|
96695
|
-
const { model, provider, errorCount, lastError, quotaRemaining } = state;
|
|
96696
|
-
const parts = [];
|
|
96697
|
-
parts.push("M: claudish ");
|
|
96698
|
-
if (model)
|
|
96699
|
-
parts.push(`C: ${model} `);
|
|
96700
|
-
if (provider)
|
|
96701
|
-
parts.push(`D: ${provider}`);
|
|
96702
|
-
if (errorCount > 0) {
|
|
96703
|
-
const errLabel = errorCount === 1 ? "\u26A0 1 error" : `\u26A0 ${errorCount} errors`;
|
|
96704
|
-
parts.push(`R: ${errLabel} `);
|
|
96705
|
-
if (lastError)
|
|
96706
|
-
parts.push(`D: ${lastError}`);
|
|
96707
|
-
}
|
|
96708
|
-
if (typeof quotaRemaining === "number") {
|
|
96709
|
-
const usedPct = Math.round((1 - quotaRemaining) * 100);
|
|
96710
|
-
const barWidth = 8;
|
|
96711
|
-
const usedCols = Math.max(usedPct > 0 ? 1 : 0, Math.round(usedPct / 100 * barWidth));
|
|
96712
|
-
const freeCols = barWidth - usedCols;
|
|
96713
|
-
const bar = "\u2588".repeat(usedCols) + "\u2591".repeat(freeCols);
|
|
96714
|
-
const color = usedPct < 50 ? "g" : usedPct < 80 ? "y" : "r";
|
|
96715
|
-
parts.push(`${color}: ${bar} ${usedPct}%`);
|
|
96716
|
-
}
|
|
96717
|
-
return parts.join("\t");
|
|
96718
|
-
}
|
|
96719
|
-
function parseLogMessage(msg) {
|
|
96720
|
-
const providerMatch = msg.match(/\[(?!Fallback|Streaming|Auto-route|SSE)([^\]]+)\]/);
|
|
96721
|
-
const provider = providerMatch?.[1];
|
|
96722
|
-
if (msg.includes("All") && msg.includes("failed")) {
|
|
96723
|
-
const countMatch = msg.match(/All (\d+)/);
|
|
96724
|
-
return { isError: true, short: `all ${countMatch?.[1] || ""} providers failed`, provider };
|
|
96725
|
-
}
|
|
96726
|
-
if (msg.includes("[Fallback]")) {
|
|
96727
|
-
if (msg.includes("succeeded")) {
|
|
96728
|
-
const n = msg.match(/after (\d+)/)?.[1] || "?";
|
|
96729
|
-
return { isError: false, short: `succeeded after ${n} retries`, provider };
|
|
96730
|
-
}
|
|
96731
|
-
const failMatch = msg.match(/\]\s*(.+?)\s+failed/);
|
|
96732
|
-
return {
|
|
96733
|
-
isError: false,
|
|
96734
|
-
short: failMatch ? `${failMatch[1]} failed, retrying` : "fallback",
|
|
96735
|
-
provider
|
|
96736
|
-
};
|
|
96737
|
-
}
|
|
96738
|
-
const httpMatch = msg.match(/HTTP (\d{3})/);
|
|
96739
|
-
if (httpMatch) {
|
|
96740
|
-
const jsonMatch = msg.match(/"message"\s*:\s*"([^"]+)"/);
|
|
96741
|
-
if (jsonMatch?.[1]) {
|
|
96742
|
-
const detail = jsonMatch[1].replace(/is not a valid model ID/, "invalid model").replace(/Provider returned error/, "provider error");
|
|
96743
|
-
return { isError: true, short: detail, provider };
|
|
96744
|
-
}
|
|
96745
|
-
const hintMatch = msg.match(/HTTP \d{3}\.\s*(.+?)\.?\s*$/);
|
|
96746
|
-
if (hintMatch?.[1]) {
|
|
96747
|
-
return { isError: true, short: hintMatch[1], provider };
|
|
96748
|
-
}
|
|
96749
|
-
return { isError: true, short: `HTTP ${httpMatch[1]}`, provider };
|
|
96750
|
-
}
|
|
96751
|
-
if (msg.toLowerCase().includes("error")) {
|
|
96752
|
-
const short = msg.replace(/^Error\s*\[[^\]]+\]:\s*/, "").replace(/\.\s*$/, "");
|
|
96753
|
-
return { isError: true, short: short.length > 80 ? short.slice(0, 79) + "\u2026" : short, provider };
|
|
96754
|
-
}
|
|
96755
|
-
return { isError: false, short: msg.length > 80 ? msg.slice(0, 79) + "\u2026" : msg };
|
|
96756
|
-
}
|
|
96757
|
-
async function tryCreateMtmRunner() {
|
|
96758
|
-
if (process.env.MTM)
|
|
96759
|
-
return null;
|
|
96760
|
-
try {
|
|
96761
|
-
const runner = new MtmDiagRunner;
|
|
96762
|
-
runner.findMtmBinary();
|
|
96763
|
-
return runner;
|
|
96764
|
-
} catch {
|
|
96765
|
-
return null;
|
|
96766
|
-
}
|
|
96767
|
-
}
|
|
96768
|
-
var tryCreatePtyRunner;
|
|
96769
|
-
var init_pty_diag_runner = __esm(() => {
|
|
96770
|
-
tryCreatePtyRunner = tryCreateMtmRunner;
|
|
96771
|
-
});
|
|
96493
|
+
var init_diag_output = () => {};
|
|
96772
96494
|
|
|
96773
96495
|
// src/index.ts
|
|
96774
96496
|
var import_dotenv3 = __toESM(require_main(), 1);
|
|
96775
|
-
import { existsSync as
|
|
96776
|
-
import { homedir as
|
|
96777
|
-
import { join as
|
|
96497
|
+
import { existsSync as existsSync29, readFileSync as readFileSync24 } from "fs";
|
|
96498
|
+
import { homedir as homedir27 } from "os";
|
|
96499
|
+
import { join as join31 } from "path";
|
|
96778
96500
|
import_dotenv3.config({ quiet: true });
|
|
96779
96501
|
function loadStoredApiKeys() {
|
|
96780
96502
|
try {
|
|
96781
|
-
const configPath =
|
|
96782
|
-
if (!
|
|
96503
|
+
const configPath = join31(homedir27(), ".claudish", "config.json");
|
|
96504
|
+
if (!existsSync29(configPath))
|
|
96783
96505
|
return;
|
|
96784
|
-
const raw2 =
|
|
96506
|
+
const raw2 = readFileSync24(configPath, "utf-8");
|
|
96785
96507
|
const cfg = JSON.parse(raw2);
|
|
96786
96508
|
if (cfg.apiKeys) {
|
|
96787
96509
|
for (const [envVar, value] of Object.entries(cfg.apiKeys)) {
|
|
@@ -96882,8 +96604,7 @@ async function runCli() {
|
|
|
96882
96604
|
getMissingKeysError: getMissingKeysError2
|
|
96883
96605
|
} = await Promise.resolve().then(() => (init_provider_resolver(), exports_provider_resolver));
|
|
96884
96606
|
const { initLogger: initLogger2, getLogFilePath: getLogFilePath2, getAlwaysOnLogPath: getAlwaysOnLogPath2, setDiagOutput: setDiagOutput2 } = await Promise.resolve().then(() => (init_logger(), exports_logger));
|
|
96885
|
-
const { createDiagOutput: createDiagOutput2
|
|
96886
|
-
const { tryCreateMtmRunner: tryCreateMtmRunner2 } = await Promise.resolve().then(() => (init_pty_diag_runner(), exports_pty_diag_runner));
|
|
96607
|
+
const { createDiagOutput: createDiagOutput2 } = await Promise.resolve().then(() => (init_diag_output(), exports_diag_output));
|
|
96887
96608
|
const { findAvailablePort: findAvailablePort2 } = await Promise.resolve().then(() => (init_port_manager(), exports_port_manager));
|
|
96888
96609
|
const { createProxyServer: createProxyServer2 } = await Promise.resolve().then(() => (init_proxy_server(), exports_proxy_server));
|
|
96889
96610
|
const { checkForUpdates: checkForUpdates2 } = await Promise.resolve().then(() => (init_update_checker(), exports_update_checker));
|
|
@@ -97038,27 +96759,16 @@ async function runCli() {
|
|
|
97038
96759
|
quiet: cliConfig.quiet,
|
|
97039
96760
|
isInteractive: cliConfig.interactive
|
|
97040
96761
|
});
|
|
97041
|
-
const needsMtm = cliConfig.interactive && (cliConfig.diagMode === "auto" || cliConfig.diagMode === "pty");
|
|
97042
|
-
const mtmRunner = needsMtm ? await tryCreateMtmRunner2() : null;
|
|
97043
|
-
if (mtmRunner) {
|
|
97044
|
-
if (explicitModel)
|
|
97045
|
-
mtmRunner.setModel(explicitModel);
|
|
97046
|
-
mtmRunner.setPort(port);
|
|
97047
|
-
}
|
|
97048
96762
|
const diag = createDiagOutput2({
|
|
97049
96763
|
interactive: cliConfig.interactive,
|
|
97050
|
-
mtmRunner,
|
|
97051
96764
|
diagMode: cliConfig.diagMode
|
|
97052
96765
|
});
|
|
97053
96766
|
if (cliConfig.interactive) {
|
|
97054
96767
|
setDiagOutput2(diag);
|
|
97055
|
-
if (!mtmRunner && !process.env.TMUX && !cliConfig.quiet && diag instanceof LogFileDiagOutput2) {
|
|
97056
|
-
console.log(`[claudish] Diagnostic log: ${diag.getLogPath()}`);
|
|
97057
|
-
}
|
|
97058
96768
|
}
|
|
97059
96769
|
let exitCode = 0;
|
|
97060
96770
|
try {
|
|
97061
|
-
exitCode = await runClaudeWithProxy2(cliConfig, proxy.url, () => diag.cleanup()
|
|
96771
|
+
exitCode = await runClaudeWithProxy2(cliConfig, proxy.url, () => diag.cleanup());
|
|
97062
96772
|
} finally {
|
|
97063
96773
|
setDiagOutput2(null);
|
|
97064
96774
|
diag.cleanup();
|