claudish 5.14.0 → 5.16.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 +1917 -821
- package/package.json +1 -1
- package/recommended-models.json +1 -1
package/dist/index.js
CHANGED
|
@@ -28416,19 +28416,379 @@ var init_stdio2 = __esm(() => {
|
|
|
28416
28416
|
init_stdio();
|
|
28417
28417
|
});
|
|
28418
28418
|
|
|
28419
|
+
// src/team-orchestrator.ts
|
|
28420
|
+
import { spawn } from "child_process";
|
|
28421
|
+
import {
|
|
28422
|
+
mkdirSync,
|
|
28423
|
+
writeFileSync,
|
|
28424
|
+
readFileSync,
|
|
28425
|
+
existsSync,
|
|
28426
|
+
readdirSync,
|
|
28427
|
+
statSync,
|
|
28428
|
+
createWriteStream
|
|
28429
|
+
} from "fs";
|
|
28430
|
+
import { join, resolve } from "path";
|
|
28431
|
+
function validateSessionPath(sessionPath) {
|
|
28432
|
+
const resolved = resolve(sessionPath);
|
|
28433
|
+
const cwd = process.cwd();
|
|
28434
|
+
if (!resolved.startsWith(cwd + "/") && resolved !== cwd) {
|
|
28435
|
+
throw new Error(`Session path must be within current directory: ${sessionPath}`);
|
|
28436
|
+
}
|
|
28437
|
+
return resolved;
|
|
28438
|
+
}
|
|
28439
|
+
function setupSession(sessionPath, models, input) {
|
|
28440
|
+
if (models.length === 0) {
|
|
28441
|
+
throw new Error("At least one model is required");
|
|
28442
|
+
}
|
|
28443
|
+
mkdirSync(join(sessionPath, "work"), { recursive: true });
|
|
28444
|
+
mkdirSync(join(sessionPath, "errors"), { recursive: true });
|
|
28445
|
+
if (input !== undefined) {
|
|
28446
|
+
writeFileSync(join(sessionPath, "input.md"), input, "utf-8");
|
|
28447
|
+
} else if (!existsSync(join(sessionPath, "input.md"))) {
|
|
28448
|
+
throw new Error(`No input.md found at ${sessionPath} and no input provided`);
|
|
28449
|
+
}
|
|
28450
|
+
const ids = models.map((_, i) => String(i + 1).padStart(2, "0"));
|
|
28451
|
+
const shuffled = fisherYatesShuffle([...ids]);
|
|
28452
|
+
const now = new Date().toISOString();
|
|
28453
|
+
const manifest = {
|
|
28454
|
+
created: now,
|
|
28455
|
+
models: {},
|
|
28456
|
+
shuffleOrder: shuffled
|
|
28457
|
+
};
|
|
28458
|
+
for (let i = 0;i < models.length; i++) {
|
|
28459
|
+
const anonId = shuffled[i];
|
|
28460
|
+
manifest.models[anonId] = {
|
|
28461
|
+
model: models[i],
|
|
28462
|
+
assignedAt: now
|
|
28463
|
+
};
|
|
28464
|
+
mkdirSync(join(sessionPath, "work", anonId), { recursive: true });
|
|
28465
|
+
}
|
|
28466
|
+
writeFileSync(join(sessionPath, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
|
|
28467
|
+
const status = {
|
|
28468
|
+
startedAt: now,
|
|
28469
|
+
models: Object.fromEntries(Object.keys(manifest.models).map((id) => [
|
|
28470
|
+
id,
|
|
28471
|
+
{
|
|
28472
|
+
state: "PENDING",
|
|
28473
|
+
exitCode: null,
|
|
28474
|
+
startedAt: null,
|
|
28475
|
+
completedAt: null,
|
|
28476
|
+
outputSize: 0
|
|
28477
|
+
}
|
|
28478
|
+
]))
|
|
28479
|
+
};
|
|
28480
|
+
writeFileSync(join(sessionPath, "status.json"), JSON.stringify(status, null, 2), "utf-8");
|
|
28481
|
+
return manifest;
|
|
28482
|
+
}
|
|
28483
|
+
async function runModels(sessionPath, opts = {}) {
|
|
28484
|
+
const timeoutMs = (opts.timeout ?? 300) * 1000;
|
|
28485
|
+
const manifest = JSON.parse(readFileSync(join(sessionPath, "manifest.json"), "utf-8"));
|
|
28486
|
+
const statusPath = join(sessionPath, "status.json");
|
|
28487
|
+
const inputPath = join(sessionPath, "input.md");
|
|
28488
|
+
const inputContent = readFileSync(inputPath, "utf-8");
|
|
28489
|
+
const statusCache = JSON.parse(readFileSync(statusPath, "utf-8"));
|
|
28490
|
+
function updateModelStatus(id, update) {
|
|
28491
|
+
statusCache.models[id] = { ...statusCache.models[id], ...update };
|
|
28492
|
+
writeFileSync(statusPath, JSON.stringify(statusCache, null, 2), "utf-8");
|
|
28493
|
+
}
|
|
28494
|
+
const processes = new Map;
|
|
28495
|
+
const sigintHandler = () => {
|
|
28496
|
+
for (const [, proc] of processes) {
|
|
28497
|
+
if (!proc.killed)
|
|
28498
|
+
proc.kill("SIGTERM");
|
|
28499
|
+
}
|
|
28500
|
+
process.exit(1);
|
|
28501
|
+
};
|
|
28502
|
+
process.on("SIGINT", sigintHandler);
|
|
28503
|
+
const completionPromises = [];
|
|
28504
|
+
for (const [anonId, entry] of Object.entries(manifest.models)) {
|
|
28505
|
+
const outputPath = join(sessionPath, `response-${anonId}.md`);
|
|
28506
|
+
const errorLogPath = join(sessionPath, "errors", `${anonId}.log`);
|
|
28507
|
+
const workDir = join(sessionPath, "work", anonId);
|
|
28508
|
+
const args = [
|
|
28509
|
+
"--model",
|
|
28510
|
+
entry.model,
|
|
28511
|
+
"-y",
|
|
28512
|
+
"--stdin",
|
|
28513
|
+
"--quiet",
|
|
28514
|
+
...opts.claudeFlags ?? []
|
|
28515
|
+
];
|
|
28516
|
+
updateModelStatus(anonId, {
|
|
28517
|
+
state: "RUNNING",
|
|
28518
|
+
startedAt: new Date().toISOString()
|
|
28519
|
+
});
|
|
28520
|
+
const proc = spawn("claudish", args, {
|
|
28521
|
+
cwd: workDir,
|
|
28522
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
28523
|
+
shell: false
|
|
28524
|
+
});
|
|
28525
|
+
const outputStream = createWriteStream(outputPath);
|
|
28526
|
+
proc.stdout?.pipe(outputStream);
|
|
28527
|
+
let stderr = "";
|
|
28528
|
+
proc.stderr?.on("data", (chunk) => {
|
|
28529
|
+
stderr += chunk.toString();
|
|
28530
|
+
});
|
|
28531
|
+
proc.stdin?.write(inputContent);
|
|
28532
|
+
proc.stdin?.end();
|
|
28533
|
+
const completionPromise = new Promise((resolve2) => {
|
|
28534
|
+
let exitCode = null;
|
|
28535
|
+
let resolved = false;
|
|
28536
|
+
const finish = () => {
|
|
28537
|
+
if (resolved)
|
|
28538
|
+
return;
|
|
28539
|
+
resolved = true;
|
|
28540
|
+
let outputSize = 0;
|
|
28541
|
+
try {
|
|
28542
|
+
outputSize = statSync(outputPath).size;
|
|
28543
|
+
} catch {}
|
|
28544
|
+
updateModelStatus(anonId, {
|
|
28545
|
+
state: exitCode === 0 ? "COMPLETED" : "FAILED",
|
|
28546
|
+
exitCode: exitCode ?? 1,
|
|
28547
|
+
completedAt: new Date().toISOString(),
|
|
28548
|
+
outputSize
|
|
28549
|
+
});
|
|
28550
|
+
opts.onStatusChange?.(anonId, statusCache.models[anonId]);
|
|
28551
|
+
resolve2();
|
|
28552
|
+
};
|
|
28553
|
+
outputStream.on("close", finish);
|
|
28554
|
+
proc.on("exit", (code) => {
|
|
28555
|
+
const current = statusCache.models[anonId];
|
|
28556
|
+
if (current?.state === "TIMEOUT") {
|
|
28557
|
+
resolved = true;
|
|
28558
|
+
resolve2();
|
|
28559
|
+
return;
|
|
28560
|
+
}
|
|
28561
|
+
if (stderr) {
|
|
28562
|
+
writeFileSync(errorLogPath, stderr, "utf-8");
|
|
28563
|
+
}
|
|
28564
|
+
exitCode = code;
|
|
28565
|
+
if (outputStream.destroyed) {
|
|
28566
|
+
finish();
|
|
28567
|
+
}
|
|
28568
|
+
});
|
|
28569
|
+
});
|
|
28570
|
+
processes.set(anonId, proc);
|
|
28571
|
+
completionPromises.push(completionPromise);
|
|
28572
|
+
}
|
|
28573
|
+
let timeoutHandle = null;
|
|
28574
|
+
await Promise.race([
|
|
28575
|
+
Promise.all(completionPromises),
|
|
28576
|
+
new Promise((resolve2) => {
|
|
28577
|
+
timeoutHandle = setTimeout(() => {
|
|
28578
|
+
for (const [id, proc] of processes) {
|
|
28579
|
+
if (!proc.killed) {
|
|
28580
|
+
proc.kill("SIGTERM");
|
|
28581
|
+
updateModelStatus(id, {
|
|
28582
|
+
state: "TIMEOUT",
|
|
28583
|
+
completedAt: new Date().toISOString()
|
|
28584
|
+
});
|
|
28585
|
+
opts.onStatusChange?.(id, statusCache.models[id]);
|
|
28586
|
+
}
|
|
28587
|
+
}
|
|
28588
|
+
resolve2();
|
|
28589
|
+
}, timeoutMs);
|
|
28590
|
+
})
|
|
28591
|
+
]);
|
|
28592
|
+
if (timeoutHandle !== null)
|
|
28593
|
+
clearTimeout(timeoutHandle);
|
|
28594
|
+
process.off("SIGINT", sigintHandler);
|
|
28595
|
+
return statusCache;
|
|
28596
|
+
}
|
|
28597
|
+
async function judgeResponses(sessionPath, opts = {}) {
|
|
28598
|
+
const responseFiles = readdirSync(sessionPath).filter((f) => f.startsWith("response-") && f.endsWith(".md")).sort();
|
|
28599
|
+
if (responseFiles.length < 2) {
|
|
28600
|
+
throw new Error(`Need at least 2 responses to judge, found ${responseFiles.length}`);
|
|
28601
|
+
}
|
|
28602
|
+
const responses = {};
|
|
28603
|
+
for (const file2 of responseFiles) {
|
|
28604
|
+
const id = file2.replace(/^response-/, "").replace(/\.md$/, "");
|
|
28605
|
+
responses[id] = readFileSync(join(sessionPath, file2), "utf-8");
|
|
28606
|
+
}
|
|
28607
|
+
const input = readFileSync(join(sessionPath, "input.md"), "utf-8");
|
|
28608
|
+
const judgePrompt = buildJudgePrompt(input, responses);
|
|
28609
|
+
writeFileSync(join(sessionPath, "judge-prompt.md"), judgePrompt, "utf-8");
|
|
28610
|
+
const judgeModels = opts.judges ?? getDefaultJudgeModels(sessionPath);
|
|
28611
|
+
const judgePath = join(sessionPath, "judging");
|
|
28612
|
+
mkdirSync(judgePath, { recursive: true });
|
|
28613
|
+
setupSession(judgePath, judgeModels, judgePrompt);
|
|
28614
|
+
await runModels(judgePath, { claudeFlags: opts.claudeFlags });
|
|
28615
|
+
const votes = parseJudgeVotes(judgePath, Object.keys(responses));
|
|
28616
|
+
const verdict = aggregateVerdict(votes, Object.keys(responses));
|
|
28617
|
+
writeFileSync(join(sessionPath, "verdict.md"), formatVerdict(verdict, sessionPath), "utf-8");
|
|
28618
|
+
return verdict;
|
|
28619
|
+
}
|
|
28620
|
+
function getStatus(sessionPath) {
|
|
28621
|
+
return JSON.parse(readFileSync(join(sessionPath, "status.json"), "utf-8"));
|
|
28622
|
+
}
|
|
28623
|
+
function fisherYatesShuffle(arr) {
|
|
28624
|
+
for (let i = arr.length - 1;i > 0; i--) {
|
|
28625
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
28626
|
+
[arr[i], arr[j]] = [arr[j], arr[i]];
|
|
28627
|
+
}
|
|
28628
|
+
return arr;
|
|
28629
|
+
}
|
|
28630
|
+
function getDefaultJudgeModels(sessionPath) {
|
|
28631
|
+
const manifest = JSON.parse(readFileSync(join(sessionPath, "manifest.json"), "utf-8"));
|
|
28632
|
+
return Object.values(manifest.models).map((e) => e.model);
|
|
28633
|
+
}
|
|
28634
|
+
function buildJudgePrompt(input, responses) {
|
|
28635
|
+
const ids = Object.keys(responses).sort();
|
|
28636
|
+
let prompt = `## Blind Evaluation Task
|
|
28637
|
+
|
|
28638
|
+
`;
|
|
28639
|
+
prompt += `### Original Task
|
|
28640
|
+
|
|
28641
|
+
`;
|
|
28642
|
+
prompt += input + `
|
|
28643
|
+
|
|
28644
|
+
`;
|
|
28645
|
+
prompt += `---
|
|
28646
|
+
|
|
28647
|
+
`;
|
|
28648
|
+
prompt += `### Responses to Evaluate
|
|
28649
|
+
|
|
28650
|
+
`;
|
|
28651
|
+
prompt += `Evaluate each response independently. You do not know which model produced which response.
|
|
28652
|
+
|
|
28653
|
+
`;
|
|
28654
|
+
for (const id of ids) {
|
|
28655
|
+
prompt += `#### Response ${id}
|
|
28656
|
+
|
|
28657
|
+
`;
|
|
28658
|
+
prompt += responses[id] + `
|
|
28659
|
+
|
|
28660
|
+
`;
|
|
28661
|
+
prompt += `---
|
|
28662
|
+
|
|
28663
|
+
`;
|
|
28664
|
+
}
|
|
28665
|
+
prompt += `### Your Assignment
|
|
28666
|
+
|
|
28667
|
+
`;
|
|
28668
|
+
prompt += `For EACH of the ${ids.length} responses above, provide a vote block in this exact format:
|
|
28669
|
+
|
|
28670
|
+
`;
|
|
28671
|
+
prompt += "```vote\n";
|
|
28672
|
+
prompt += `RESPONSE: [ID]
|
|
28673
|
+
`;
|
|
28674
|
+
prompt += `VERDICT: [APPROVE|REJECT|ABSTAIN]
|
|
28675
|
+
`;
|
|
28676
|
+
prompt += `CONFIDENCE: [1-10]
|
|
28677
|
+
`;
|
|
28678
|
+
prompt += `SUMMARY: [One sentence]
|
|
28679
|
+
`;
|
|
28680
|
+
prompt += `KEY_ISSUES: [Comma-separated issues, or None]
|
|
28681
|
+
`;
|
|
28682
|
+
prompt += "```\n\n";
|
|
28683
|
+
prompt += `Provide exactly ${ids.length} vote blocks, one per response. Be decisive and analytical.
|
|
28684
|
+
`;
|
|
28685
|
+
return prompt;
|
|
28686
|
+
}
|
|
28687
|
+
function parseJudgeVotes(judgePath, responseIds) {
|
|
28688
|
+
const votes = [];
|
|
28689
|
+
const responseFiles = readdirSync(judgePath).filter((f) => f.startsWith("response-") && f.endsWith(".md")).sort();
|
|
28690
|
+
for (const file2 of responseFiles) {
|
|
28691
|
+
const judgeId = file2.replace(/^response-/, "").replace(/\.md$/, "");
|
|
28692
|
+
let content;
|
|
28693
|
+
try {
|
|
28694
|
+
content = readFileSync(join(judgePath, file2), "utf-8");
|
|
28695
|
+
} catch {
|
|
28696
|
+
continue;
|
|
28697
|
+
}
|
|
28698
|
+
const votePattern = /```vote\s*\n([\s\S]*?)\n\s*```/g;
|
|
28699
|
+
let match;
|
|
28700
|
+
while ((match = votePattern.exec(content)) !== null) {
|
|
28701
|
+
const block = match[1];
|
|
28702
|
+
const responseMatch = block.match(/RESPONSE:\s*(\S+)/);
|
|
28703
|
+
const verdictMatch = block.match(/VERDICT:\s*(APPROVE|REJECT|ABSTAIN)/);
|
|
28704
|
+
const confidenceMatch = block.match(/CONFIDENCE:\s*(\d+)/);
|
|
28705
|
+
const summaryMatch = block.match(/SUMMARY:\s*(.+)/);
|
|
28706
|
+
const keyIssuesMatch = block.match(/KEY_ISSUES:\s*(.+)/);
|
|
28707
|
+
const responseId = responseMatch?.[1];
|
|
28708
|
+
const verdict = verdictMatch?.[1];
|
|
28709
|
+
if (!responseId || !verdict)
|
|
28710
|
+
continue;
|
|
28711
|
+
if (!responseIds.includes(responseId))
|
|
28712
|
+
continue;
|
|
28713
|
+
votes.push({
|
|
28714
|
+
judgeId,
|
|
28715
|
+
responseId,
|
|
28716
|
+
verdict,
|
|
28717
|
+
confidence: parseInt(confidenceMatch?.[1] ?? "5", 10),
|
|
28718
|
+
summary: summaryMatch?.[1]?.trim() ?? "",
|
|
28719
|
+
keyIssues: keyIssuesMatch?.[1]?.split(",").map((s) => s.trim()).filter((s) => s.toLowerCase() !== "none" && s.length > 0) ?? []
|
|
28720
|
+
});
|
|
28721
|
+
}
|
|
28722
|
+
}
|
|
28723
|
+
return votes;
|
|
28724
|
+
}
|
|
28725
|
+
function aggregateVerdict(votes, responseIds) {
|
|
28726
|
+
const responses = {};
|
|
28727
|
+
for (const id of responseIds) {
|
|
28728
|
+
const votesForResponse = votes.filter((v) => v.responseId === id);
|
|
28729
|
+
const approvals = votesForResponse.filter((v) => v.verdict === "APPROVE").length;
|
|
28730
|
+
const rejections = votesForResponse.filter((v) => v.verdict === "REJECT").length;
|
|
28731
|
+
const abstentions = votesForResponse.filter((v) => v.verdict === "ABSTAIN").length;
|
|
28732
|
+
const total = approvals + rejections;
|
|
28733
|
+
responses[id] = {
|
|
28734
|
+
approvals,
|
|
28735
|
+
rejections,
|
|
28736
|
+
abstentions,
|
|
28737
|
+
score: total > 0 ? approvals / total : 0
|
|
28738
|
+
};
|
|
28739
|
+
}
|
|
28740
|
+
const ranking = Object.entries(responses).sort(([, a], [, b]) => b.score - a.score).map(([id]) => id);
|
|
28741
|
+
return { responses, ranking, votes };
|
|
28742
|
+
}
|
|
28743
|
+
function formatVerdict(verdict, sessionPath) {
|
|
28744
|
+
let manifest = null;
|
|
28745
|
+
try {
|
|
28746
|
+
manifest = JSON.parse(readFileSync(join(sessionPath, "manifest.json"), "utf-8"));
|
|
28747
|
+
} catch {}
|
|
28748
|
+
let output = `# Team Verdict
|
|
28749
|
+
|
|
28750
|
+
`;
|
|
28751
|
+
output += `## Ranking
|
|
28752
|
+
|
|
28753
|
+
`;
|
|
28754
|
+
output += `| Rank | Response | Model | Score | Approvals | Rejections | Abstentions |
|
|
28755
|
+
`;
|
|
28756
|
+
output += `|------|----------|-------|-------|-----------|------------|-------------|
|
|
28757
|
+
`;
|
|
28758
|
+
for (let i = 0;i < verdict.ranking.length; i++) {
|
|
28759
|
+
const id = verdict.ranking[i];
|
|
28760
|
+
const r = verdict.responses[id];
|
|
28761
|
+
const modelName = manifest?.models[id]?.model ?? "unknown";
|
|
28762
|
+
const scoreStr = `${(r.score * 100).toFixed(0)}%`;
|
|
28763
|
+
output += `| ${i + 1} | ${id} | ${modelName} | ${scoreStr} | ${r.approvals} | ${r.rejections} | ${r.abstentions} |
|
|
28764
|
+
`;
|
|
28765
|
+
}
|
|
28766
|
+
output += `
|
|
28767
|
+
## Individual Votes
|
|
28768
|
+
|
|
28769
|
+
`;
|
|
28770
|
+
for (const vote of verdict.votes) {
|
|
28771
|
+
const issueStr = vote.keyIssues.length > 0 ? ` Issues: ${vote.keyIssues.join(", ")}.` : "";
|
|
28772
|
+
output += `- **Judge ${vote.judgeId}** -> Response ${vote.responseId}: **${vote.verdict}** (${vote.confidence}/10) \u2014 ${vote.summary}${issueStr}
|
|
28773
|
+
`;
|
|
28774
|
+
}
|
|
28775
|
+
return output;
|
|
28776
|
+
}
|
|
28777
|
+
var init_team_orchestrator = () => {};
|
|
28778
|
+
|
|
28419
28779
|
// src/mcp-server.ts
|
|
28420
28780
|
var exports_mcp_server = {};
|
|
28421
28781
|
__export(exports_mcp_server, {
|
|
28422
28782
|
startMcpServer: () => startMcpServer
|
|
28423
28783
|
});
|
|
28424
|
-
import { readFileSync, existsSync, writeFileSync, mkdirSync } from "fs";
|
|
28425
|
-
import { join, dirname } from "path";
|
|
28784
|
+
import { readFileSync as readFileSync2, existsSync as existsSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
28785
|
+
import { join as join2, dirname } from "path";
|
|
28426
28786
|
import { homedir } from "os";
|
|
28427
28787
|
import { fileURLToPath } from "url";
|
|
28428
28788
|
function loadRecommendedModels() {
|
|
28429
|
-
if (
|
|
28789
|
+
if (existsSync2(RECOMMENDED_MODELS_PATH)) {
|
|
28430
28790
|
try {
|
|
28431
|
-
const data = JSON.parse(
|
|
28791
|
+
const data = JSON.parse(readFileSync2(RECOMMENDED_MODELS_PATH, "utf-8"));
|
|
28432
28792
|
return data.models || [];
|
|
28433
28793
|
} catch {
|
|
28434
28794
|
return [];
|
|
@@ -28437,9 +28797,9 @@ function loadRecommendedModels() {
|
|
|
28437
28797
|
return [];
|
|
28438
28798
|
}
|
|
28439
28799
|
async function loadAllModels(forceRefresh = false) {
|
|
28440
|
-
if (!forceRefresh &&
|
|
28800
|
+
if (!forceRefresh && existsSync2(ALL_MODELS_CACHE_PATH)) {
|
|
28441
28801
|
try {
|
|
28442
|
-
const cacheData = JSON.parse(
|
|
28802
|
+
const cacheData = JSON.parse(readFileSync2(ALL_MODELS_CACHE_PATH, "utf-8"));
|
|
28443
28803
|
const lastUpdated = new Date(cacheData.lastUpdated);
|
|
28444
28804
|
const ageInDays = (Date.now() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
|
|
28445
28805
|
if (ageInDays <= CACHE_MAX_AGE_DAYS) {
|
|
@@ -28453,15 +28813,15 @@ async function loadAllModels(forceRefresh = false) {
|
|
|
28453
28813
|
throw new Error(`API returned ${response.status}`);
|
|
28454
28814
|
const data = await response.json();
|
|
28455
28815
|
const models = data.data || [];
|
|
28456
|
-
|
|
28457
|
-
|
|
28816
|
+
mkdirSync2(CLAUDISH_CACHE_DIR, { recursive: true });
|
|
28817
|
+
writeFileSync2(ALL_MODELS_CACHE_PATH, JSON.stringify({
|
|
28458
28818
|
lastUpdated: new Date().toISOString(),
|
|
28459
28819
|
models
|
|
28460
28820
|
}), "utf-8");
|
|
28461
28821
|
return models;
|
|
28462
28822
|
} catch (error46) {
|
|
28463
|
-
if (
|
|
28464
|
-
const cacheData = JSON.parse(
|
|
28823
|
+
if (existsSync2(ALL_MODELS_CACHE_PATH)) {
|
|
28824
|
+
const cacheData = JSON.parse(readFileSync2(ALL_MODELS_CACHE_PATH, "utf-8"));
|
|
28465
28825
|
return cacheData.models || [];
|
|
28466
28826
|
}
|
|
28467
28827
|
return [];
|
|
@@ -28488,7 +28848,7 @@ async function runPrompt(model, prompt, systemPrompt, maxTokens) {
|
|
|
28488
28848
|
body: JSON.stringify({
|
|
28489
28849
|
model,
|
|
28490
28850
|
messages,
|
|
28491
|
-
max_tokens: maxTokens
|
|
28851
|
+
...maxTokens ? { max_tokens: maxTokens } : {}
|
|
28492
28852
|
})
|
|
28493
28853
|
});
|
|
28494
28854
|
if (!response.ok) {
|
|
@@ -28526,7 +28886,7 @@ async function main() {
|
|
|
28526
28886
|
model: exports_external.string().describe("OpenRouter model ID (e.g., 'x-ai/grok-code-fast-1', 'openai/gpt-5.1-codex')"),
|
|
28527
28887
|
prompt: exports_external.string().describe("The prompt to send to the model"),
|
|
28528
28888
|
system_prompt: exports_external.string().optional().describe("Optional system prompt"),
|
|
28529
|
-
max_tokens: exports_external.number().optional().describe("Maximum tokens in response (
|
|
28889
|
+
max_tokens: exports_external.number().optional().describe("Maximum tokens in response (omit to let model decide)")
|
|
28530
28890
|
}, async ({ model, prompt, system_prompt, max_tokens }) => {
|
|
28531
28891
|
try {
|
|
28532
28892
|
const result = await runPrompt(model, prompt, system_prompt, max_tokens);
|
|
@@ -28633,12 +28993,13 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
28633
28993
|
server.tool("compare_models", "Run the same prompt through multiple models and compare responses", {
|
|
28634
28994
|
models: exports_external.array(exports_external.string()).describe("List of model IDs to compare"),
|
|
28635
28995
|
prompt: exports_external.string().describe("The prompt to send to all models"),
|
|
28636
|
-
system_prompt: exports_external.string().optional().describe("Optional system prompt")
|
|
28637
|
-
|
|
28996
|
+
system_prompt: exports_external.string().optional().describe("Optional system prompt"),
|
|
28997
|
+
max_tokens: exports_external.number().optional().describe("Maximum tokens in response (omit to let model decide)")
|
|
28998
|
+
}, async ({ models, prompt, system_prompt, max_tokens }) => {
|
|
28638
28999
|
const results = [];
|
|
28639
29000
|
for (const model of models) {
|
|
28640
29001
|
try {
|
|
28641
|
-
const result = await runPrompt(model, prompt, system_prompt,
|
|
29002
|
+
const result = await runPrompt(model, prompt, system_prompt, max_tokens);
|
|
28642
29003
|
results.push({
|
|
28643
29004
|
model,
|
|
28644
29005
|
response: result.content,
|
|
@@ -28682,6 +29043,93 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
28682
29043
|
}
|
|
28683
29044
|
return { content: [{ type: "text", text: output }] };
|
|
28684
29045
|
});
|
|
29046
|
+
server.tool("team_run", "Run multiple AI models on a task and produce anonymized outputs in a session directory", {
|
|
29047
|
+
path: exports_external.string().describe("Session directory path (must be within current working directory)"),
|
|
29048
|
+
models: exports_external.array(exports_external.string()).describe("Model IDs to run (e.g., ['minimax-m2.5', 'kimi-k2.5'])"),
|
|
29049
|
+
input: exports_external.string().optional().describe("Task prompt text (or place input.md in the session directory before calling)"),
|
|
29050
|
+
timeout: exports_external.number().optional().describe("Per-model timeout in seconds (default: 300)")
|
|
29051
|
+
}, async ({ path, models, input, timeout }) => {
|
|
29052
|
+
try {
|
|
29053
|
+
const resolved = validateSessionPath(path);
|
|
29054
|
+
setupSession(resolved, models, input);
|
|
29055
|
+
const status = await runModels(resolved, { timeout });
|
|
29056
|
+
return { content: [{ type: "text", text: JSON.stringify(status, null, 2) }] };
|
|
29057
|
+
} catch (error46) {
|
|
29058
|
+
return {
|
|
29059
|
+
content: [
|
|
29060
|
+
{
|
|
29061
|
+
type: "text",
|
|
29062
|
+
text: `Error: ${error46 instanceof Error ? error46.message : String(error46)}`
|
|
29063
|
+
}
|
|
29064
|
+
],
|
|
29065
|
+
isError: true
|
|
29066
|
+
};
|
|
29067
|
+
}
|
|
29068
|
+
});
|
|
29069
|
+
server.tool("team_judge", "Blind-judge existing anonymized model outputs in a session directory", {
|
|
29070
|
+
path: exports_external.string().describe("Session directory containing response-*.md files (must be within current working directory)"),
|
|
29071
|
+
judges: exports_external.array(exports_external.string()).optional().describe("Model IDs to use as judges (default: same models that produced the responses)")
|
|
29072
|
+
}, async ({ path, judges }) => {
|
|
29073
|
+
try {
|
|
29074
|
+
const resolved = validateSessionPath(path);
|
|
29075
|
+
const verdict = await judgeResponses(resolved, { judges });
|
|
29076
|
+
return { content: [{ type: "text", text: JSON.stringify(verdict, null, 2) }] };
|
|
29077
|
+
} catch (error46) {
|
|
29078
|
+
return {
|
|
29079
|
+
content: [
|
|
29080
|
+
{
|
|
29081
|
+
type: "text",
|
|
29082
|
+
text: `Error: ${error46 instanceof Error ? error46.message : String(error46)}`
|
|
29083
|
+
}
|
|
29084
|
+
],
|
|
29085
|
+
isError: true
|
|
29086
|
+
};
|
|
29087
|
+
}
|
|
29088
|
+
});
|
|
29089
|
+
server.tool("team_run_and_judge", "Run multiple AI models on a task, then blind-judge their outputs \u2014 full pipeline", {
|
|
29090
|
+
path: exports_external.string().describe("Session directory path (must be within current working directory)"),
|
|
29091
|
+
models: exports_external.array(exports_external.string()).describe("Model IDs to run"),
|
|
29092
|
+
judges: exports_external.array(exports_external.string()).optional().describe("Model IDs to use as judges (default: same as runners)"),
|
|
29093
|
+
input: exports_external.string().optional().describe("Task prompt text"),
|
|
29094
|
+
timeout: exports_external.number().optional().describe("Per-model timeout in seconds (default: 300)")
|
|
29095
|
+
}, async ({ path, models, judges, input, timeout }) => {
|
|
29096
|
+
try {
|
|
29097
|
+
const resolved = validateSessionPath(path);
|
|
29098
|
+
setupSession(resolved, models, input);
|
|
29099
|
+
await runModels(resolved, { timeout });
|
|
29100
|
+
const verdict = await judgeResponses(resolved, { judges });
|
|
29101
|
+
return { content: [{ type: "text", text: JSON.stringify(verdict, null, 2) }] };
|
|
29102
|
+
} catch (error46) {
|
|
29103
|
+
return {
|
|
29104
|
+
content: [
|
|
29105
|
+
{
|
|
29106
|
+
type: "text",
|
|
29107
|
+
text: `Error: ${error46 instanceof Error ? error46.message : String(error46)}`
|
|
29108
|
+
}
|
|
29109
|
+
],
|
|
29110
|
+
isError: true
|
|
29111
|
+
};
|
|
29112
|
+
}
|
|
29113
|
+
});
|
|
29114
|
+
server.tool("team_status", "Check the execution status of a team orchestrator session", {
|
|
29115
|
+
path: exports_external.string().describe("Session directory path (must be within current working directory)")
|
|
29116
|
+
}, async ({ path }) => {
|
|
29117
|
+
try {
|
|
29118
|
+
const resolved = validateSessionPath(path);
|
|
29119
|
+
const status = getStatus(resolved);
|
|
29120
|
+
return { content: [{ type: "text", text: JSON.stringify(status, null, 2) }] };
|
|
29121
|
+
} catch (error46) {
|
|
29122
|
+
return {
|
|
29123
|
+
content: [
|
|
29124
|
+
{
|
|
29125
|
+
type: "text",
|
|
29126
|
+
text: `Error: ${error46 instanceof Error ? error46.message : String(error46)}`
|
|
29127
|
+
}
|
|
29128
|
+
],
|
|
29129
|
+
isError: true
|
|
29130
|
+
};
|
|
29131
|
+
}
|
|
29132
|
+
});
|
|
28685
29133
|
const transport = new StdioServerTransport;
|
|
28686
29134
|
await server.connect(transport);
|
|
28687
29135
|
console.error("[claudish] MCP server started");
|
|
@@ -28697,21 +29145,24 @@ var init_mcp_server = __esm(() => {
|
|
|
28697
29145
|
init_mcp();
|
|
28698
29146
|
init_stdio2();
|
|
28699
29147
|
init_zod();
|
|
29148
|
+
init_team_orchestrator();
|
|
28700
29149
|
import_dotenv = __toESM(require_main(), 1);
|
|
28701
29150
|
import_dotenv.config();
|
|
28702
29151
|
__filename2 = fileURLToPath(import.meta.url);
|
|
28703
29152
|
__dirname2 = dirname(__filename2);
|
|
28704
|
-
RECOMMENDED_MODELS_PATH =
|
|
28705
|
-
CLAUDISH_CACHE_DIR =
|
|
28706
|
-
ALL_MODELS_CACHE_PATH =
|
|
29153
|
+
RECOMMENDED_MODELS_PATH = join2(__dirname2, "../recommended-models.json");
|
|
29154
|
+
CLAUDISH_CACHE_DIR = join2(homedir(), ".claudish");
|
|
29155
|
+
ALL_MODELS_CACHE_PATH = join2(CLAUDISH_CACHE_DIR, "all-models.json");
|
|
28707
29156
|
});
|
|
28708
29157
|
|
|
28709
29158
|
// src/logger.ts
|
|
28710
29159
|
var exports_logger = {};
|
|
28711
29160
|
__export(exports_logger, {
|
|
28712
29161
|
truncateContent: () => truncateContent,
|
|
29162
|
+
structuralRedact: () => structuralRedact,
|
|
28713
29163
|
setStderrQuiet: () => setStderrQuiet,
|
|
28714
29164
|
setLogLevel: () => setLogLevel,
|
|
29165
|
+
setDiagOutput: () => setDiagOutput,
|
|
28715
29166
|
maskCredential: () => maskCredential,
|
|
28716
29167
|
logStructured: () => logStructured,
|
|
28717
29168
|
logStderr: () => logStderr,
|
|
@@ -28719,10 +29170,12 @@ __export(exports_logger, {
|
|
|
28719
29170
|
isLoggingEnabled: () => isLoggingEnabled,
|
|
28720
29171
|
initLogger: () => initLogger,
|
|
28721
29172
|
getLogLevel: () => getLogLevel,
|
|
28722
|
-
getLogFilePath: () => getLogFilePath
|
|
29173
|
+
getLogFilePath: () => getLogFilePath,
|
|
29174
|
+
getAlwaysOnLogPath: () => getAlwaysOnLogPath
|
|
28723
29175
|
});
|
|
28724
|
-
import { writeFileSync as
|
|
28725
|
-
import { join as
|
|
29176
|
+
import { writeFileSync as writeFileSync3, appendFile, existsSync as existsSync3, mkdirSync as mkdirSync3, readdirSync as readdirSync2, unlinkSync } from "fs";
|
|
29177
|
+
import { join as join3 } from "path";
|
|
29178
|
+
import { homedir as homedir2 } from "os";
|
|
28726
29179
|
function flushLogBuffer() {
|
|
28727
29180
|
if (!logFilePath || logBuffer.length === 0)
|
|
28728
29181
|
return;
|
|
@@ -28734,11 +29187,19 @@ function flushLogBuffer() {
|
|
|
28734
29187
|
}
|
|
28735
29188
|
});
|
|
28736
29189
|
}
|
|
29190
|
+
function flushAlwaysOnBuffer() {
|
|
29191
|
+
if (!alwaysOnLogPath || alwaysOnBuffer.length === 0)
|
|
29192
|
+
return;
|
|
29193
|
+
const toWrite = alwaysOnBuffer.join("");
|
|
29194
|
+
alwaysOnBuffer = [];
|
|
29195
|
+
appendFile(alwaysOnLogPath, toWrite, () => {});
|
|
29196
|
+
}
|
|
28737
29197
|
function scheduleFlush() {
|
|
28738
29198
|
if (flushTimer)
|
|
28739
29199
|
return;
|
|
28740
29200
|
flushTimer = setInterval(() => {
|
|
28741
29201
|
flushLogBuffer();
|
|
29202
|
+
flushAlwaysOnBuffer();
|
|
28742
29203
|
}, FLUSH_INTERVAL_MS);
|
|
28743
29204
|
process.on("exit", () => {
|
|
28744
29205
|
if (flushTimer) {
|
|
@@ -28746,33 +29207,106 @@ function scheduleFlush() {
|
|
|
28746
29207
|
flushTimer = null;
|
|
28747
29208
|
}
|
|
28748
29209
|
if (logFilePath && logBuffer.length > 0) {
|
|
28749
|
-
|
|
29210
|
+
writeFileSync3(logFilePath, logBuffer.join(""), { flag: "a" });
|
|
28750
29211
|
logBuffer = [];
|
|
28751
29212
|
}
|
|
29213
|
+
if (alwaysOnLogPath && alwaysOnBuffer.length > 0) {
|
|
29214
|
+
writeFileSync3(alwaysOnLogPath, alwaysOnBuffer.join(""), { flag: "a" });
|
|
29215
|
+
alwaysOnBuffer = [];
|
|
29216
|
+
}
|
|
28752
29217
|
});
|
|
28753
29218
|
}
|
|
28754
|
-
function
|
|
28755
|
-
|
|
28756
|
-
|
|
28757
|
-
|
|
28758
|
-
|
|
28759
|
-
|
|
29219
|
+
function rotateOldLogs(dir, keep) {
|
|
29220
|
+
try {
|
|
29221
|
+
const files = readdirSync2(dir).filter((f) => f.startsWith("claudish_") && f.endsWith(".log")).sort().reverse();
|
|
29222
|
+
for (const file2 of files.slice(keep)) {
|
|
29223
|
+
try {
|
|
29224
|
+
unlinkSync(join3(dir, file2));
|
|
29225
|
+
} catch {}
|
|
28760
29226
|
}
|
|
28761
|
-
|
|
29227
|
+
} catch {}
|
|
29228
|
+
}
|
|
29229
|
+
function structuralRedact(jsonStr) {
|
|
29230
|
+
try {
|
|
29231
|
+
const obj = JSON.parse(jsonStr);
|
|
29232
|
+
return JSON.stringify(redactDeep(obj));
|
|
29233
|
+
} catch {
|
|
29234
|
+
return jsonStr.replace(/"[^"]{20,}"/g, (m) => `"<${m.length - 2} chars>"`);
|
|
28762
29235
|
}
|
|
28763
|
-
|
|
28764
|
-
|
|
28765
|
-
if (
|
|
28766
|
-
|
|
29236
|
+
}
|
|
29237
|
+
function redactDeep(val, key) {
|
|
29238
|
+
if (val === null || val === undefined)
|
|
29239
|
+
return val;
|
|
29240
|
+
if (typeof val === "boolean" || typeof val === "number")
|
|
29241
|
+
return val;
|
|
29242
|
+
if (typeof val === "string") {
|
|
29243
|
+
if (key && CONTENT_KEYS.has(key)) {
|
|
29244
|
+
return `<${val.length} chars>`;
|
|
29245
|
+
}
|
|
29246
|
+
return val.length <= 20 ? val : `<${val.length} chars>`;
|
|
29247
|
+
}
|
|
29248
|
+
if (Array.isArray(val))
|
|
29249
|
+
return val.map((v) => redactDeep(v));
|
|
29250
|
+
if (typeof val === "object") {
|
|
29251
|
+
const result = {};
|
|
29252
|
+
for (const [k, v] of Object.entries(val)) {
|
|
29253
|
+
result[k] = redactDeep(v, k);
|
|
29254
|
+
}
|
|
29255
|
+
return result;
|
|
29256
|
+
}
|
|
29257
|
+
return val;
|
|
29258
|
+
}
|
|
29259
|
+
function isStructuralLogWorthy(msg) {
|
|
29260
|
+
return msg.startsWith("[SSE:") || msg.startsWith("[Proxy]") || msg.startsWith("[Fallback]") || msg.startsWith("[Streaming] ===") || msg.startsWith("[Streaming] Chunk:") || msg.startsWith("[Streaming] Received") || msg.startsWith("[Streaming] Text-based tool calls") || msg.startsWith("[Streaming] Final usage") || msg.startsWith("[Streaming] Sending") || msg.startsWith("[AnthropicSSE] Stream complete") || msg.startsWith("[AnthropicSSE] Tool use:") || msg.includes("Response status:") || msg.includes("Error") || msg.includes("error") || msg.includes("[Auto-route]");
|
|
29261
|
+
}
|
|
29262
|
+
function redactLogLine(message, timestamp) {
|
|
29263
|
+
if (message.startsWith("[SSE:")) {
|
|
29264
|
+
const prefixEnd = message.indexOf("] ") + 2;
|
|
29265
|
+
const prefix = message.substring(0, prefixEnd);
|
|
29266
|
+
const payload = message.substring(prefixEnd);
|
|
29267
|
+
return `[${timestamp}] ${prefix}${structuralRedact(payload)}
|
|
29268
|
+
`;
|
|
28767
29269
|
}
|
|
28768
|
-
|
|
28769
|
-
|
|
28770
|
-
|
|
29270
|
+
return `[${timestamp}] ${message}
|
|
29271
|
+
`;
|
|
29272
|
+
}
|
|
29273
|
+
function initLogger(debugMode, level = "info", noLogs = false) {
|
|
29274
|
+
if (!noLogs) {
|
|
29275
|
+
const logsDir = join3(homedir2(), ".claudish", "logs");
|
|
29276
|
+
if (!existsSync3(logsDir)) {
|
|
29277
|
+
mkdirSync3(logsDir, { recursive: true });
|
|
29278
|
+
}
|
|
29279
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-").split("T").join("_").slice(0, -5);
|
|
29280
|
+
alwaysOnLogPath = join3(logsDir, `claudish_${timestamp}.log`);
|
|
29281
|
+
writeFileSync3(alwaysOnLogPath, `Claudish Session Log - ${new Date().toISOString()}
|
|
29282
|
+
Mode: structural (content redacted)
|
|
29283
|
+
${"=".repeat(60)}
|
|
29284
|
+
|
|
29285
|
+
`);
|
|
29286
|
+
rotateOldLogs(logsDir, 20);
|
|
29287
|
+
scheduleFlush();
|
|
29288
|
+
}
|
|
29289
|
+
if (debugMode) {
|
|
29290
|
+
logLevel = level;
|
|
29291
|
+
const logsDir = join3(process.cwd(), "logs");
|
|
29292
|
+
if (!existsSync3(logsDir)) {
|
|
29293
|
+
mkdirSync3(logsDir, { recursive: true });
|
|
29294
|
+
}
|
|
29295
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-").split("T").join("_").slice(0, -5);
|
|
29296
|
+
logFilePath = join3(logsDir, `claudish_${timestamp}.log`);
|
|
29297
|
+
writeFileSync3(logFilePath, `Claudish Debug Log - ${new Date().toISOString()}
|
|
28771
29298
|
Log Level: ${level}
|
|
28772
29299
|
${"=".repeat(80)}
|
|
28773
29300
|
|
|
28774
29301
|
`);
|
|
28775
|
-
|
|
29302
|
+
scheduleFlush();
|
|
29303
|
+
} else {
|
|
29304
|
+
logFilePath = null;
|
|
29305
|
+
if (noLogs && flushTimer) {
|
|
29306
|
+
clearInterval(flushTimer);
|
|
29307
|
+
flushTimer = null;
|
|
29308
|
+
}
|
|
29309
|
+
}
|
|
28776
29310
|
}
|
|
28777
29311
|
function log(message, forceConsole = false) {
|
|
28778
29312
|
const timestamp = new Date().toISOString();
|
|
@@ -28784,25 +29318,40 @@ function log(message, forceConsole = false) {
|
|
|
28784
29318
|
flushLogBuffer();
|
|
28785
29319
|
}
|
|
28786
29320
|
}
|
|
29321
|
+
if (alwaysOnLogPath && isStructuralLogWorthy(message)) {
|
|
29322
|
+
const redactedLine = redactLogLine(message, timestamp);
|
|
29323
|
+
alwaysOnBuffer.push(redactedLine);
|
|
29324
|
+
if (alwaysOnBuffer.length >= MAX_BUFFER_SIZE) {
|
|
29325
|
+
flushAlwaysOnBuffer();
|
|
29326
|
+
}
|
|
29327
|
+
}
|
|
28787
29328
|
if (forceConsole) {
|
|
28788
29329
|
console.log(message);
|
|
28789
29330
|
}
|
|
28790
29331
|
}
|
|
28791
29332
|
function logStderr(message) {
|
|
28792
|
-
if (
|
|
29333
|
+
if (diagOutput) {
|
|
29334
|
+
diagOutput.write(message);
|
|
29335
|
+
} else if (!stderrQuiet) {
|
|
28793
29336
|
process.stderr.write(`[claudish] ${message}
|
|
28794
29337
|
`);
|
|
28795
29338
|
}
|
|
28796
29339
|
log(message);
|
|
28797
29340
|
}
|
|
29341
|
+
function setDiagOutput(output) {
|
|
29342
|
+
diagOutput = output;
|
|
29343
|
+
}
|
|
28798
29344
|
function setStderrQuiet(quiet) {
|
|
28799
29345
|
stderrQuiet = quiet;
|
|
28800
29346
|
}
|
|
28801
29347
|
function getLogFilePath() {
|
|
28802
29348
|
return logFilePath;
|
|
28803
29349
|
}
|
|
29350
|
+
function getAlwaysOnLogPath() {
|
|
29351
|
+
return alwaysOnLogPath;
|
|
29352
|
+
}
|
|
28804
29353
|
function isLoggingEnabled() {
|
|
28805
|
-
return logFilePath !== null;
|
|
29354
|
+
return logFilePath !== null || alwaysOnLogPath !== null;
|
|
28806
29355
|
}
|
|
28807
29356
|
function maskCredential(credential) {
|
|
28808
29357
|
if (!credential || credential.length <= 8) {
|
|
@@ -28849,9 +29398,19 @@ function logStructured(label, data) {
|
|
|
28849
29398
|
}
|
|
28850
29399
|
log(`[${label}] ${JSON.stringify(data, null, 2)}`);
|
|
28851
29400
|
}
|
|
28852
|
-
var logFilePath = null, logLevel = "info", stderrQuiet = false, logBuffer, flushTimer = null, FLUSH_INTERVAL_MS = 100, MAX_BUFFER_SIZE = 50;
|
|
29401
|
+
var logFilePath = null, logLevel = "info", stderrQuiet = false, diagOutput = null, logBuffer, flushTimer = null, FLUSH_INTERVAL_MS = 100, MAX_BUFFER_SIZE = 50, alwaysOnLogPath = null, alwaysOnBuffer, CONTENT_KEYS;
|
|
28853
29402
|
var init_logger = __esm(() => {
|
|
28854
29403
|
logBuffer = [];
|
|
29404
|
+
alwaysOnBuffer = [];
|
|
29405
|
+
CONTENT_KEYS = new Set([
|
|
29406
|
+
"content",
|
|
29407
|
+
"reasoning_content",
|
|
29408
|
+
"text",
|
|
29409
|
+
"thinking",
|
|
29410
|
+
"partial_json",
|
|
29411
|
+
"arguments",
|
|
29412
|
+
"input"
|
|
29413
|
+
]);
|
|
28855
29414
|
});
|
|
28856
29415
|
|
|
28857
29416
|
// src/auth/gemini-oauth.ts
|
|
@@ -28864,9 +29423,9 @@ __export(exports_gemini_oauth, {
|
|
|
28864
29423
|
});
|
|
28865
29424
|
import { createServer } from "http";
|
|
28866
29425
|
import { randomBytes, createHash } from "crypto";
|
|
28867
|
-
import { readFileSync as
|
|
28868
|
-
import { homedir as
|
|
28869
|
-
import { join as
|
|
29426
|
+
import { readFileSync as readFileSync3, existsSync as existsSync4, unlinkSync as unlinkSync2, openSync, writeSync, closeSync } from "fs";
|
|
29427
|
+
import { homedir as homedir3 } from "os";
|
|
29428
|
+
import { join as join4 } from "path";
|
|
28870
29429
|
import { exec } from "child_process";
|
|
28871
29430
|
import { promisify } from "util";
|
|
28872
29431
|
|
|
@@ -28889,8 +29448,8 @@ class GeminiOAuth {
|
|
|
28889
29448
|
return this.credentials !== null && !!this.credentials.refresh_token;
|
|
28890
29449
|
}
|
|
28891
29450
|
getCredentialsPath() {
|
|
28892
|
-
const claudishDir =
|
|
28893
|
-
return
|
|
29451
|
+
const claudishDir = join4(homedir3(), ".claudish");
|
|
29452
|
+
return join4(claudishDir, "gemini-oauth.json");
|
|
28894
29453
|
}
|
|
28895
29454
|
async login() {
|
|
28896
29455
|
log("[GeminiOAuth] Starting OAuth login flow");
|
|
@@ -28911,8 +29470,8 @@ class GeminiOAuth {
|
|
|
28911
29470
|
}
|
|
28912
29471
|
async logout() {
|
|
28913
29472
|
const credPath = this.getCredentialsPath();
|
|
28914
|
-
if (
|
|
28915
|
-
|
|
29473
|
+
if (existsSync4(credPath)) {
|
|
29474
|
+
unlinkSync2(credPath);
|
|
28916
29475
|
log("[GeminiOAuth] Credentials deleted");
|
|
28917
29476
|
}
|
|
28918
29477
|
this.credentials = null;
|
|
@@ -28988,11 +29547,11 @@ Details: ${e.message}`);
|
|
|
28988
29547
|
}
|
|
28989
29548
|
loadCredentials() {
|
|
28990
29549
|
const credPath = this.getCredentialsPath();
|
|
28991
|
-
if (!
|
|
29550
|
+
if (!existsSync4(credPath)) {
|
|
28992
29551
|
return null;
|
|
28993
29552
|
}
|
|
28994
29553
|
try {
|
|
28995
|
-
const data =
|
|
29554
|
+
const data = readFileSync3(credPath, "utf-8");
|
|
28996
29555
|
const credentials = JSON.parse(data);
|
|
28997
29556
|
if (!credentials.access_token || !credentials.refresh_token || !credentials.expires_at) {
|
|
28998
29557
|
log("[GeminiOAuth] Invalid credentials file structure");
|
|
@@ -29007,10 +29566,10 @@ Details: ${e.message}`);
|
|
|
29007
29566
|
}
|
|
29008
29567
|
saveCredentials(credentials) {
|
|
29009
29568
|
const credPath = this.getCredentialsPath();
|
|
29010
|
-
const claudishDir =
|
|
29011
|
-
if (!
|
|
29012
|
-
const { mkdirSync:
|
|
29013
|
-
|
|
29569
|
+
const claudishDir = join4(homedir3(), ".claudish");
|
|
29570
|
+
if (!existsSync4(claudishDir)) {
|
|
29571
|
+
const { mkdirSync: mkdirSync4 } = __require("fs");
|
|
29572
|
+
mkdirSync4(claudishDir, { recursive: true });
|
|
29014
29573
|
}
|
|
29015
29574
|
const fd = openSync(credPath, "w", 384);
|
|
29016
29575
|
try {
|
|
@@ -29043,7 +29602,7 @@ Details: ${e.message}`);
|
|
|
29043
29602
|
return `${OAUTH_CONFIG.authUrl}?${params.toString()}`;
|
|
29044
29603
|
}
|
|
29045
29604
|
async startCallbackServer(codeChallenge, state) {
|
|
29046
|
-
return new Promise((
|
|
29605
|
+
return new Promise((resolve2, reject) => {
|
|
29047
29606
|
let redirectUri = "";
|
|
29048
29607
|
const server = createServer((req, res) => {
|
|
29049
29608
|
const url2 = new URL(req.url, redirectUri.replace("/callback", ""));
|
|
@@ -29106,7 +29665,7 @@ Details: ${e.message}`);
|
|
|
29106
29665
|
</html>
|
|
29107
29666
|
`);
|
|
29108
29667
|
server.close();
|
|
29109
|
-
|
|
29668
|
+
resolve2({ authCode: code, redirectUri });
|
|
29110
29669
|
} else {
|
|
29111
29670
|
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
29112
29671
|
res.end("Not found");
|
|
@@ -29322,9 +29881,9 @@ __export(exports_kimi_oauth, {
|
|
|
29322
29881
|
KimiOAuth: () => KimiOAuth
|
|
29323
29882
|
});
|
|
29324
29883
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
29325
|
-
import { readFileSync as
|
|
29326
|
-
import { homedir as
|
|
29327
|
-
import { join as
|
|
29884
|
+
import { readFileSync as readFileSync4, existsSync as existsSync5, unlinkSync as unlinkSync3, openSync as openSync2, writeSync as writeSync2, closeSync as closeSync2 } from "fs";
|
|
29885
|
+
import { homedir as homedir4, hostname as hostname3, platform, release } from "os";
|
|
29886
|
+
import { join as join5 } from "path";
|
|
29328
29887
|
import { exec as exec2 } from "child_process";
|
|
29329
29888
|
import { promisify as promisify2 } from "util";
|
|
29330
29889
|
|
|
@@ -29349,23 +29908,23 @@ class KimiOAuth {
|
|
|
29349
29908
|
return this.credentials !== null && !!this.credentials.refresh_token;
|
|
29350
29909
|
}
|
|
29351
29910
|
getCredentialsPath() {
|
|
29352
|
-
const claudishDir =
|
|
29353
|
-
return
|
|
29911
|
+
const claudishDir = join5(homedir4(), ".claudish");
|
|
29912
|
+
return join5(claudishDir, "kimi-oauth.json");
|
|
29354
29913
|
}
|
|
29355
29914
|
getDeviceIdPath() {
|
|
29356
|
-
const claudishDir =
|
|
29357
|
-
return
|
|
29915
|
+
const claudishDir = join5(homedir4(), ".claudish");
|
|
29916
|
+
return join5(claudishDir, "kimi-device-id");
|
|
29358
29917
|
}
|
|
29359
29918
|
loadOrCreateDeviceId() {
|
|
29360
29919
|
const deviceIdPath = this.getDeviceIdPath();
|
|
29361
|
-
const claudishDir =
|
|
29362
|
-
if (!
|
|
29363
|
-
const { mkdirSync:
|
|
29364
|
-
|
|
29920
|
+
const claudishDir = join5(homedir4(), ".claudish");
|
|
29921
|
+
if (!existsSync5(claudishDir)) {
|
|
29922
|
+
const { mkdirSync: mkdirSync4 } = __require("fs");
|
|
29923
|
+
mkdirSync4(claudishDir, { recursive: true });
|
|
29365
29924
|
}
|
|
29366
|
-
if (
|
|
29925
|
+
if (existsSync5(deviceIdPath)) {
|
|
29367
29926
|
try {
|
|
29368
|
-
const deviceId2 =
|
|
29927
|
+
const deviceId2 = readFileSync4(deviceIdPath, "utf-8").trim();
|
|
29369
29928
|
if (deviceId2) {
|
|
29370
29929
|
return deviceId2;
|
|
29371
29930
|
}
|
|
@@ -29389,7 +29948,7 @@ class KimiOAuth {
|
|
|
29389
29948
|
}
|
|
29390
29949
|
getVersion() {
|
|
29391
29950
|
try {
|
|
29392
|
-
const packageJson = JSON.parse(
|
|
29951
|
+
const packageJson = JSON.parse(readFileSync4(join5(__dirname, "../../package.json"), "utf-8"));
|
|
29393
29952
|
return packageJson.version;
|
|
29394
29953
|
} catch {
|
|
29395
29954
|
return "4.0.6";
|
|
@@ -29467,7 +30026,7 @@ Waiting for authorization...`);
|
|
|
29467
30026
|
const timeoutMs = expiresIn * 1000;
|
|
29468
30027
|
let currentInterval = interval * 1000;
|
|
29469
30028
|
while (Date.now() - startTime < timeoutMs) {
|
|
29470
|
-
await new Promise((
|
|
30029
|
+
await new Promise((resolve2) => setTimeout(resolve2, currentInterval));
|
|
29471
30030
|
const result = await this.pollForTokenWithRetry(deviceCode);
|
|
29472
30031
|
if (result.error) {
|
|
29473
30032
|
if (result.error === "authorization_pending") {
|
|
@@ -29517,7 +30076,7 @@ Waiting for authorization...`);
|
|
|
29517
30076
|
} catch (e) {
|
|
29518
30077
|
if (retryCount < maxRetries) {
|
|
29519
30078
|
log(`[KimiOAuth] Network error during polling (attempt ${retryCount + 1}/${maxRetries}), retrying in ${backoffMs}ms...`);
|
|
29520
|
-
await new Promise((
|
|
30079
|
+
await new Promise((resolve2) => setTimeout(resolve2, backoffMs));
|
|
29521
30080
|
return this.pollForTokenWithRetry(deviceCode, retryCount + 1);
|
|
29522
30081
|
}
|
|
29523
30082
|
throw new Error(`Network error during token polling: ${e.message}`);
|
|
@@ -29539,8 +30098,8 @@ Waiting for authorization...`);
|
|
|
29539
30098
|
}
|
|
29540
30099
|
async logout() {
|
|
29541
30100
|
const credPath = this.getCredentialsPath();
|
|
29542
|
-
if (
|
|
29543
|
-
|
|
30101
|
+
if (existsSync5(credPath)) {
|
|
30102
|
+
unlinkSync3(credPath);
|
|
29544
30103
|
log("[KimiOAuth] Credentials deleted");
|
|
29545
30104
|
}
|
|
29546
30105
|
this.credentials = null;
|
|
@@ -29606,8 +30165,8 @@ Waiting for authorization...`);
|
|
|
29606
30165
|
} catch (e) {
|
|
29607
30166
|
log(`[KimiOAuth] Refresh failed: ${e.message}`);
|
|
29608
30167
|
const credPath = this.getCredentialsPath();
|
|
29609
|
-
if (
|
|
29610
|
-
|
|
30168
|
+
if (existsSync5(credPath)) {
|
|
30169
|
+
unlinkSync3(credPath);
|
|
29611
30170
|
}
|
|
29612
30171
|
this.credentials = null;
|
|
29613
30172
|
if (process.env.MOONSHOT_API_KEY || process.env.KIMI_API_KEY) {
|
|
@@ -29623,11 +30182,11 @@ Waiting for authorization...`);
|
|
|
29623
30182
|
}
|
|
29624
30183
|
loadCredentials() {
|
|
29625
30184
|
const credPath = this.getCredentialsPath();
|
|
29626
|
-
if (!
|
|
30185
|
+
if (!existsSync5(credPath)) {
|
|
29627
30186
|
return null;
|
|
29628
30187
|
}
|
|
29629
30188
|
try {
|
|
29630
|
-
const data =
|
|
30189
|
+
const data = readFileSync4(credPath, "utf-8");
|
|
29631
30190
|
const credentials = JSON.parse(data);
|
|
29632
30191
|
if (!credentials.access_token || !credentials.refresh_token || !credentials.expires_at || !credentials.scope || !credentials.token_type) {
|
|
29633
30192
|
log("[KimiOAuth] Invalid credentials file structure");
|
|
@@ -29642,10 +30201,10 @@ Waiting for authorization...`);
|
|
|
29642
30201
|
}
|
|
29643
30202
|
saveCredentials(credentials) {
|
|
29644
30203
|
const credPath = this.getCredentialsPath();
|
|
29645
|
-
const claudishDir =
|
|
29646
|
-
if (!
|
|
29647
|
-
const { mkdirSync:
|
|
29648
|
-
|
|
30204
|
+
const claudishDir = join5(homedir4(), ".claudish");
|
|
30205
|
+
if (!existsSync5(claudishDir)) {
|
|
30206
|
+
const { mkdirSync: mkdirSync4 } = __require("fs");
|
|
30207
|
+
mkdirSync4(claudishDir, { recursive: true });
|
|
29649
30208
|
}
|
|
29650
30209
|
const fd = openSync2(credPath, "w", 384);
|
|
29651
30210
|
try {
|
|
@@ -29666,10 +30225,10 @@ async function getValidKimiAccessToken() {
|
|
|
29666
30225
|
}
|
|
29667
30226
|
function hasKimiOAuthCredentials() {
|
|
29668
30227
|
try {
|
|
29669
|
-
const credPath =
|
|
29670
|
-
if (!
|
|
30228
|
+
const credPath = join5(homedir4(), ".claudish", "kimi-oauth.json");
|
|
30229
|
+
if (!existsSync5(credPath))
|
|
29671
30230
|
return false;
|
|
29672
|
-
const data = JSON.parse(
|
|
30231
|
+
const data = JSON.parse(readFileSync4(credPath, "utf-8"));
|
|
29673
30232
|
const now = Date.now();
|
|
29674
30233
|
const bufferMs = 5 * 60 * 1000;
|
|
29675
30234
|
return !!(data.access_token && data.refresh_token && data.expires_at && data.expires_at > now + bufferMs);
|
|
@@ -29732,24 +30291,24 @@ var init_config = __esm(() => {
|
|
|
29732
30291
|
});
|
|
29733
30292
|
|
|
29734
30293
|
// src/model-loader.ts
|
|
29735
|
-
import { readFileSync as
|
|
29736
|
-
import { join as
|
|
30294
|
+
import { readFileSync as readFileSync5, existsSync as existsSync6, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4 } from "fs";
|
|
30295
|
+
import { join as join6, dirname as dirname2 } from "path";
|
|
29737
30296
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
29738
|
-
import { homedir as
|
|
30297
|
+
import { homedir as homedir5 } from "os";
|
|
29739
30298
|
import { createHash as createHash2 } from "crypto";
|
|
29740
30299
|
function getRecommendedModelsPath() {
|
|
29741
|
-
return
|
|
30300
|
+
return join6(__dirname3, "../recommended-models.json");
|
|
29742
30301
|
}
|
|
29743
30302
|
function loadRecommendedModelsJSON() {
|
|
29744
30303
|
if (_cachedRecommendedModels) {
|
|
29745
30304
|
return _cachedRecommendedModels;
|
|
29746
30305
|
}
|
|
29747
30306
|
const jsonPath = getRecommendedModelsPath();
|
|
29748
|
-
if (!
|
|
30307
|
+
if (!existsSync6(jsonPath)) {
|
|
29749
30308
|
throw new Error(`recommended-models.json not found at ${jsonPath}. ` + `Run 'claudish --update-models' to fetch the latest model list.`);
|
|
29750
30309
|
}
|
|
29751
30310
|
try {
|
|
29752
|
-
const jsonContent =
|
|
30311
|
+
const jsonContent = readFileSync5(jsonPath, "utf-8");
|
|
29753
30312
|
_cachedRecommendedModels = JSON.parse(jsonContent);
|
|
29754
30313
|
return _cachedRecommendedModels;
|
|
29755
30314
|
} catch (error46) {
|
|
@@ -29807,11 +30366,11 @@ async function ensureOpenRouterModelsLoaded() {
|
|
|
29807
30366
|
}
|
|
29808
30367
|
async function fetchLiteLLMModels(baseUrl, apiKey, forceUpdate = false) {
|
|
29809
30368
|
const hash2 = createHash2("sha256").update(baseUrl).digest("hex").substring(0, 16);
|
|
29810
|
-
const cacheDir =
|
|
29811
|
-
const cachePath =
|
|
29812
|
-
if (!forceUpdate &&
|
|
30369
|
+
const cacheDir = join6(homedir5(), ".claudish");
|
|
30370
|
+
const cachePath = join6(cacheDir, `litellm-models-${hash2}.json`);
|
|
30371
|
+
if (!forceUpdate && existsSync6(cachePath)) {
|
|
29813
30372
|
try {
|
|
29814
|
-
const cacheData = JSON.parse(
|
|
30373
|
+
const cacheData = JSON.parse(readFileSync5(cachePath, "utf-8"));
|
|
29815
30374
|
const timestamp = new Date(cacheData.timestamp);
|
|
29816
30375
|
const now = new Date;
|
|
29817
30376
|
const ageInHours = (now.getTime() - timestamp.getTime()) / (1000 * 60 * 60);
|
|
@@ -29830,9 +30389,9 @@ async function fetchLiteLLMModels(baseUrl, apiKey, forceUpdate = false) {
|
|
|
29830
30389
|
});
|
|
29831
30390
|
if (!response.ok) {
|
|
29832
30391
|
console.error(`Failed to fetch LiteLLM models: ${response.status} ${response.statusText}`);
|
|
29833
|
-
if (
|
|
30392
|
+
if (existsSync6(cachePath)) {
|
|
29834
30393
|
try {
|
|
29835
|
-
const cacheData2 = JSON.parse(
|
|
30394
|
+
const cacheData2 = JSON.parse(readFileSync5(cachePath, "utf-8"));
|
|
29836
30395
|
return cacheData2.models;
|
|
29837
30396
|
} catch {
|
|
29838
30397
|
return [];
|
|
@@ -29868,18 +30427,18 @@ async function fetchLiteLLMModels(baseUrl, apiKey, forceUpdate = false) {
|
|
|
29868
30427
|
source: "LiteLLM"
|
|
29869
30428
|
};
|
|
29870
30429
|
});
|
|
29871
|
-
|
|
30430
|
+
mkdirSync4(cacheDir, { recursive: true });
|
|
29872
30431
|
const cacheData = {
|
|
29873
30432
|
timestamp: new Date().toISOString(),
|
|
29874
30433
|
models: transformedModels
|
|
29875
30434
|
};
|
|
29876
|
-
|
|
30435
|
+
writeFileSync4(cachePath, JSON.stringify(cacheData, null, 2), "utf-8");
|
|
29877
30436
|
return transformedModels;
|
|
29878
30437
|
} catch (error46) {
|
|
29879
30438
|
console.error(`Failed to fetch LiteLLM models: ${error46}`);
|
|
29880
|
-
if (
|
|
30439
|
+
if (existsSync6(cachePath)) {
|
|
29881
30440
|
try {
|
|
29882
|
-
const cacheData = JSON.parse(
|
|
30441
|
+
const cacheData = JSON.parse(readFileSync5(cachePath, "utf-8"));
|
|
29883
30442
|
return cacheData.models;
|
|
29884
30443
|
} catch {
|
|
29885
30444
|
return [];
|
|
@@ -29939,21 +30498,21 @@ function fuzzyScore2(text, query) {
|
|
|
29939
30498
|
}
|
|
29940
30499
|
|
|
29941
30500
|
// src/profile-config.ts
|
|
29942
|
-
import { existsSync as
|
|
29943
|
-
import { homedir as
|
|
29944
|
-
import { join as
|
|
30501
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
30502
|
+
import { homedir as homedir6 } from "os";
|
|
30503
|
+
import { join as join7 } from "path";
|
|
29945
30504
|
function ensureConfigDir() {
|
|
29946
|
-
if (!
|
|
29947
|
-
|
|
30505
|
+
if (!existsSync7(CONFIG_DIR)) {
|
|
30506
|
+
mkdirSync5(CONFIG_DIR, { recursive: true });
|
|
29948
30507
|
}
|
|
29949
30508
|
}
|
|
29950
30509
|
function loadConfig() {
|
|
29951
30510
|
ensureConfigDir();
|
|
29952
|
-
if (!
|
|
30511
|
+
if (!existsSync7(CONFIG_FILE)) {
|
|
29953
30512
|
return { ...DEFAULT_CONFIG };
|
|
29954
30513
|
}
|
|
29955
30514
|
try {
|
|
29956
|
-
const content =
|
|
30515
|
+
const content = readFileSync6(CONFIG_FILE, "utf-8");
|
|
29957
30516
|
const config3 = JSON.parse(content);
|
|
29958
30517
|
const merged = {
|
|
29959
30518
|
version: config3.version || DEFAULT_CONFIG.version,
|
|
@@ -29983,31 +30542,31 @@ function loadConfig() {
|
|
|
29983
30542
|
}
|
|
29984
30543
|
function saveConfig(config3) {
|
|
29985
30544
|
ensureConfigDir();
|
|
29986
|
-
|
|
30545
|
+
writeFileSync5(CONFIG_FILE, JSON.stringify(config3, null, 2), "utf-8");
|
|
29987
30546
|
}
|
|
29988
30547
|
function configExists() {
|
|
29989
|
-
return
|
|
30548
|
+
return existsSync7(CONFIG_FILE);
|
|
29990
30549
|
}
|
|
29991
30550
|
function getConfigPath() {
|
|
29992
30551
|
return CONFIG_FILE;
|
|
29993
30552
|
}
|
|
29994
30553
|
function getLocalConfigPath() {
|
|
29995
|
-
return
|
|
30554
|
+
return join7(process.cwd(), LOCAL_CONFIG_FILENAME);
|
|
29996
30555
|
}
|
|
29997
30556
|
function localConfigExists() {
|
|
29998
|
-
return
|
|
30557
|
+
return existsSync7(getLocalConfigPath());
|
|
29999
30558
|
}
|
|
30000
30559
|
function isProjectDirectory() {
|
|
30001
30560
|
const cwd = process.cwd();
|
|
30002
|
-
return [".git", "package.json", "Cargo.toml", "go.mod", "pyproject.toml", ".claudish.json"].some((f) =>
|
|
30561
|
+
return [".git", "package.json", "Cargo.toml", "go.mod", "pyproject.toml", ".claudish.json"].some((f) => existsSync7(join7(cwd, f)));
|
|
30003
30562
|
}
|
|
30004
30563
|
function loadLocalConfig() {
|
|
30005
30564
|
const localPath = getLocalConfigPath();
|
|
30006
|
-
if (!
|
|
30565
|
+
if (!existsSync7(localPath)) {
|
|
30007
30566
|
return null;
|
|
30008
30567
|
}
|
|
30009
30568
|
try {
|
|
30010
|
-
const content =
|
|
30569
|
+
const content = readFileSync6(localPath, "utf-8");
|
|
30011
30570
|
const config3 = JSON.parse(content);
|
|
30012
30571
|
const local = {
|
|
30013
30572
|
version: config3.version || DEFAULT_CONFIG.version,
|
|
@@ -30024,7 +30583,7 @@ function loadLocalConfig() {
|
|
|
30024
30583
|
}
|
|
30025
30584
|
}
|
|
30026
30585
|
function saveLocalConfig(config3) {
|
|
30027
|
-
|
|
30586
|
+
writeFileSync5(getLocalConfigPath(), JSON.stringify(config3, null, 2), "utf-8");
|
|
30028
30587
|
}
|
|
30029
30588
|
function loadConfigForScope(scope) {
|
|
30030
30589
|
if (scope === "local") {
|
|
@@ -30229,8 +30788,8 @@ function removeEndpoint(name) {
|
|
|
30229
30788
|
}
|
|
30230
30789
|
var CONFIG_DIR, CONFIG_FILE, LOCAL_CONFIG_FILENAME = ".claudish.json", DEFAULT_CONFIG;
|
|
30231
30790
|
var init_profile_config = __esm(() => {
|
|
30232
|
-
CONFIG_DIR =
|
|
30233
|
-
CONFIG_FILE =
|
|
30791
|
+
CONFIG_DIR = join7(homedir6(), ".claudish");
|
|
30792
|
+
CONFIG_FILE = join7(CONFIG_DIR, "config.json");
|
|
30234
30793
|
DEFAULT_CONFIG = {
|
|
30235
30794
|
version: "1.0.0",
|
|
30236
30795
|
defaultProfile: "default",
|
|
@@ -30246,6 +30805,554 @@ var init_profile_config = __esm(() => {
|
|
|
30246
30805
|
};
|
|
30247
30806
|
});
|
|
30248
30807
|
|
|
30808
|
+
// src/providers/provider-definitions.ts
|
|
30809
|
+
function ensureProviderByNameCache() {
|
|
30810
|
+
if (!_providerByNameCache) {
|
|
30811
|
+
_providerByNameCache = new Map;
|
|
30812
|
+
for (const def of BUILTIN_PROVIDERS) {
|
|
30813
|
+
_providerByNameCache.set(def.name, def);
|
|
30814
|
+
}
|
|
30815
|
+
}
|
|
30816
|
+
return _providerByNameCache;
|
|
30817
|
+
}
|
|
30818
|
+
function getShortcuts() {
|
|
30819
|
+
if (!_shortcutsCache) {
|
|
30820
|
+
_shortcutsCache = {};
|
|
30821
|
+
for (const def of BUILTIN_PROVIDERS) {
|
|
30822
|
+
for (const shortcut of def.shortcuts) {
|
|
30823
|
+
_shortcutsCache[shortcut] = def.name;
|
|
30824
|
+
}
|
|
30825
|
+
}
|
|
30826
|
+
}
|
|
30827
|
+
return _shortcutsCache;
|
|
30828
|
+
}
|
|
30829
|
+
function getLegacyPrefixPatterns() {
|
|
30830
|
+
if (!_legacyPrefixCache) {
|
|
30831
|
+
_legacyPrefixCache = [];
|
|
30832
|
+
for (const def of BUILTIN_PROVIDERS) {
|
|
30833
|
+
for (const lp of def.legacyPrefixes) {
|
|
30834
|
+
_legacyPrefixCache.push({
|
|
30835
|
+
prefix: lp.prefix,
|
|
30836
|
+
provider: def.name,
|
|
30837
|
+
stripPrefix: lp.stripPrefix
|
|
30838
|
+
});
|
|
30839
|
+
}
|
|
30840
|
+
}
|
|
30841
|
+
}
|
|
30842
|
+
return _legacyPrefixCache;
|
|
30843
|
+
}
|
|
30844
|
+
function getNativeModelPatterns() {
|
|
30845
|
+
if (!_nativeModelPatternsCache) {
|
|
30846
|
+
_nativeModelPatternsCache = [];
|
|
30847
|
+
for (const def of BUILTIN_PROVIDERS) {
|
|
30848
|
+
if (def.nativeModelPatterns) {
|
|
30849
|
+
for (const np of def.nativeModelPatterns) {
|
|
30850
|
+
_nativeModelPatternsCache.push({
|
|
30851
|
+
pattern: np.pattern,
|
|
30852
|
+
provider: def.name
|
|
30853
|
+
});
|
|
30854
|
+
}
|
|
30855
|
+
}
|
|
30856
|
+
}
|
|
30857
|
+
}
|
|
30858
|
+
return _nativeModelPatternsCache;
|
|
30859
|
+
}
|
|
30860
|
+
function getProviderByName(name) {
|
|
30861
|
+
return ensureProviderByNameCache().get(name);
|
|
30862
|
+
}
|
|
30863
|
+
function getApiKeyInfo(providerName) {
|
|
30864
|
+
const def = getProviderByName(providerName);
|
|
30865
|
+
if (!def)
|
|
30866
|
+
return null;
|
|
30867
|
+
return {
|
|
30868
|
+
envVar: def.apiKeyEnvVar,
|
|
30869
|
+
description: def.apiKeyDescription,
|
|
30870
|
+
url: def.apiKeyUrl,
|
|
30871
|
+
aliases: def.apiKeyAliases,
|
|
30872
|
+
oauthFallback: def.oauthFallback
|
|
30873
|
+
};
|
|
30874
|
+
}
|
|
30875
|
+
function getDisplayName(providerName) {
|
|
30876
|
+
const def = getProviderByName(providerName);
|
|
30877
|
+
return def?.displayName || providerName.charAt(0).toUpperCase() + providerName.slice(1);
|
|
30878
|
+
}
|
|
30879
|
+
function getEffectiveBaseUrl(def) {
|
|
30880
|
+
if (def.baseUrlEnvVars) {
|
|
30881
|
+
for (const envVar of def.baseUrlEnvVars) {
|
|
30882
|
+
const value = process.env[envVar];
|
|
30883
|
+
if (value)
|
|
30884
|
+
return value;
|
|
30885
|
+
}
|
|
30886
|
+
}
|
|
30887
|
+
return def.baseUrl;
|
|
30888
|
+
}
|
|
30889
|
+
function isLocalTransport(providerName) {
|
|
30890
|
+
if (!_localProvidersCache) {
|
|
30891
|
+
_localProvidersCache = new Set;
|
|
30892
|
+
for (const def of BUILTIN_PROVIDERS) {
|
|
30893
|
+
if (def.isLocal) {
|
|
30894
|
+
_localProvidersCache.add(def.name);
|
|
30895
|
+
}
|
|
30896
|
+
}
|
|
30897
|
+
}
|
|
30898
|
+
return _localProvidersCache.has(providerName.toLowerCase());
|
|
30899
|
+
}
|
|
30900
|
+
function toRemoteProvider(def) {
|
|
30901
|
+
const baseUrl = getEffectiveBaseUrl(def);
|
|
30902
|
+
let effectiveBaseUrl = baseUrl;
|
|
30903
|
+
if (def.name === "opencode-zen-go" && def.baseUrlEnvVars) {
|
|
30904
|
+
const envOverride = process.env[def.baseUrlEnvVars[0]];
|
|
30905
|
+
if (envOverride) {
|
|
30906
|
+
effectiveBaseUrl = envOverride.replace("/zen", "/zen/go");
|
|
30907
|
+
}
|
|
30908
|
+
}
|
|
30909
|
+
return {
|
|
30910
|
+
name: def.name === "google" ? "gemini" : def.name,
|
|
30911
|
+
baseUrl: effectiveBaseUrl,
|
|
30912
|
+
apiPath: def.apiPath,
|
|
30913
|
+
apiKeyEnvVar: def.apiKeyEnvVar,
|
|
30914
|
+
prefixes: def.legacyPrefixes.map((lp) => lp.prefix),
|
|
30915
|
+
headers: def.headers,
|
|
30916
|
+
authScheme: def.authScheme
|
|
30917
|
+
};
|
|
30918
|
+
}
|
|
30919
|
+
function getAllProviders() {
|
|
30920
|
+
return BUILTIN_PROVIDERS;
|
|
30921
|
+
}
|
|
30922
|
+
function getApiKeyEnvVars(providerName) {
|
|
30923
|
+
const def = getProviderByName(providerName);
|
|
30924
|
+
if (!def)
|
|
30925
|
+
return null;
|
|
30926
|
+
return {
|
|
30927
|
+
envVar: def.apiKeyEnvVar,
|
|
30928
|
+
aliases: def.apiKeyAliases
|
|
30929
|
+
};
|
|
30930
|
+
}
|
|
30931
|
+
var BUILTIN_PROVIDERS, _shortcutsCache = null, _legacyPrefixCache = null, _nativeModelPatternsCache = null, _providerByNameCache = null, _localProvidersCache = null;
|
|
30932
|
+
var init_provider_definitions = __esm(() => {
|
|
30933
|
+
BUILTIN_PROVIDERS = [
|
|
30934
|
+
{
|
|
30935
|
+
name: "google",
|
|
30936
|
+
displayName: "Gemini",
|
|
30937
|
+
transport: "gemini",
|
|
30938
|
+
baseUrl: "https://generativelanguage.googleapis.com",
|
|
30939
|
+
baseUrlEnvVars: ["GEMINI_BASE_URL"],
|
|
30940
|
+
apiPath: "/v1beta/models/{model}:streamGenerateContent?alt=sse",
|
|
30941
|
+
apiKeyEnvVar: "GEMINI_API_KEY",
|
|
30942
|
+
apiKeyDescription: "Google Gemini API Key",
|
|
30943
|
+
apiKeyUrl: "https://aistudio.google.com/app/apikey",
|
|
30944
|
+
shortcuts: ["g", "gemini"],
|
|
30945
|
+
shortestPrefix: "g",
|
|
30946
|
+
legacyPrefixes: [
|
|
30947
|
+
{ prefix: "g/", stripPrefix: true },
|
|
30948
|
+
{ prefix: "gemini/", stripPrefix: true }
|
|
30949
|
+
],
|
|
30950
|
+
nativeModelPatterns: [{ pattern: /^google\//i }, { pattern: /^gemini-/i }],
|
|
30951
|
+
isDirectApi: true
|
|
30952
|
+
},
|
|
30953
|
+
{
|
|
30954
|
+
name: "gemini-codeassist",
|
|
30955
|
+
displayName: "Gemini Code Assist",
|
|
30956
|
+
transport: "gemini-oauth",
|
|
30957
|
+
baseUrl: "https://cloudcode-pa.googleapis.com",
|
|
30958
|
+
apiPath: "/v1internal:streamGenerateContent?alt=sse",
|
|
30959
|
+
apiKeyEnvVar: "",
|
|
30960
|
+
apiKeyDescription: "Gemini Code Assist (OAuth)",
|
|
30961
|
+
apiKeyUrl: "https://cloud.google.com/code-assist",
|
|
30962
|
+
shortcuts: ["go"],
|
|
30963
|
+
shortestPrefix: "go",
|
|
30964
|
+
legacyPrefixes: [{ prefix: "go/", stripPrefix: true }],
|
|
30965
|
+
isDirectApi: true
|
|
30966
|
+
},
|
|
30967
|
+
{
|
|
30968
|
+
name: "openai",
|
|
30969
|
+
displayName: "OpenAI",
|
|
30970
|
+
transport: "openai",
|
|
30971
|
+
tokenStrategy: "delta-aware",
|
|
30972
|
+
baseUrl: "https://api.openai.com",
|
|
30973
|
+
baseUrlEnvVars: ["OPENAI_BASE_URL"],
|
|
30974
|
+
apiPath: "/v1/chat/completions",
|
|
30975
|
+
apiKeyEnvVar: "OPENAI_API_KEY",
|
|
30976
|
+
apiKeyDescription: "OpenAI API Key",
|
|
30977
|
+
apiKeyUrl: "https://platform.openai.com/api-keys",
|
|
30978
|
+
shortcuts: ["oai"],
|
|
30979
|
+
shortestPrefix: "oai",
|
|
30980
|
+
legacyPrefixes: [{ prefix: "oai/", stripPrefix: true }],
|
|
30981
|
+
nativeModelPatterns: [
|
|
30982
|
+
{ pattern: /^openai\//i },
|
|
30983
|
+
{ pattern: /^gpt-/i },
|
|
30984
|
+
{ pattern: /^o1(-|$)/i },
|
|
30985
|
+
{ pattern: /^o3(-|$)/i },
|
|
30986
|
+
{ pattern: /^chatgpt-/i }
|
|
30987
|
+
],
|
|
30988
|
+
isDirectApi: true
|
|
30989
|
+
},
|
|
30990
|
+
{
|
|
30991
|
+
name: "openrouter",
|
|
30992
|
+
displayName: "OpenRouter",
|
|
30993
|
+
transport: "openrouter",
|
|
30994
|
+
baseUrl: "https://openrouter.ai",
|
|
30995
|
+
apiPath: "/api/v1/chat/completions",
|
|
30996
|
+
apiKeyEnvVar: "OPENROUTER_API_KEY",
|
|
30997
|
+
apiKeyDescription: "OpenRouter API Key",
|
|
30998
|
+
apiKeyUrl: "https://openrouter.ai/keys",
|
|
30999
|
+
shortcuts: ["or"],
|
|
31000
|
+
shortestPrefix: "or",
|
|
31001
|
+
legacyPrefixes: [{ prefix: "or/", stripPrefix: true }],
|
|
31002
|
+
nativeModelPatterns: [{ pattern: /^openrouter\//i }],
|
|
31003
|
+
headers: {
|
|
31004
|
+
"HTTP-Referer": "https://claudish.com",
|
|
31005
|
+
"X-Title": "Claudish - OpenRouter Proxy"
|
|
31006
|
+
},
|
|
31007
|
+
isDirectApi: true
|
|
31008
|
+
},
|
|
31009
|
+
{
|
|
31010
|
+
name: "minimax",
|
|
31011
|
+
displayName: "MiniMax",
|
|
31012
|
+
transport: "anthropic",
|
|
31013
|
+
baseUrl: "https://api.minimax.io",
|
|
31014
|
+
baseUrlEnvVars: ["MINIMAX_BASE_URL"],
|
|
31015
|
+
apiPath: "/anthropic/v1/messages",
|
|
31016
|
+
apiKeyEnvVar: "MINIMAX_API_KEY",
|
|
31017
|
+
apiKeyDescription: "MiniMax API Key",
|
|
31018
|
+
apiKeyUrl: "https://www.minimaxi.com/",
|
|
31019
|
+
authScheme: "bearer",
|
|
31020
|
+
shortcuts: ["mm", "mmax"],
|
|
31021
|
+
shortestPrefix: "mm",
|
|
31022
|
+
legacyPrefixes: [
|
|
31023
|
+
{ prefix: "mmax/", stripPrefix: true },
|
|
31024
|
+
{ prefix: "mm/", stripPrefix: true }
|
|
31025
|
+
],
|
|
31026
|
+
nativeModelPatterns: [
|
|
31027
|
+
{ pattern: /^minimax\//i },
|
|
31028
|
+
{ pattern: /^minimax-/i },
|
|
31029
|
+
{ pattern: /^abab-/i }
|
|
31030
|
+
],
|
|
31031
|
+
isDirectApi: true
|
|
31032
|
+
},
|
|
31033
|
+
{
|
|
31034
|
+
name: "minimax-coding",
|
|
31035
|
+
displayName: "MiniMax Coding",
|
|
31036
|
+
transport: "anthropic",
|
|
31037
|
+
baseUrl: "https://api.minimax.io",
|
|
31038
|
+
baseUrlEnvVars: ["MINIMAX_CODING_BASE_URL"],
|
|
31039
|
+
apiPath: "/anthropic/v1/messages",
|
|
31040
|
+
apiKeyEnvVar: "MINIMAX_CODING_API_KEY",
|
|
31041
|
+
apiKeyDescription: "MiniMax Coding Plan API Key",
|
|
31042
|
+
apiKeyUrl: "https://platform.minimax.io/user-center/basic-information/interface-key",
|
|
31043
|
+
authScheme: "bearer",
|
|
31044
|
+
shortcuts: ["mmc"],
|
|
31045
|
+
shortestPrefix: "mmc",
|
|
31046
|
+
legacyPrefixes: [{ prefix: "mmc/", stripPrefix: true }],
|
|
31047
|
+
isDirectApi: true
|
|
31048
|
+
},
|
|
31049
|
+
{
|
|
31050
|
+
name: "kimi-coding",
|
|
31051
|
+
displayName: "Kimi Coding",
|
|
31052
|
+
transport: "kimi-coding",
|
|
31053
|
+
baseUrl: "https://api.kimi.com/coding/v1",
|
|
31054
|
+
apiPath: "/messages",
|
|
31055
|
+
apiKeyEnvVar: "KIMI_CODING_API_KEY",
|
|
31056
|
+
apiKeyDescription: "Kimi Coding API Key",
|
|
31057
|
+
apiKeyUrl: "https://kimi.com/code (get key from membership page, or run: claudish --kimi-login)",
|
|
31058
|
+
oauthFallback: "kimi-oauth.json",
|
|
31059
|
+
shortcuts: ["kc"],
|
|
31060
|
+
shortestPrefix: "kc",
|
|
31061
|
+
legacyPrefixes: [{ prefix: "kc/", stripPrefix: true }],
|
|
31062
|
+
nativeModelPatterns: [{ pattern: /^kimi-for-coding$/i }],
|
|
31063
|
+
isDirectApi: true
|
|
31064
|
+
},
|
|
31065
|
+
{
|
|
31066
|
+
name: "kimi",
|
|
31067
|
+
displayName: "Kimi",
|
|
31068
|
+
transport: "anthropic",
|
|
31069
|
+
baseUrl: "https://api.moonshot.ai",
|
|
31070
|
+
baseUrlEnvVars: ["MOONSHOT_BASE_URL", "KIMI_BASE_URL"],
|
|
31071
|
+
apiPath: "/anthropic/v1/messages",
|
|
31072
|
+
apiKeyEnvVar: "MOONSHOT_API_KEY",
|
|
31073
|
+
apiKeyAliases: ["KIMI_API_KEY"],
|
|
31074
|
+
apiKeyDescription: "Kimi/Moonshot API Key",
|
|
31075
|
+
apiKeyUrl: "https://platform.moonshot.cn/",
|
|
31076
|
+
shortcuts: ["kimi", "moon", "moonshot"],
|
|
31077
|
+
shortestPrefix: "kimi",
|
|
31078
|
+
legacyPrefixes: [
|
|
31079
|
+
{ prefix: "kimi/", stripPrefix: true },
|
|
31080
|
+
{ prefix: "moonshot/", stripPrefix: true }
|
|
31081
|
+
],
|
|
31082
|
+
nativeModelPatterns: [
|
|
31083
|
+
{ pattern: /^moonshot(ai)?\//i },
|
|
31084
|
+
{ pattern: /^moonshot-/i },
|
|
31085
|
+
{ pattern: /^kimi-/i }
|
|
31086
|
+
],
|
|
31087
|
+
isDirectApi: true
|
|
31088
|
+
},
|
|
31089
|
+
{
|
|
31090
|
+
name: "glm",
|
|
31091
|
+
displayName: "GLM",
|
|
31092
|
+
transport: "openai",
|
|
31093
|
+
tokenStrategy: "delta-aware",
|
|
31094
|
+
baseUrl: "https://open.bigmodel.cn",
|
|
31095
|
+
baseUrlEnvVars: ["ZHIPU_BASE_URL", "GLM_BASE_URL"],
|
|
31096
|
+
apiPath: "/api/paas/v4/chat/completions",
|
|
31097
|
+
apiKeyEnvVar: "ZHIPU_API_KEY",
|
|
31098
|
+
apiKeyAliases: ["GLM_API_KEY"],
|
|
31099
|
+
apiKeyDescription: "GLM/Zhipu API Key",
|
|
31100
|
+
apiKeyUrl: "https://open.bigmodel.cn/",
|
|
31101
|
+
shortcuts: ["glm", "zhipu"],
|
|
31102
|
+
shortestPrefix: "glm",
|
|
31103
|
+
legacyPrefixes: [
|
|
31104
|
+
{ prefix: "glm/", stripPrefix: true },
|
|
31105
|
+
{ prefix: "zhipu/", stripPrefix: true }
|
|
31106
|
+
],
|
|
31107
|
+
nativeModelPatterns: [
|
|
31108
|
+
{ pattern: /^zhipu\//i },
|
|
31109
|
+
{ pattern: /^glm-/i },
|
|
31110
|
+
{ pattern: /^chatglm-/i }
|
|
31111
|
+
],
|
|
31112
|
+
isDirectApi: true
|
|
31113
|
+
},
|
|
31114
|
+
{
|
|
31115
|
+
name: "glm-coding",
|
|
31116
|
+
displayName: "GLM Coding",
|
|
31117
|
+
transport: "openai",
|
|
31118
|
+
tokenStrategy: "delta-aware",
|
|
31119
|
+
baseUrl: "https://api.z.ai",
|
|
31120
|
+
apiPath: "/api/coding/paas/v4/chat/completions",
|
|
31121
|
+
apiKeyEnvVar: "GLM_CODING_API_KEY",
|
|
31122
|
+
apiKeyAliases: ["ZAI_CODING_API_KEY"],
|
|
31123
|
+
apiKeyDescription: "GLM Coding Plan API Key",
|
|
31124
|
+
apiKeyUrl: "https://z.ai/subscribe",
|
|
31125
|
+
shortcuts: ["gc"],
|
|
31126
|
+
shortestPrefix: "gc",
|
|
31127
|
+
legacyPrefixes: [{ prefix: "gc/", stripPrefix: true }],
|
|
31128
|
+
isDirectApi: true
|
|
31129
|
+
},
|
|
31130
|
+
{
|
|
31131
|
+
name: "zai",
|
|
31132
|
+
displayName: "Z.AI",
|
|
31133
|
+
transport: "anthropic",
|
|
31134
|
+
baseUrl: "https://api.z.ai",
|
|
31135
|
+
baseUrlEnvVars: ["ZAI_BASE_URL"],
|
|
31136
|
+
apiPath: "/api/anthropic/v1/messages",
|
|
31137
|
+
apiKeyEnvVar: "ZAI_API_KEY",
|
|
31138
|
+
apiKeyDescription: "Z.AI API Key",
|
|
31139
|
+
apiKeyUrl: "https://z.ai/",
|
|
31140
|
+
shortcuts: ["zai"],
|
|
31141
|
+
shortestPrefix: "zai",
|
|
31142
|
+
legacyPrefixes: [{ prefix: "zai/", stripPrefix: true }],
|
|
31143
|
+
nativeModelPatterns: [{ pattern: /^z-ai\//i }, { pattern: /^zai\//i }],
|
|
31144
|
+
isDirectApi: true
|
|
31145
|
+
},
|
|
31146
|
+
{
|
|
31147
|
+
name: "ollamacloud",
|
|
31148
|
+
displayName: "OllamaCloud",
|
|
31149
|
+
transport: "ollamacloud",
|
|
31150
|
+
tokenStrategy: "accumulate-both",
|
|
31151
|
+
baseUrl: "https://ollama.com",
|
|
31152
|
+
baseUrlEnvVars: ["OLLAMACLOUD_BASE_URL"],
|
|
31153
|
+
apiPath: "/api/chat",
|
|
31154
|
+
apiKeyEnvVar: "OLLAMA_API_KEY",
|
|
31155
|
+
apiKeyDescription: "OllamaCloud API Key",
|
|
31156
|
+
apiKeyUrl: "https://ollama.com/account",
|
|
31157
|
+
shortcuts: ["oc", "llama", "lc", "meta"],
|
|
31158
|
+
shortestPrefix: "oc",
|
|
31159
|
+
legacyPrefixes: [{ prefix: "oc/", stripPrefix: true }],
|
|
31160
|
+
nativeModelPatterns: [
|
|
31161
|
+
{ pattern: /^ollamacloud\//i },
|
|
31162
|
+
{ pattern: /^meta-llama\//i },
|
|
31163
|
+
{ pattern: /^llama-/i },
|
|
31164
|
+
{ pattern: /^llama3/i }
|
|
31165
|
+
],
|
|
31166
|
+
isDirectApi: true
|
|
31167
|
+
},
|
|
31168
|
+
{
|
|
31169
|
+
name: "opencode-zen",
|
|
31170
|
+
displayName: "OpenCode Zen",
|
|
31171
|
+
transport: "openai",
|
|
31172
|
+
tokenStrategy: "delta-aware",
|
|
31173
|
+
baseUrl: "https://opencode.ai/zen",
|
|
31174
|
+
baseUrlEnvVars: ["OPENCODE_BASE_URL"],
|
|
31175
|
+
apiPath: "/v1/chat/completions",
|
|
31176
|
+
apiKeyEnvVar: "OPENCODE_API_KEY",
|
|
31177
|
+
apiKeyDescription: "OpenCode Zen (Free)",
|
|
31178
|
+
apiKeyUrl: "https://opencode.ai/",
|
|
31179
|
+
publicKeyFallback: "public",
|
|
31180
|
+
shortcuts: ["zen"],
|
|
31181
|
+
shortestPrefix: "zen",
|
|
31182
|
+
legacyPrefixes: [{ prefix: "zen/", stripPrefix: true }],
|
|
31183
|
+
isDirectApi: true
|
|
31184
|
+
},
|
|
31185
|
+
{
|
|
31186
|
+
name: "opencode-zen-go",
|
|
31187
|
+
displayName: "OpenCode Zen Go",
|
|
31188
|
+
transport: "openai",
|
|
31189
|
+
tokenStrategy: "delta-aware",
|
|
31190
|
+
baseUrl: "https://opencode.ai/zen/go",
|
|
31191
|
+
baseUrlEnvVars: ["OPENCODE_BASE_URL"],
|
|
31192
|
+
apiPath: "/v1/chat/completions",
|
|
31193
|
+
apiKeyEnvVar: "OPENCODE_API_KEY",
|
|
31194
|
+
apiKeyDescription: "OpenCode Zen Go (Lite Plan)",
|
|
31195
|
+
apiKeyUrl: "https://opencode.ai/",
|
|
31196
|
+
shortcuts: ["zengo", "zgo"],
|
|
31197
|
+
shortestPrefix: "zengo",
|
|
31198
|
+
legacyPrefixes: [
|
|
31199
|
+
{ prefix: "zengo/", stripPrefix: true },
|
|
31200
|
+
{ prefix: "zgo/", stripPrefix: true }
|
|
31201
|
+
],
|
|
31202
|
+
isDirectApi: true
|
|
31203
|
+
},
|
|
31204
|
+
{
|
|
31205
|
+
name: "vertex",
|
|
31206
|
+
displayName: "Vertex AI",
|
|
31207
|
+
transport: "vertex",
|
|
31208
|
+
baseUrl: "",
|
|
31209
|
+
apiPath: "",
|
|
31210
|
+
apiKeyEnvVar: "VERTEX_PROJECT",
|
|
31211
|
+
apiKeyAliases: ["VERTEX_API_KEY"],
|
|
31212
|
+
apiKeyDescription: "Vertex AI API Key",
|
|
31213
|
+
apiKeyUrl: "https://console.cloud.google.com/vertex-ai",
|
|
31214
|
+
shortcuts: ["v", "vertex"],
|
|
31215
|
+
shortestPrefix: "v",
|
|
31216
|
+
legacyPrefixes: [
|
|
31217
|
+
{ prefix: "v/", stripPrefix: true },
|
|
31218
|
+
{ prefix: "vertex/", stripPrefix: true }
|
|
31219
|
+
],
|
|
31220
|
+
isDirectApi: true
|
|
31221
|
+
},
|
|
31222
|
+
{
|
|
31223
|
+
name: "litellm",
|
|
31224
|
+
displayName: "LiteLLM",
|
|
31225
|
+
transport: "litellm",
|
|
31226
|
+
baseUrl: "",
|
|
31227
|
+
baseUrlEnvVars: ["LITELLM_BASE_URL"],
|
|
31228
|
+
apiPath: "/v1/chat/completions",
|
|
31229
|
+
apiKeyEnvVar: "LITELLM_API_KEY",
|
|
31230
|
+
apiKeyDescription: "LiteLLM API Key",
|
|
31231
|
+
apiKeyUrl: "https://docs.litellm.ai/",
|
|
31232
|
+
shortcuts: ["litellm", "ll"],
|
|
31233
|
+
shortestPrefix: "ll",
|
|
31234
|
+
legacyPrefixes: [
|
|
31235
|
+
{ prefix: "litellm/", stripPrefix: true },
|
|
31236
|
+
{ prefix: "ll/", stripPrefix: true }
|
|
31237
|
+
],
|
|
31238
|
+
isDirectApi: true
|
|
31239
|
+
},
|
|
31240
|
+
{
|
|
31241
|
+
name: "poe",
|
|
31242
|
+
displayName: "Poe",
|
|
31243
|
+
transport: "poe",
|
|
31244
|
+
baseUrl: "https://api.poe.com",
|
|
31245
|
+
apiPath: "/v1/chat/completions",
|
|
31246
|
+
apiKeyEnvVar: "POE_API_KEY",
|
|
31247
|
+
apiKeyDescription: "Poe API Key",
|
|
31248
|
+
apiKeyUrl: "https://poe.com/api_key",
|
|
31249
|
+
shortcuts: ["poe"],
|
|
31250
|
+
shortestPrefix: "poe",
|
|
31251
|
+
legacyPrefixes: [],
|
|
31252
|
+
nativeModelPatterns: [{ pattern: /^poe:/i }],
|
|
31253
|
+
isDirectApi: true
|
|
31254
|
+
},
|
|
31255
|
+
{
|
|
31256
|
+
name: "ollama",
|
|
31257
|
+
displayName: "Ollama",
|
|
31258
|
+
transport: "local",
|
|
31259
|
+
baseUrl: "http://localhost:11434",
|
|
31260
|
+
apiPath: "/api/chat",
|
|
31261
|
+
apiKeyEnvVar: "",
|
|
31262
|
+
apiKeyDescription: "Ollama (Local)",
|
|
31263
|
+
apiKeyUrl: "",
|
|
31264
|
+
shortcuts: ["ollama"],
|
|
31265
|
+
shortestPrefix: "ollama",
|
|
31266
|
+
legacyPrefixes: [
|
|
31267
|
+
{ prefix: "ollama/", stripPrefix: true },
|
|
31268
|
+
{ prefix: "ollama:", stripPrefix: true }
|
|
31269
|
+
],
|
|
31270
|
+
isLocal: true
|
|
31271
|
+
},
|
|
31272
|
+
{
|
|
31273
|
+
name: "lmstudio",
|
|
31274
|
+
displayName: "LM Studio",
|
|
31275
|
+
transport: "local",
|
|
31276
|
+
baseUrl: "http://localhost:1234",
|
|
31277
|
+
apiPath: "/v1/chat/completions",
|
|
31278
|
+
apiKeyEnvVar: "",
|
|
31279
|
+
apiKeyDescription: "LM Studio (Local)",
|
|
31280
|
+
apiKeyUrl: "",
|
|
31281
|
+
shortcuts: ["lms", "lmstudio", "mlstudio"],
|
|
31282
|
+
shortestPrefix: "lms",
|
|
31283
|
+
legacyPrefixes: [
|
|
31284
|
+
{ prefix: "lmstudio/", stripPrefix: true },
|
|
31285
|
+
{ prefix: "lmstudio:", stripPrefix: true },
|
|
31286
|
+
{ prefix: "mlstudio/", stripPrefix: true },
|
|
31287
|
+
{ prefix: "mlstudio:", stripPrefix: true }
|
|
31288
|
+
],
|
|
31289
|
+
isLocal: true
|
|
31290
|
+
},
|
|
31291
|
+
{
|
|
31292
|
+
name: "vllm",
|
|
31293
|
+
displayName: "vLLM",
|
|
31294
|
+
transport: "local",
|
|
31295
|
+
baseUrl: "http://localhost:8000",
|
|
31296
|
+
apiPath: "/v1/chat/completions",
|
|
31297
|
+
apiKeyEnvVar: "",
|
|
31298
|
+
apiKeyDescription: "vLLM (Local)",
|
|
31299
|
+
apiKeyUrl: "",
|
|
31300
|
+
shortcuts: ["vllm"],
|
|
31301
|
+
shortestPrefix: "vllm",
|
|
31302
|
+
legacyPrefixes: [
|
|
31303
|
+
{ prefix: "vllm/", stripPrefix: true },
|
|
31304
|
+
{ prefix: "vllm:", stripPrefix: true }
|
|
31305
|
+
],
|
|
31306
|
+
isLocal: true
|
|
31307
|
+
},
|
|
31308
|
+
{
|
|
31309
|
+
name: "mlx",
|
|
31310
|
+
displayName: "MLX",
|
|
31311
|
+
transport: "local",
|
|
31312
|
+
baseUrl: "http://localhost:8080",
|
|
31313
|
+
apiPath: "/v1/chat/completions",
|
|
31314
|
+
apiKeyEnvVar: "",
|
|
31315
|
+
apiKeyDescription: "MLX (Local)",
|
|
31316
|
+
apiKeyUrl: "",
|
|
31317
|
+
shortcuts: ["mlx"],
|
|
31318
|
+
shortestPrefix: "mlx",
|
|
31319
|
+
legacyPrefixes: [
|
|
31320
|
+
{ prefix: "mlx/", stripPrefix: true },
|
|
31321
|
+
{ prefix: "mlx:", stripPrefix: true }
|
|
31322
|
+
],
|
|
31323
|
+
isLocal: true
|
|
31324
|
+
},
|
|
31325
|
+
{
|
|
31326
|
+
name: "qwen",
|
|
31327
|
+
displayName: "Qwen",
|
|
31328
|
+
transport: "openai",
|
|
31329
|
+
baseUrl: "",
|
|
31330
|
+
apiPath: "",
|
|
31331
|
+
apiKeyEnvVar: "",
|
|
31332
|
+
apiKeyDescription: "Qwen (auto-routed via OpenRouter)",
|
|
31333
|
+
apiKeyUrl: "",
|
|
31334
|
+
shortcuts: [],
|
|
31335
|
+
shortestPrefix: "qwen",
|
|
31336
|
+
legacyPrefixes: [],
|
|
31337
|
+
nativeModelPatterns: [{ pattern: /^qwen/i }]
|
|
31338
|
+
},
|
|
31339
|
+
{
|
|
31340
|
+
name: "native-anthropic",
|
|
31341
|
+
displayName: "Anthropic (Native)",
|
|
31342
|
+
transport: "anthropic",
|
|
31343
|
+
baseUrl: "",
|
|
31344
|
+
apiPath: "",
|
|
31345
|
+
apiKeyEnvVar: "",
|
|
31346
|
+
apiKeyDescription: "Anthropic (Native Claude Code auth)",
|
|
31347
|
+
apiKeyUrl: "",
|
|
31348
|
+
shortcuts: [],
|
|
31349
|
+
shortestPrefix: "",
|
|
31350
|
+
legacyPrefixes: [],
|
|
31351
|
+
nativeModelPatterns: [{ pattern: /^anthropic\//i }, { pattern: /^claude-/i }]
|
|
31352
|
+
}
|
|
31353
|
+
];
|
|
31354
|
+
});
|
|
31355
|
+
|
|
30249
31356
|
// src/providers/model-parser.ts
|
|
30250
31357
|
function parseModelSpec(modelSpec) {
|
|
30251
31358
|
const original = modelSpec;
|
|
@@ -30342,140 +31449,32 @@ function getLegacySyntaxWarning(parsed) {
|
|
|
30342
31449
|
return `Deprecation warning: "${parsed.original}" uses legacy prefix syntax.
|
|
30343
31450
|
` + ` Consider using: ${newSyntax}`;
|
|
30344
31451
|
}
|
|
30345
|
-
var PROVIDER_SHORTCUTS,
|
|
31452
|
+
var PROVIDER_SHORTCUTS, LOCAL_PROVIDERS, NATIVE_MODEL_PATTERNS, LEGACY_PREFIX_PATTERNS;
|
|
30346
31453
|
var init_model_parser = __esm(() => {
|
|
30347
|
-
|
|
30348
|
-
|
|
30349
|
-
|
|
30350
|
-
|
|
30351
|
-
|
|
30352
|
-
|
|
30353
|
-
|
|
30354
|
-
|
|
30355
|
-
|
|
30356
|
-
moon: "kimi",
|
|
30357
|
-
moonshot: "kimi",
|
|
30358
|
-
kc: "kimi-coding",
|
|
30359
|
-
glm: "glm",
|
|
30360
|
-
zhipu: "glm",
|
|
30361
|
-
gc: "glm-coding",
|
|
30362
|
-
zai: "zai",
|
|
30363
|
-
oc: "ollamacloud",
|
|
30364
|
-
zen: "opencode-zen",
|
|
30365
|
-
zengo: "opencode-zen-go",
|
|
30366
|
-
zgo: "opencode-zen-go",
|
|
30367
|
-
v: "vertex",
|
|
30368
|
-
vertex: "vertex",
|
|
30369
|
-
go: "gemini-codeassist",
|
|
30370
|
-
llama: "ollamacloud",
|
|
30371
|
-
lc: "ollamacloud",
|
|
30372
|
-
meta: "ollamacloud",
|
|
30373
|
-
poe: "poe",
|
|
30374
|
-
litellm: "litellm",
|
|
30375
|
-
ll: "litellm",
|
|
30376
|
-
ollama: "ollama",
|
|
30377
|
-
lms: "lmstudio",
|
|
30378
|
-
lmstudio: "lmstudio",
|
|
30379
|
-
mlstudio: "lmstudio",
|
|
30380
|
-
vllm: "vllm",
|
|
30381
|
-
mlx: "mlx"
|
|
30382
|
-
};
|
|
30383
|
-
DIRECT_API_PROVIDERS = new Set([
|
|
30384
|
-
"google",
|
|
30385
|
-
"openai",
|
|
30386
|
-
"minimax",
|
|
30387
|
-
"kimi",
|
|
30388
|
-
"minimax-coding",
|
|
30389
|
-
"kimi-coding",
|
|
30390
|
-
"glm",
|
|
30391
|
-
"glm-coding",
|
|
30392
|
-
"zai",
|
|
30393
|
-
"ollamacloud",
|
|
30394
|
-
"opencode-zen",
|
|
30395
|
-
"vertex",
|
|
30396
|
-
"gemini-codeassist",
|
|
30397
|
-
"poe",
|
|
30398
|
-
"litellm"
|
|
30399
|
-
]);
|
|
30400
|
-
LOCAL_PROVIDERS = new Set(["ollama", "lmstudio", "vllm", "mlx"]);
|
|
30401
|
-
NATIVE_MODEL_PATTERNS = [
|
|
30402
|
-
{ pattern: /^google\//i, provider: "google" },
|
|
30403
|
-
{ pattern: /^gemini-/i, provider: "google" },
|
|
30404
|
-
{ pattern: /^openai\//i, provider: "openai" },
|
|
30405
|
-
{ pattern: /^gpt-/i, provider: "openai" },
|
|
30406
|
-
{ pattern: /^o1(-|$)/i, provider: "openai" },
|
|
30407
|
-
{ pattern: /^o3(-|$)/i, provider: "openai" },
|
|
30408
|
-
{ pattern: /^chatgpt-/i, provider: "openai" },
|
|
30409
|
-
{ pattern: /^minimax\//i, provider: "minimax" },
|
|
30410
|
-
{ pattern: /^minimax-/i, provider: "minimax" },
|
|
30411
|
-
{ pattern: /^abab-/i, provider: "minimax" },
|
|
30412
|
-
{ pattern: /^kimi-for-coding$/i, provider: "kimi-coding" },
|
|
30413
|
-
{ pattern: /^moonshot(ai)?\//i, provider: "kimi" },
|
|
30414
|
-
{ pattern: /^moonshot-/i, provider: "kimi" },
|
|
30415
|
-
{ pattern: /^kimi-/i, provider: "kimi" },
|
|
30416
|
-
{ pattern: /^zhipu\//i, provider: "glm" },
|
|
30417
|
-
{ pattern: /^glm-/i, provider: "glm" },
|
|
30418
|
-
{ pattern: /^chatglm-/i, provider: "glm" },
|
|
30419
|
-
{ pattern: /^z-ai\//i, provider: "zai" },
|
|
30420
|
-
{ pattern: /^zai\//i, provider: "zai" },
|
|
30421
|
-
{ pattern: /^ollamacloud\//i, provider: "ollamacloud" },
|
|
30422
|
-
{ pattern: /^meta-llama\//i, provider: "ollamacloud" },
|
|
30423
|
-
{ pattern: /^llama-/i, provider: "ollamacloud" },
|
|
30424
|
-
{ pattern: /^llama3/i, provider: "ollamacloud" },
|
|
30425
|
-
{ pattern: /^openrouter\//i, provider: "openrouter" },
|
|
30426
|
-
{ pattern: /^qwen/i, provider: "qwen" },
|
|
30427
|
-
{ pattern: /^poe:/i, provider: "poe" },
|
|
30428
|
-
{ pattern: /^anthropic\//i, provider: "native-anthropic" },
|
|
30429
|
-
{ pattern: /^claude-/i, provider: "native-anthropic" }
|
|
30430
|
-
];
|
|
30431
|
-
LEGACY_PREFIX_PATTERNS = [
|
|
30432
|
-
{ prefix: "g/", provider: "google", stripPrefix: true },
|
|
30433
|
-
{ prefix: "gemini/", provider: "google", stripPrefix: true },
|
|
30434
|
-
{ prefix: "oai/", provider: "openai", stripPrefix: true },
|
|
30435
|
-
{ prefix: "or/", provider: "openrouter", stripPrefix: true },
|
|
30436
|
-
{ prefix: "mmax/", provider: "minimax", stripPrefix: true },
|
|
30437
|
-
{ prefix: "mm/", provider: "minimax", stripPrefix: true },
|
|
30438
|
-
{ prefix: "mmc/", provider: "minimax-coding", stripPrefix: true },
|
|
30439
|
-
{ prefix: "kimi/", provider: "kimi", stripPrefix: true },
|
|
30440
|
-
{ prefix: "moonshot/", provider: "kimi", stripPrefix: true },
|
|
30441
|
-
{ prefix: "kc/", provider: "kimi-coding", stripPrefix: true },
|
|
30442
|
-
{ prefix: "glm/", provider: "glm", stripPrefix: true },
|
|
30443
|
-
{ prefix: "zhipu/", provider: "glm", stripPrefix: true },
|
|
30444
|
-
{ prefix: "gc/", provider: "glm-coding", stripPrefix: true },
|
|
30445
|
-
{ prefix: "zai/", provider: "zai", stripPrefix: true },
|
|
30446
|
-
{ prefix: "oc/", provider: "ollamacloud", stripPrefix: true },
|
|
30447
|
-
{ prefix: "zen/", provider: "opencode-zen", stripPrefix: true },
|
|
30448
|
-
{ prefix: "zengo/", provider: "opencode-zen-go", stripPrefix: true },
|
|
30449
|
-
{ prefix: "zgo/", provider: "opencode-zen-go", stripPrefix: true },
|
|
30450
|
-
{ prefix: "v/", provider: "vertex", stripPrefix: true },
|
|
30451
|
-
{ prefix: "vertex/", provider: "vertex", stripPrefix: true },
|
|
30452
|
-
{ prefix: "go/", provider: "gemini-codeassist", stripPrefix: true },
|
|
30453
|
-
{ prefix: "ollama/", provider: "ollama", stripPrefix: true },
|
|
30454
|
-
{ prefix: "ollama:", provider: "ollama", stripPrefix: true },
|
|
30455
|
-
{ prefix: "lmstudio/", provider: "lmstudio", stripPrefix: true },
|
|
30456
|
-
{ prefix: "lmstudio:", provider: "lmstudio", stripPrefix: true },
|
|
30457
|
-
{ prefix: "mlstudio/", provider: "lmstudio", stripPrefix: true },
|
|
30458
|
-
{ prefix: "mlstudio:", provider: "lmstudio", stripPrefix: true },
|
|
30459
|
-
{ prefix: "vllm/", provider: "vllm", stripPrefix: true },
|
|
30460
|
-
{ prefix: "vllm:", provider: "vllm", stripPrefix: true },
|
|
30461
|
-
{ prefix: "mlx/", provider: "mlx", stripPrefix: true },
|
|
30462
|
-
{ prefix: "mlx:", provider: "mlx", stripPrefix: true }
|
|
30463
|
-
];
|
|
31454
|
+
init_provider_definitions();
|
|
31455
|
+
PROVIDER_SHORTCUTS = getShortcuts();
|
|
31456
|
+
LOCAL_PROVIDERS = {
|
|
31457
|
+
has(name) {
|
|
31458
|
+
return isLocalTransport(name);
|
|
31459
|
+
}
|
|
31460
|
+
};
|
|
31461
|
+
NATIVE_MODEL_PATTERNS = getNativeModelPatterns();
|
|
31462
|
+
LEGACY_PREFIX_PATTERNS = getLegacyPrefixPatterns();
|
|
30464
31463
|
});
|
|
30465
31464
|
|
|
30466
31465
|
// src/auth/oauth-registry.ts
|
|
30467
|
-
import { existsSync as
|
|
30468
|
-
import { join as
|
|
30469
|
-
import { homedir as
|
|
31466
|
+
import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
|
|
31467
|
+
import { join as join8 } from "path";
|
|
31468
|
+
import { homedir as homedir7 } from "os";
|
|
30470
31469
|
function hasValidOAuthCredentials(descriptor) {
|
|
30471
|
-
const credPath =
|
|
30472
|
-
if (!
|
|
31470
|
+
const credPath = join8(homedir7(), ".claudish", descriptor.credentialFile);
|
|
31471
|
+
if (!existsSync8(credPath))
|
|
30473
31472
|
return false;
|
|
30474
31473
|
if (descriptor.validationMode === "file-exists") {
|
|
30475
31474
|
return true;
|
|
30476
31475
|
}
|
|
30477
31476
|
try {
|
|
30478
|
-
const data = JSON.parse(
|
|
31477
|
+
const data = JSON.parse(readFileSync7(credPath, "utf-8"));
|
|
30479
31478
|
if (!data.access_token)
|
|
30480
31479
|
return false;
|
|
30481
31480
|
if (data.refresh_token)
|
|
@@ -30555,9 +31554,9 @@ var init_static_fallback = __esm(() => {
|
|
|
30555
31554
|
});
|
|
30556
31555
|
|
|
30557
31556
|
// src/providers/catalog-resolvers/openrouter.ts
|
|
30558
|
-
import { readFileSync as
|
|
30559
|
-
import { join as
|
|
30560
|
-
import { homedir as
|
|
31557
|
+
import { readFileSync as readFileSync8, existsSync as existsSync9 } from "fs";
|
|
31558
|
+
import { join as join9 } from "path";
|
|
31559
|
+
import { homedir as homedir8 } from "os";
|
|
30561
31560
|
|
|
30562
31561
|
class OpenRouterCatalogResolver {
|
|
30563
31562
|
provider = "openrouter";
|
|
@@ -30602,10 +31601,10 @@ class OpenRouterCatalogResolver {
|
|
|
30602
31601
|
_getModels() {
|
|
30603
31602
|
if (_memCache)
|
|
30604
31603
|
return _memCache;
|
|
30605
|
-
const diskPath =
|
|
30606
|
-
if (
|
|
31604
|
+
const diskPath = join9(homedir8(), ".claudish", "all-models.json");
|
|
31605
|
+
if (existsSync9(diskPath)) {
|
|
30607
31606
|
try {
|
|
30608
|
-
const data = JSON.parse(
|
|
31607
|
+
const data = JSON.parse(readFileSync8(diskPath, "utf-8"));
|
|
30609
31608
|
if (Array.isArray(data.models) && data.models.length > 0) {
|
|
30610
31609
|
_memCache = data.models;
|
|
30611
31610
|
return _memCache;
|
|
@@ -30622,16 +31621,16 @@ var init_openrouter = __esm(() => {
|
|
|
30622
31621
|
});
|
|
30623
31622
|
|
|
30624
31623
|
// src/providers/catalog-resolvers/litellm.ts
|
|
30625
|
-
import { readFileSync as
|
|
30626
|
-
import { join as
|
|
30627
|
-
import { homedir as
|
|
31624
|
+
import { readFileSync as readFileSync9, existsSync as existsSync10 } from "fs";
|
|
31625
|
+
import { join as join10 } from "path";
|
|
31626
|
+
import { homedir as homedir9 } from "os";
|
|
30628
31627
|
import { createHash as createHash3 } from "crypto";
|
|
30629
31628
|
function getCachePath() {
|
|
30630
31629
|
const baseUrl = process.env.LITELLM_BASE_URL;
|
|
30631
31630
|
if (!baseUrl)
|
|
30632
31631
|
return null;
|
|
30633
31632
|
const hash2 = createHash3("sha256").update(baseUrl).digest("hex").substring(0, 16);
|
|
30634
|
-
return
|
|
31633
|
+
return join10(homedir9(), ".claudish", `litellm-models-${hash2}.json`);
|
|
30635
31634
|
}
|
|
30636
31635
|
|
|
30637
31636
|
class LiteLLMCatalogResolver {
|
|
@@ -30659,10 +31658,10 @@ class LiteLLMCatalogResolver {
|
|
|
30659
31658
|
}
|
|
30660
31659
|
async warmCache() {
|
|
30661
31660
|
const path = getCachePath();
|
|
30662
|
-
if (!path || !
|
|
31661
|
+
if (!path || !existsSync10(path))
|
|
30663
31662
|
return;
|
|
30664
31663
|
try {
|
|
30665
|
-
const data = JSON.parse(
|
|
31664
|
+
const data = JSON.parse(readFileSync9(path, "utf-8"));
|
|
30666
31665
|
if (Array.isArray(data.models)) {
|
|
30667
31666
|
_memCache2 = data.models.map((m) => m.name ?? m.id?.replace("litellm@", "") ?? "");
|
|
30668
31667
|
}
|
|
@@ -30675,10 +31674,10 @@ class LiteLLMCatalogResolver {
|
|
|
30675
31674
|
if (_memCache2)
|
|
30676
31675
|
return _memCache2;
|
|
30677
31676
|
const path = getCachePath();
|
|
30678
|
-
if (!path || !
|
|
31677
|
+
if (!path || !existsSync10(path))
|
|
30679
31678
|
return null;
|
|
30680
31679
|
try {
|
|
30681
|
-
const data = JSON.parse(
|
|
31680
|
+
const data = JSON.parse(readFileSync9(path, "utf-8"));
|
|
30682
31681
|
if (Array.isArray(data.models)) {
|
|
30683
31682
|
_memCache2 = data.models.map((m) => m.name ?? m.id?.replace("litellm@", "") ?? "");
|
|
30684
31683
|
return _memCache2;
|
|
@@ -30737,17 +31736,17 @@ var init_model_catalog_resolver = __esm(() => {
|
|
|
30737
31736
|
});
|
|
30738
31737
|
|
|
30739
31738
|
// src/providers/auto-route.ts
|
|
30740
|
-
import { existsSync as
|
|
30741
|
-
import { join as
|
|
30742
|
-
import { homedir as
|
|
31739
|
+
import { existsSync as existsSync11, readFileSync as readFileSync10 } from "fs";
|
|
31740
|
+
import { join as join11 } from "path";
|
|
31741
|
+
import { homedir as homedir10 } from "os";
|
|
30743
31742
|
import { createHash as createHash4 } from "crypto";
|
|
30744
31743
|
function readLiteLLMCacheSync(baseUrl) {
|
|
30745
31744
|
const hash2 = createHash4("sha256").update(baseUrl).digest("hex").substring(0, 16);
|
|
30746
|
-
const cachePath =
|
|
30747
|
-
if (!
|
|
31745
|
+
const cachePath = join11(homedir10(), ".claudish", `litellm-models-${hash2}.json`);
|
|
31746
|
+
if (!existsSync11(cachePath))
|
|
30748
31747
|
return null;
|
|
30749
31748
|
try {
|
|
30750
|
-
const data = JSON.parse(
|
|
31749
|
+
const data = JSON.parse(readFileSync10(cachePath, "utf-8"));
|
|
30751
31750
|
if (!Array.isArray(data.models))
|
|
30752
31751
|
return null;
|
|
30753
31752
|
return data.models;
|
|
@@ -30767,7 +31766,7 @@ function checkOAuthForProvider(nativeProvider, modelName) {
|
|
|
30767
31766
|
};
|
|
30768
31767
|
}
|
|
30769
31768
|
function checkApiKeyForProvider(nativeProvider, modelName) {
|
|
30770
|
-
const keyInfo =
|
|
31769
|
+
const keyInfo = getApiKeyEnvVars(nativeProvider);
|
|
30771
31770
|
if (!keyInfo)
|
|
30772
31771
|
return null;
|
|
30773
31772
|
if (keyInfo.envVar && process.env[keyInfo.envVar]) {
|
|
@@ -30858,11 +31857,11 @@ function autoRoute(modelName, nativeProvider) {
|
|
|
30858
31857
|
return null;
|
|
30859
31858
|
}
|
|
30860
31859
|
function readZenModelCacheSync() {
|
|
30861
|
-
const cachePath =
|
|
30862
|
-
if (!
|
|
31860
|
+
const cachePath = join11(homedir10(), ".claudish", "zen-models.json");
|
|
31861
|
+
if (!existsSync11(cachePath))
|
|
30863
31862
|
return null;
|
|
30864
31863
|
try {
|
|
30865
|
-
const data = JSON.parse(
|
|
31864
|
+
const data = JSON.parse(readFileSync10(cachePath, "utf-8"));
|
|
30866
31865
|
if (!Array.isArray(data.models))
|
|
30867
31866
|
return null;
|
|
30868
31867
|
return new Set(data.models.map((m) => m.id));
|
|
@@ -30889,13 +31888,13 @@ async function warmZenModelCache() {
|
|
|
30889
31888
|
const models = (data.data ?? []).map((m) => ({ id: m.id }));
|
|
30890
31889
|
if (models.length === 0)
|
|
30891
31890
|
return;
|
|
30892
|
-
const cacheDir =
|
|
30893
|
-
const { mkdirSync:
|
|
30894
|
-
|
|
30895
|
-
writeSync3(
|
|
31891
|
+
const cacheDir = join11(homedir10(), ".claudish");
|
|
31892
|
+
const { mkdirSync: mkdirSync6, writeFileSync: writeSync3 } = await import("fs");
|
|
31893
|
+
mkdirSync6(cacheDir, { recursive: true });
|
|
31894
|
+
writeSync3(join11(cacheDir, "zen-models.json"), JSON.stringify({ models, fetchedAt: new Date().toISOString() }));
|
|
30896
31895
|
}
|
|
30897
31896
|
function hasProviderCredentials(provider) {
|
|
30898
|
-
const keyInfo =
|
|
31897
|
+
const keyInfo = getApiKeyEnvVars(provider);
|
|
30899
31898
|
if (keyInfo?.envVar && process.env[keyInfo.envVar])
|
|
30900
31899
|
return true;
|
|
30901
31900
|
if (keyInfo?.aliases?.some((a) => process.env[a]))
|
|
@@ -30948,27 +31947,12 @@ function getFallbackChain(modelName, nativeProvider) {
|
|
|
30948
31947
|
}
|
|
30949
31948
|
return routes;
|
|
30950
31949
|
}
|
|
30951
|
-
var
|
|
31950
|
+
var PROVIDER_HINT_MAP, PROVIDER_TO_PREFIX, DISPLAY_NAMES, SUBSCRIPTION_ALTERNATIVES;
|
|
30952
31951
|
var init_auto_route = __esm(() => {
|
|
30953
31952
|
init_oauth_registry();
|
|
30954
31953
|
init_model_catalog_resolver();
|
|
30955
|
-
|
|
30956
|
-
|
|
30957
|
-
"gemini-codeassist": { envVar: "GEMINI_API_KEY" },
|
|
30958
|
-
openai: { envVar: "OPENAI_API_KEY" },
|
|
30959
|
-
minimax: { envVar: "MINIMAX_API_KEY" },
|
|
30960
|
-
"minimax-coding": { envVar: "MINIMAX_CODING_API_KEY" },
|
|
30961
|
-
kimi: { envVar: "MOONSHOT_API_KEY", aliases: ["KIMI_API_KEY"] },
|
|
30962
|
-
"kimi-coding": { envVar: "KIMI_CODING_API_KEY" },
|
|
30963
|
-
glm: { envVar: "ZHIPU_API_KEY", aliases: ["GLM_API_KEY"] },
|
|
30964
|
-
"glm-coding": { envVar: "GLM_CODING_API_KEY", aliases: ["ZAI_CODING_API_KEY"] },
|
|
30965
|
-
zai: { envVar: "ZAI_API_KEY" },
|
|
30966
|
-
ollamacloud: { envVar: "OLLAMA_API_KEY" },
|
|
30967
|
-
litellm: { envVar: "LITELLM_API_KEY" },
|
|
30968
|
-
openrouter: { envVar: "OPENROUTER_API_KEY" },
|
|
30969
|
-
vertex: { envVar: "VERTEX_API_KEY", aliases: ["VERTEX_PROJECT"] },
|
|
30970
|
-
poe: { envVar: "POE_API_KEY" }
|
|
30971
|
-
};
|
|
31954
|
+
init_provider_definitions();
|
|
31955
|
+
init_provider_definitions();
|
|
30972
31956
|
PROVIDER_HINT_MAP = {
|
|
30973
31957
|
"kimi-coding": {
|
|
30974
31958
|
loginFlag: "--kimi-login",
|
|
@@ -31012,39 +31996,22 @@ var init_auto_route = __esm(() => {
|
|
|
31012
31996
|
apiKeyEnvVar: "OLLAMA_API_KEY"
|
|
31013
31997
|
}
|
|
31014
31998
|
};
|
|
31015
|
-
PROVIDER_TO_PREFIX = {
|
|
31016
|
-
|
|
31017
|
-
|
|
31018
|
-
|
|
31019
|
-
|
|
31020
|
-
|
|
31021
|
-
|
|
31022
|
-
|
|
31023
|
-
|
|
31024
|
-
|
|
31025
|
-
|
|
31026
|
-
|
|
31027
|
-
|
|
31028
|
-
|
|
31029
|
-
|
|
31030
|
-
|
|
31031
|
-
};
|
|
31032
|
-
DISPLAY_NAMES = {
|
|
31033
|
-
google: "Gemini",
|
|
31034
|
-
openai: "OpenAI",
|
|
31035
|
-
minimax: "MiniMax",
|
|
31036
|
-
"minimax-coding": "MiniMax Coding",
|
|
31037
|
-
kimi: "Kimi",
|
|
31038
|
-
"kimi-coding": "Kimi Coding",
|
|
31039
|
-
glm: "GLM",
|
|
31040
|
-
"glm-coding": "GLM Coding",
|
|
31041
|
-
zai: "Z.AI",
|
|
31042
|
-
ollamacloud: "OllamaCloud",
|
|
31043
|
-
"opencode-zen": "OpenCode Zen",
|
|
31044
|
-
"opencode-zen-go": "OpenCode Zen Go",
|
|
31045
|
-
litellm: "LiteLLM",
|
|
31046
|
-
openrouter: "OpenRouter"
|
|
31047
|
-
};
|
|
31999
|
+
PROVIDER_TO_PREFIX = (() => {
|
|
32000
|
+
const map3 = {};
|
|
32001
|
+
for (const def of getAllProviders()) {
|
|
32002
|
+
if (def.shortestPrefix) {
|
|
32003
|
+
map3[def.name] = def.shortestPrefix;
|
|
32004
|
+
}
|
|
32005
|
+
}
|
|
32006
|
+
return map3;
|
|
32007
|
+
})();
|
|
32008
|
+
DISPLAY_NAMES = (() => {
|
|
32009
|
+
const map3 = {};
|
|
32010
|
+
for (const def of getAllProviders()) {
|
|
32011
|
+
map3[def.name] = def.displayName;
|
|
32012
|
+
}
|
|
32013
|
+
return map3;
|
|
32014
|
+
})();
|
|
31048
32015
|
SUBSCRIPTION_ALTERNATIVES = {
|
|
31049
32016
|
kimi: {
|
|
31050
32017
|
subscriptionProvider: "kimi-coding",
|
|
@@ -31275,40 +32242,20 @@ function resolveRemoteProvider(modelId) {
|
|
|
31275
32242
|
if (parsed.provider === "custom-url") {
|
|
31276
32243
|
return null;
|
|
31277
32244
|
}
|
|
31278
|
-
const
|
|
31279
|
-
|
|
31280
|
-
|
|
31281
|
-
|
|
31282
|
-
|
|
31283
|
-
|
|
31284
|
-
|
|
31285
|
-
|
|
31286
|
-
glm: "glm",
|
|
31287
|
-
"glm-coding": "glm-coding",
|
|
31288
|
-
zai: "zai",
|
|
31289
|
-
ollamacloud: "ollamacloud",
|
|
31290
|
-
"opencode-zen": "opencode-zen",
|
|
31291
|
-
"opencode-zen-go": "opencode-zen-go",
|
|
31292
|
-
vertex: "vertex",
|
|
31293
|
-
"gemini-codeassist": "gemini-codeassist",
|
|
31294
|
-
litellm: "litellm"
|
|
31295
|
-
};
|
|
31296
|
-
const mappedProviderName = providerNameMap[parsed.provider];
|
|
31297
|
-
if (mappedProviderName) {
|
|
31298
|
-
const provider = providers.find((p) => p.name === mappedProviderName);
|
|
31299
|
-
if (provider) {
|
|
31300
|
-
return {
|
|
31301
|
-
provider,
|
|
31302
|
-
modelName: parsed.model,
|
|
31303
|
-
isLegacySyntax: parsed.isLegacySyntax
|
|
31304
|
-
};
|
|
31305
|
-
}
|
|
32245
|
+
const mappedName = parsed.provider === "google" ? "gemini" : parsed.provider;
|
|
32246
|
+
const provider = providers.find((p) => p.name === mappedName || p.name === parsed.provider);
|
|
32247
|
+
if (provider) {
|
|
32248
|
+
return {
|
|
32249
|
+
provider,
|
|
32250
|
+
modelName: parsed.model,
|
|
32251
|
+
isLegacySyntax: parsed.isLegacySyntax
|
|
32252
|
+
};
|
|
31306
32253
|
}
|
|
31307
|
-
for (const
|
|
31308
|
-
for (const prefix of
|
|
32254
|
+
for (const provider2 of providers) {
|
|
32255
|
+
for (const prefix of provider2.prefixes) {
|
|
31309
32256
|
if (modelId.startsWith(prefix)) {
|
|
31310
32257
|
return {
|
|
31311
|
-
provider,
|
|
32258
|
+
provider: provider2,
|
|
31312
32259
|
modelName: modelId.slice(prefix.length),
|
|
31313
32260
|
isLegacySyntax: true
|
|
31314
32261
|
};
|
|
@@ -31354,128 +32301,12 @@ Set it with:
|
|
|
31354
32301
|
function getRegisteredRemoteProviders() {
|
|
31355
32302
|
return getRemoteProviders();
|
|
31356
32303
|
}
|
|
31357
|
-
var getRemoteProviders = () =>
|
|
31358
|
-
|
|
31359
|
-
|
|
31360
|
-
baseUrl: process.env.GEMINI_BASE_URL || "https://generativelanguage.googleapis.com",
|
|
31361
|
-
apiPath: "/v1beta/models/{model}:streamGenerateContent?alt=sse",
|
|
31362
|
-
apiKeyEnvVar: "GEMINI_API_KEY",
|
|
31363
|
-
prefixes: ["g/", "gemini/"]
|
|
31364
|
-
},
|
|
31365
|
-
{
|
|
31366
|
-
name: "gemini-codeassist",
|
|
31367
|
-
baseUrl: "https://cloudcode-pa.googleapis.com",
|
|
31368
|
-
apiPath: "/v1internal:streamGenerateContent?alt=sse",
|
|
31369
|
-
apiKeyEnvVar: "",
|
|
31370
|
-
prefixes: ["go/"]
|
|
31371
|
-
},
|
|
31372
|
-
{
|
|
31373
|
-
name: "openai",
|
|
31374
|
-
baseUrl: process.env.OPENAI_BASE_URL || "https://api.openai.com",
|
|
31375
|
-
apiPath: "/v1/chat/completions",
|
|
31376
|
-
apiKeyEnvVar: "OPENAI_API_KEY",
|
|
31377
|
-
prefixes: ["oai/"]
|
|
31378
|
-
},
|
|
31379
|
-
{
|
|
31380
|
-
name: "openrouter",
|
|
31381
|
-
baseUrl: "https://openrouter.ai",
|
|
31382
|
-
apiPath: "/api/v1/chat/completions",
|
|
31383
|
-
apiKeyEnvVar: "OPENROUTER_API_KEY",
|
|
31384
|
-
prefixes: ["or/"],
|
|
31385
|
-
headers: {
|
|
31386
|
-
"HTTP-Referer": "https://claudish.com",
|
|
31387
|
-
"X-Title": "Claudish - OpenRouter Proxy"
|
|
31388
|
-
}
|
|
31389
|
-
},
|
|
31390
|
-
{
|
|
31391
|
-
name: "minimax",
|
|
31392
|
-
baseUrl: process.env.MINIMAX_BASE_URL || "https://api.minimax.io",
|
|
31393
|
-
apiPath: "/anthropic/v1/messages",
|
|
31394
|
-
apiKeyEnvVar: "MINIMAX_API_KEY",
|
|
31395
|
-
prefixes: ["mmax/", "mm/"],
|
|
31396
|
-
authScheme: "bearer"
|
|
31397
|
-
},
|
|
31398
|
-
{
|
|
31399
|
-
name: "minimax-coding",
|
|
31400
|
-
baseUrl: process.env.MINIMAX_CODING_BASE_URL || "https://api.minimax.io",
|
|
31401
|
-
apiPath: "/anthropic/v1/messages",
|
|
31402
|
-
apiKeyEnvVar: "MINIMAX_CODING_API_KEY",
|
|
31403
|
-
prefixes: ["mmc/"],
|
|
31404
|
-
authScheme: "bearer"
|
|
31405
|
-
},
|
|
31406
|
-
{
|
|
31407
|
-
name: "kimi",
|
|
31408
|
-
baseUrl: process.env.MOONSHOT_BASE_URL || process.env.KIMI_BASE_URL || "https://api.moonshot.ai",
|
|
31409
|
-
apiPath: "/anthropic/v1/messages",
|
|
31410
|
-
apiKeyEnvVar: "MOONSHOT_API_KEY",
|
|
31411
|
-
prefixes: ["kimi/", "moonshot/"]
|
|
31412
|
-
},
|
|
31413
|
-
{
|
|
31414
|
-
name: "kimi-coding",
|
|
31415
|
-
baseUrl: "https://api.kimi.com/coding/v1",
|
|
31416
|
-
apiPath: "/messages",
|
|
31417
|
-
apiKeyEnvVar: "KIMI_CODING_API_KEY",
|
|
31418
|
-
prefixes: ["kc/"]
|
|
31419
|
-
},
|
|
31420
|
-
{
|
|
31421
|
-
name: "glm",
|
|
31422
|
-
baseUrl: process.env.ZHIPU_BASE_URL || process.env.GLM_BASE_URL || "https://open.bigmodel.cn",
|
|
31423
|
-
apiPath: "/api/paas/v4/chat/completions",
|
|
31424
|
-
apiKeyEnvVar: "ZHIPU_API_KEY",
|
|
31425
|
-
prefixes: ["glm/", "zhipu/"]
|
|
31426
|
-
},
|
|
31427
|
-
{
|
|
31428
|
-
name: "glm-coding",
|
|
31429
|
-
baseUrl: "https://api.z.ai",
|
|
31430
|
-
apiPath: "/api/coding/paas/v4/chat/completions",
|
|
31431
|
-
apiKeyEnvVar: "GLM_CODING_API_KEY",
|
|
31432
|
-
prefixes: ["gc/"]
|
|
31433
|
-
},
|
|
31434
|
-
{
|
|
31435
|
-
name: "zai",
|
|
31436
|
-
baseUrl: process.env.ZAI_BASE_URL || "https://api.z.ai",
|
|
31437
|
-
apiPath: "/api/anthropic/v1/messages",
|
|
31438
|
-
apiKeyEnvVar: "ZAI_API_KEY",
|
|
31439
|
-
prefixes: ["zai/"]
|
|
31440
|
-
},
|
|
31441
|
-
{
|
|
31442
|
-
name: "ollamacloud",
|
|
31443
|
-
baseUrl: process.env.OLLAMACLOUD_BASE_URL || "https://ollama.com",
|
|
31444
|
-
apiPath: "/api/chat",
|
|
31445
|
-
apiKeyEnvVar: "OLLAMA_API_KEY",
|
|
31446
|
-
prefixes: ["oc/"]
|
|
31447
|
-
},
|
|
31448
|
-
{
|
|
31449
|
-
name: "opencode-zen",
|
|
31450
|
-
baseUrl: process.env.OPENCODE_BASE_URL || "https://opencode.ai/zen",
|
|
31451
|
-
apiPath: "/v1/chat/completions",
|
|
31452
|
-
apiKeyEnvVar: "OPENCODE_API_KEY",
|
|
31453
|
-
prefixes: ["zen/"]
|
|
31454
|
-
},
|
|
31455
|
-
{
|
|
31456
|
-
name: "opencode-zen-go",
|
|
31457
|
-
baseUrl: process.env.OPENCODE_BASE_URL ? process.env.OPENCODE_BASE_URL.replace("/zen", "/zen/go") : "https://opencode.ai/zen/go",
|
|
31458
|
-
apiPath: "/v1/chat/completions",
|
|
31459
|
-
apiKeyEnvVar: "OPENCODE_API_KEY",
|
|
31460
|
-
prefixes: ["zengo/", "zgo/"]
|
|
31461
|
-
},
|
|
31462
|
-
{
|
|
31463
|
-
name: "vertex",
|
|
31464
|
-
baseUrl: "",
|
|
31465
|
-
apiPath: "",
|
|
31466
|
-
apiKeyEnvVar: "VERTEX_PROJECT",
|
|
31467
|
-
prefixes: ["v/", "vertex/"]
|
|
31468
|
-
},
|
|
31469
|
-
{
|
|
31470
|
-
name: "litellm",
|
|
31471
|
-
baseUrl: process.env.LITELLM_BASE_URL || "",
|
|
31472
|
-
apiPath: "/v1/chat/completions",
|
|
31473
|
-
apiKeyEnvVar: "LITELLM_API_KEY",
|
|
31474
|
-
prefixes: ["litellm/", "ll/"]
|
|
31475
|
-
}
|
|
31476
|
-
];
|
|
32304
|
+
var getRemoteProviders = () => {
|
|
32305
|
+
return getAllProviders().filter((def) => !def.isLocal && def.baseUrl !== "" && def.name !== "qwen" && def.name !== "native-anthropic").map(toRemoteProvider);
|
|
32306
|
+
};
|
|
31477
32307
|
var init_remote_provider_registry = __esm(() => {
|
|
31478
32308
|
init_model_parser();
|
|
32309
|
+
init_provider_definitions();
|
|
31479
32310
|
});
|
|
31480
32311
|
|
|
31481
32312
|
// src/providers/provider-resolver.ts
|
|
@@ -31489,9 +32320,27 @@ __export(exports_provider_resolver, {
|
|
|
31489
32320
|
getMissingKeyResolutions: () => getMissingKeyResolutions,
|
|
31490
32321
|
getMissingKeyError: () => getMissingKeyError
|
|
31491
32322
|
});
|
|
31492
|
-
import { existsSync as
|
|
31493
|
-
import { join as
|
|
31494
|
-
import { homedir as
|
|
32323
|
+
import { existsSync as existsSync12 } from "fs";
|
|
32324
|
+
import { join as join12 } from "path";
|
|
32325
|
+
import { homedir as homedir11 } from "os";
|
|
32326
|
+
function getApiKeyInfoForProvider(providerName) {
|
|
32327
|
+
const lookupName = providerName === "gemini" ? "google" : providerName;
|
|
32328
|
+
const info = getApiKeyInfo(lookupName);
|
|
32329
|
+
if (info) {
|
|
32330
|
+
return {
|
|
32331
|
+
envVar: info.envVar,
|
|
32332
|
+
description: info.description,
|
|
32333
|
+
url: info.url,
|
|
32334
|
+
aliases: info.aliases,
|
|
32335
|
+
oauthFallback: info.oauthFallback
|
|
32336
|
+
};
|
|
32337
|
+
}
|
|
32338
|
+
return {
|
|
32339
|
+
envVar: "",
|
|
32340
|
+
description: `${providerName} API Key`,
|
|
32341
|
+
url: ""
|
|
32342
|
+
};
|
|
32343
|
+
}
|
|
31495
32344
|
function isApiKeyAvailable(info) {
|
|
31496
32345
|
if (!info.envVar) {
|
|
31497
32346
|
return true;
|
|
@@ -31508,8 +32357,8 @@ function isApiKeyAvailable(info) {
|
|
|
31508
32357
|
}
|
|
31509
32358
|
if (info.oauthFallback) {
|
|
31510
32359
|
try {
|
|
31511
|
-
const credPath =
|
|
31512
|
-
if (
|
|
32360
|
+
const credPath = join12(homedir11(), ".claudish", info.oauthFallback);
|
|
32361
|
+
if (existsSync12(credPath)) {
|
|
31513
32362
|
return true;
|
|
31514
32363
|
}
|
|
31515
32364
|
} catch {}
|
|
@@ -31792,105 +32641,21 @@ var init_provider_resolver = __esm(() => {
|
|
|
31792
32641
|
init_remote_provider_registry();
|
|
31793
32642
|
init_auto_route();
|
|
31794
32643
|
init_model_parser();
|
|
31795
|
-
|
|
31796
|
-
|
|
31797
|
-
|
|
31798
|
-
|
|
31799
|
-
url: "https://openrouter.ai/keys"
|
|
31800
|
-
},
|
|
31801
|
-
gemini: {
|
|
31802
|
-
envVar: "GEMINI_API_KEY",
|
|
31803
|
-
description: "Google Gemini API Key",
|
|
31804
|
-
url: "https://aistudio.google.com/app/apikey"
|
|
31805
|
-
},
|
|
31806
|
-
"gemini-codeassist": {
|
|
31807
|
-
envVar: "",
|
|
31808
|
-
description: "Gemini Code Assist (OAuth)",
|
|
31809
|
-
url: "https://cloud.google.com/code-assist"
|
|
31810
|
-
},
|
|
31811
|
-
vertex: {
|
|
31812
|
-
envVar: "VERTEX_API_KEY",
|
|
31813
|
-
description: "Vertex AI API Key",
|
|
31814
|
-
url: "https://console.cloud.google.com/vertex-ai",
|
|
31815
|
-
aliases: ["VERTEX_PROJECT"]
|
|
31816
|
-
},
|
|
31817
|
-
openai: {
|
|
31818
|
-
envVar: "OPENAI_API_KEY",
|
|
31819
|
-
description: "OpenAI API Key",
|
|
31820
|
-
url: "https://platform.openai.com/api-keys"
|
|
31821
|
-
},
|
|
31822
|
-
minimax: {
|
|
31823
|
-
envVar: "MINIMAX_API_KEY",
|
|
31824
|
-
description: "MiniMax API Key",
|
|
31825
|
-
url: "https://www.minimaxi.com/"
|
|
31826
|
-
},
|
|
31827
|
-
"minimax-coding": {
|
|
31828
|
-
envVar: "MINIMAX_CODING_API_KEY",
|
|
31829
|
-
description: "MiniMax Coding Plan API Key",
|
|
31830
|
-
url: "https://platform.minimax.io/user-center/basic-information/interface-key"
|
|
31831
|
-
},
|
|
31832
|
-
kimi: {
|
|
31833
|
-
envVar: "MOONSHOT_API_KEY",
|
|
31834
|
-
description: "Kimi/Moonshot API Key",
|
|
31835
|
-
url: "https://platform.moonshot.cn/",
|
|
31836
|
-
aliases: ["KIMI_API_KEY"]
|
|
31837
|
-
},
|
|
31838
|
-
"kimi-coding": {
|
|
31839
|
-
envVar: "KIMI_CODING_API_KEY",
|
|
31840
|
-
description: "Kimi Coding API Key",
|
|
31841
|
-
url: "https://kimi.com/code (get key from membership page, or run: claudish --kimi-login)",
|
|
31842
|
-
oauthFallback: "kimi-oauth.json"
|
|
32644
|
+
init_provider_definitions();
|
|
32645
|
+
API_KEY_INFO = new Proxy({}, {
|
|
32646
|
+
get(_target, prop) {
|
|
32647
|
+
return getApiKeyInfoForProvider(prop);
|
|
31843
32648
|
},
|
|
31844
|
-
|
|
31845
|
-
|
|
31846
|
-
description: "GLM/Zhipu API Key",
|
|
31847
|
-
url: "https://open.bigmodel.cn/",
|
|
31848
|
-
aliases: ["GLM_API_KEY"]
|
|
31849
|
-
},
|
|
31850
|
-
"glm-coding": {
|
|
31851
|
-
envVar: "GLM_CODING_API_KEY",
|
|
31852
|
-
description: "GLM Coding Plan API Key",
|
|
31853
|
-
url: "https://z.ai/subscribe",
|
|
31854
|
-
aliases: ["ZAI_CODING_API_KEY"]
|
|
31855
|
-
},
|
|
31856
|
-
ollamacloud: {
|
|
31857
|
-
envVar: "OLLAMA_API_KEY",
|
|
31858
|
-
description: "OllamaCloud API Key",
|
|
31859
|
-
url: "https://ollama.com/account"
|
|
31860
|
-
},
|
|
31861
|
-
"opencode-zen": {
|
|
31862
|
-
envVar: "",
|
|
31863
|
-
description: "OpenCode Zen (Free)",
|
|
31864
|
-
url: "https://opencode.ai/"
|
|
31865
|
-
},
|
|
31866
|
-
zai: {
|
|
31867
|
-
envVar: "ZAI_API_KEY",
|
|
31868
|
-
description: "Z.AI API Key",
|
|
31869
|
-
url: "https://z.ai/"
|
|
31870
|
-
},
|
|
31871
|
-
litellm: {
|
|
31872
|
-
envVar: "LITELLM_API_KEY",
|
|
31873
|
-
description: "LiteLLM API Key",
|
|
31874
|
-
url: "https://docs.litellm.ai/"
|
|
32649
|
+
has() {
|
|
32650
|
+
return true;
|
|
31875
32651
|
}
|
|
31876
|
-
};
|
|
31877
|
-
PROVIDER_DISPLAY_NAMES = {
|
|
31878
|
-
|
|
31879
|
-
|
|
31880
|
-
|
|
31881
|
-
|
|
31882
|
-
|
|
31883
|
-
minimax: "MiniMax",
|
|
31884
|
-
"minimax-coding": "MiniMax Coding",
|
|
31885
|
-
kimi: "Kimi",
|
|
31886
|
-
"kimi-coding": "Kimi Coding",
|
|
31887
|
-
glm: "GLM",
|
|
31888
|
-
"glm-coding": "GLM Coding",
|
|
31889
|
-
zai: "Z.AI",
|
|
31890
|
-
ollamacloud: "OllamaCloud",
|
|
31891
|
-
"opencode-zen": "OpenCode Zen",
|
|
31892
|
-
litellm: "LiteLLM"
|
|
31893
|
-
};
|
|
32652
|
+
});
|
|
32653
|
+
PROVIDER_DISPLAY_NAMES = new Proxy({}, {
|
|
32654
|
+
get(_target, prop) {
|
|
32655
|
+
const lookupName = prop === "gemini" ? "google" : prop;
|
|
32656
|
+
return getDisplayName(lookupName);
|
|
32657
|
+
}
|
|
32658
|
+
});
|
|
31894
32659
|
});
|
|
31895
32660
|
|
|
31896
32661
|
// src/adapters/tool-name-utils.ts
|
|
@@ -32219,6 +32984,12 @@ var init_openai_tools = __esm(() => {
|
|
|
32219
32984
|
});
|
|
32220
32985
|
|
|
32221
32986
|
// src/adapters/base-adapter.ts
|
|
32987
|
+
function matchesModelFamily(modelId, family) {
|
|
32988
|
+
const lower = modelId.toLowerCase();
|
|
32989
|
+
const fam = family.toLowerCase();
|
|
32990
|
+
return lower.startsWith(fam) || lower.includes(`/${fam}`);
|
|
32991
|
+
}
|
|
32992
|
+
|
|
32222
32993
|
class BaseModelAdapter {
|
|
32223
32994
|
modelId;
|
|
32224
32995
|
toolNameMap = new Map;
|
|
@@ -32414,13 +33185,15 @@ var init_grok_adapter = __esm(() => {
|
|
|
32414
33185
|
return params;
|
|
32415
33186
|
}
|
|
32416
33187
|
shouldHandle(modelId) {
|
|
32417
|
-
return modelId
|
|
33188
|
+
return matchesModelFamily(modelId, "grok") || modelId.toLowerCase().includes("x-ai/");
|
|
32418
33189
|
}
|
|
32419
33190
|
getName() {
|
|
32420
33191
|
return "GrokAdapter";
|
|
32421
33192
|
}
|
|
32422
33193
|
getContextWindow() {
|
|
32423
33194
|
const model = this.modelId.toLowerCase();
|
|
33195
|
+
if (model.includes("grok-4.20") || model.includes("grok-4-20"))
|
|
33196
|
+
return 2000000;
|
|
32424
33197
|
if (model.includes("grok-4.1-fast") || model.includes("grok-4-1-fast"))
|
|
32425
33198
|
return 2000000;
|
|
32426
33199
|
if (model.includes("grok-4-fast"))
|
|
@@ -33666,10 +34439,10 @@ CRITICAL INSTRUCTION FOR OUTPUT FORMAT:
|
|
|
33666
34439
|
this.reasoningBlockDepth = 0;
|
|
33667
34440
|
}
|
|
33668
34441
|
getContextWindow() {
|
|
33669
|
-
return
|
|
34442
|
+
return 1048576;
|
|
33670
34443
|
}
|
|
33671
34444
|
shouldHandle(modelId) {
|
|
33672
|
-
return modelId
|
|
34445
|
+
return matchesModelFamily(modelId, "gemini") || modelId.toLowerCase().includes("google/");
|
|
33673
34446
|
}
|
|
33674
34447
|
getName() {
|
|
33675
34448
|
return "GeminiAdapter";
|
|
@@ -33722,7 +34495,7 @@ var init_codex_adapter = __esm(() => {
|
|
|
33722
34495
|
};
|
|
33723
34496
|
}
|
|
33724
34497
|
shouldHandle(modelId) {
|
|
33725
|
-
return modelId
|
|
34498
|
+
return matchesModelFamily(modelId, "codex");
|
|
33726
34499
|
}
|
|
33727
34500
|
getName() {
|
|
33728
34501
|
return "CodexAdapter";
|
|
@@ -33886,9 +34659,11 @@ var init_openai_adapter = __esm(() => {
|
|
|
33886
34659
|
}
|
|
33887
34660
|
getContextWindow() {
|
|
33888
34661
|
const model = this.modelId.toLowerCase();
|
|
34662
|
+
if (model.includes("gpt-5.4"))
|
|
34663
|
+
return 1050000;
|
|
33889
34664
|
if (model.includes("gpt-5"))
|
|
33890
|
-
return
|
|
33891
|
-
if (model.includes("o1") || model.includes("o3"))
|
|
34665
|
+
return 400000;
|
|
34666
|
+
if (model.includes("o1") || model.includes("o3") || model.includes("o4"))
|
|
33892
34667
|
return 200000;
|
|
33893
34668
|
if (model.includes("gpt-4o") || model.includes("gpt-4-turbo"))
|
|
33894
34669
|
return 128000;
|
|
@@ -33994,8 +34769,7 @@ var init_qwen_adapter = __esm(() => {
|
|
|
33994
34769
|
return request;
|
|
33995
34770
|
}
|
|
33996
34771
|
shouldHandle(modelId) {
|
|
33997
|
-
|
|
33998
|
-
return lower.includes("qwen") || lower.includes("alibaba");
|
|
34772
|
+
return matchesModelFamily(modelId, "qwen") || matchesModelFamily(modelId, "alibaba");
|
|
33999
34773
|
}
|
|
34000
34774
|
getName() {
|
|
34001
34775
|
return "QwenAdapter";
|
|
@@ -34025,7 +34799,7 @@ var init_minimax_adapter = __esm(() => {
|
|
|
34025
34799
|
return request;
|
|
34026
34800
|
}
|
|
34027
34801
|
shouldHandle(modelId) {
|
|
34028
|
-
return modelId
|
|
34802
|
+
return matchesModelFamily(modelId, "minimax");
|
|
34029
34803
|
}
|
|
34030
34804
|
getName() {
|
|
34031
34805
|
return "MiniMaxAdapter";
|
|
@@ -34054,7 +34828,7 @@ var init_deepseek_adapter = __esm(() => {
|
|
|
34054
34828
|
return request;
|
|
34055
34829
|
}
|
|
34056
34830
|
shouldHandle(modelId) {
|
|
34057
|
-
return modelId
|
|
34831
|
+
return matchesModelFamily(modelId, "deepseek");
|
|
34058
34832
|
}
|
|
34059
34833
|
getName() {
|
|
34060
34834
|
return "DeepSeekAdapter";
|
|
@@ -34068,18 +34842,20 @@ var init_glm_adapter = __esm(() => {
|
|
|
34068
34842
|
init_base_adapter();
|
|
34069
34843
|
init_logger();
|
|
34070
34844
|
GLM_CONTEXT_WINDOWS = [
|
|
34071
|
-
["glm-5",
|
|
34072
|
-
["glm-
|
|
34073
|
-
["glm-4.7",
|
|
34074
|
-
["glm-4.
|
|
34845
|
+
["glm-5-turbo", 202752],
|
|
34846
|
+
["glm-5", 80000],
|
|
34847
|
+
["glm-4.7-flash", 202752],
|
|
34848
|
+
["glm-4.7", 202752],
|
|
34849
|
+
["glm-4.6v", 131072],
|
|
34075
34850
|
["glm-4.6", 204800],
|
|
34076
|
-
["glm-4.5v",
|
|
34851
|
+
["glm-4.5v", 65536],
|
|
34077
34852
|
["glm-4.5-flash", 131072],
|
|
34078
34853
|
["glm-4.5-air", 131072],
|
|
34079
34854
|
["glm-4.5", 131072],
|
|
34080
34855
|
["glm-4-long", 1e6],
|
|
34081
34856
|
["glm-4-plus", 128000],
|
|
34082
34857
|
["glm-4-flash", 128000],
|
|
34858
|
+
["glm-4-32b", 128000],
|
|
34083
34859
|
["glm-4", 128000],
|
|
34084
34860
|
["glm-3-turbo", 128000],
|
|
34085
34861
|
["glm-", 131072]
|
|
@@ -34101,7 +34877,7 @@ var init_glm_adapter = __esm(() => {
|
|
|
34101
34877
|
return request;
|
|
34102
34878
|
}
|
|
34103
34879
|
shouldHandle(modelId) {
|
|
34104
|
-
return modelId
|
|
34880
|
+
return matchesModelFamily(modelId, "glm-") || matchesModelFamily(modelId, "chatglm-") || modelId.toLowerCase().includes("zhipu/");
|
|
34105
34881
|
}
|
|
34106
34882
|
getName() {
|
|
34107
34883
|
return "GLMAdapter";
|
|
@@ -34121,6 +34897,42 @@ var init_glm_adapter = __esm(() => {
|
|
|
34121
34897
|
};
|
|
34122
34898
|
});
|
|
34123
34899
|
|
|
34900
|
+
// src/adapters/xiaomi-adapter.ts
|
|
34901
|
+
var XiaomiAdapter;
|
|
34902
|
+
var init_xiaomi_adapter = __esm(() => {
|
|
34903
|
+
init_base_adapter();
|
|
34904
|
+
init_logger();
|
|
34905
|
+
XiaomiAdapter = class XiaomiAdapter extends BaseModelAdapter {
|
|
34906
|
+
processTextContent(textContent, accumulatedText) {
|
|
34907
|
+
return {
|
|
34908
|
+
cleanedText: textContent,
|
|
34909
|
+
extractedToolCalls: [],
|
|
34910
|
+
wasTransformed: false
|
|
34911
|
+
};
|
|
34912
|
+
}
|
|
34913
|
+
getToolNameLimit() {
|
|
34914
|
+
return 64;
|
|
34915
|
+
}
|
|
34916
|
+
prepareRequest(request, originalRequest) {
|
|
34917
|
+
if (originalRequest.thinking) {
|
|
34918
|
+
log(`[XiaomiAdapter] Stripping thinking object (not supported by Xiaomi API)`);
|
|
34919
|
+
delete request.thinking;
|
|
34920
|
+
}
|
|
34921
|
+
this.truncateToolNames(request);
|
|
34922
|
+
if (request.messages) {
|
|
34923
|
+
this.truncateToolNamesInMessages(request.messages);
|
|
34924
|
+
}
|
|
34925
|
+
return request;
|
|
34926
|
+
}
|
|
34927
|
+
shouldHandle(modelId) {
|
|
34928
|
+
return matchesModelFamily(modelId, "xiaomi") || matchesModelFamily(modelId, "mimo");
|
|
34929
|
+
}
|
|
34930
|
+
getName() {
|
|
34931
|
+
return "XiaomiAdapter";
|
|
34932
|
+
}
|
|
34933
|
+
};
|
|
34934
|
+
});
|
|
34935
|
+
|
|
34124
34936
|
// src/adapters/adapter-manager.ts
|
|
34125
34937
|
var exports_adapter_manager = {};
|
|
34126
34938
|
__export(exports_adapter_manager, {
|
|
@@ -34139,7 +34951,8 @@ class AdapterManager {
|
|
|
34139
34951
|
new QwenAdapter(modelId),
|
|
34140
34952
|
new MiniMaxAdapter(modelId),
|
|
34141
34953
|
new DeepSeekAdapter(modelId),
|
|
34142
|
-
new GLMAdapter(modelId)
|
|
34954
|
+
new GLMAdapter(modelId),
|
|
34955
|
+
new XiaomiAdapter(modelId)
|
|
34143
34956
|
];
|
|
34144
34957
|
this.defaultAdapter = new DefaultAdapter(modelId);
|
|
34145
34958
|
}
|
|
@@ -34165,6 +34978,7 @@ var init_adapter_manager = __esm(() => {
|
|
|
34165
34978
|
init_minimax_adapter();
|
|
34166
34979
|
init_deepseek_adapter();
|
|
34167
34980
|
init_glm_adapter();
|
|
34981
|
+
init_xiaomi_adapter();
|
|
34168
34982
|
});
|
|
34169
34983
|
|
|
34170
34984
|
// src/cli.ts
|
|
@@ -34181,31 +34995,31 @@ __export(exports_cli, {
|
|
|
34181
34995
|
getMissingKeyError: () => getMissingKeyError
|
|
34182
34996
|
});
|
|
34183
34997
|
import {
|
|
34184
|
-
readFileSync as
|
|
34185
|
-
writeFileSync as
|
|
34186
|
-
existsSync as
|
|
34187
|
-
mkdirSync as
|
|
34998
|
+
readFileSync as readFileSync11,
|
|
34999
|
+
writeFileSync as writeFileSync6,
|
|
35000
|
+
existsSync as existsSync13,
|
|
35001
|
+
mkdirSync as mkdirSync6,
|
|
34188
35002
|
copyFileSync,
|
|
34189
|
-
readdirSync,
|
|
34190
|
-
unlinkSync as
|
|
35003
|
+
readdirSync as readdirSync3,
|
|
35004
|
+
unlinkSync as unlinkSync4
|
|
34191
35005
|
} from "fs";
|
|
34192
35006
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
34193
|
-
import { dirname as dirname3, join as
|
|
34194
|
-
import { homedir as
|
|
35007
|
+
import { dirname as dirname3, join as join13 } from "path";
|
|
35008
|
+
import { homedir as homedir12 } from "os";
|
|
34195
35009
|
function getVersion() {
|
|
34196
35010
|
return VERSION;
|
|
34197
35011
|
}
|
|
34198
35012
|
function clearAllModelCaches() {
|
|
34199
|
-
const cacheDir =
|
|
34200
|
-
if (!
|
|
35013
|
+
const cacheDir = join13(homedir12(), ".claudish");
|
|
35014
|
+
if (!existsSync13(cacheDir))
|
|
34201
35015
|
return;
|
|
34202
35016
|
const cachePatterns = ["all-models.json", "pricing-cache.json"];
|
|
34203
35017
|
let cleared = 0;
|
|
34204
35018
|
try {
|
|
34205
|
-
const files =
|
|
35019
|
+
const files = readdirSync3(cacheDir);
|
|
34206
35020
|
for (const file2 of files) {
|
|
34207
35021
|
if (cachePatterns.includes(file2) || file2.startsWith("litellm-models-")) {
|
|
34208
|
-
|
|
35022
|
+
unlinkSync4(join13(cacheDir, file2));
|
|
34209
35023
|
cleared++;
|
|
34210
35024
|
}
|
|
34211
35025
|
}
|
|
@@ -34229,6 +35043,7 @@ async function parseArgs(args) {
|
|
|
34229
35043
|
monitor: false,
|
|
34230
35044
|
stdin: false,
|
|
34231
35045
|
freeOnly: false,
|
|
35046
|
+
noLogs: false,
|
|
34232
35047
|
claudeArgs: []
|
|
34233
35048
|
};
|
|
34234
35049
|
const claudishModel = process.env[ENV.CLAUDISH_MODEL];
|
|
@@ -34395,6 +35210,8 @@ async function parseArgs(args) {
|
|
|
34395
35210
|
process.exit(0);
|
|
34396
35211
|
} else if (arg === "--summarize-tools") {
|
|
34397
35212
|
config3.summarizeTools = true;
|
|
35213
|
+
} else if (arg === "--no-logs") {
|
|
35214
|
+
config3.noLogs = true;
|
|
34398
35215
|
} else if (arg === "--") {
|
|
34399
35216
|
config3.claudeArgs.push(...args.slice(i + 1));
|
|
34400
35217
|
break;
|
|
@@ -34496,9 +35313,9 @@ async function fetchOllamaModels() {
|
|
|
34496
35313
|
}
|
|
34497
35314
|
async function searchAndPrintModels(query, forceUpdate) {
|
|
34498
35315
|
let models = [];
|
|
34499
|
-
if (!forceUpdate &&
|
|
35316
|
+
if (!forceUpdate && existsSync13(ALL_MODELS_JSON_PATH)) {
|
|
34500
35317
|
try {
|
|
34501
|
-
const cacheData = JSON.parse(
|
|
35318
|
+
const cacheData = JSON.parse(readFileSync11(ALL_MODELS_JSON_PATH, "utf-8"));
|
|
34502
35319
|
const lastUpdated = new Date(cacheData.lastUpdated);
|
|
34503
35320
|
const now = new Date;
|
|
34504
35321
|
const ageInDays = (now.getTime() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
|
|
@@ -34515,8 +35332,8 @@ async function searchAndPrintModels(query, forceUpdate) {
|
|
|
34515
35332
|
throw new Error(`API returned ${response.status}`);
|
|
34516
35333
|
const data = await response.json();
|
|
34517
35334
|
models = data.data;
|
|
34518
|
-
|
|
34519
|
-
|
|
35335
|
+
mkdirSync6(CLAUDISH_CACHE_DIR2, { recursive: true });
|
|
35336
|
+
writeFileSync6(ALL_MODELS_JSON_PATH, JSON.stringify({
|
|
34520
35337
|
lastUpdated: new Date().toISOString(),
|
|
34521
35338
|
models
|
|
34522
35339
|
}), "utf-8");
|
|
@@ -34666,9 +35483,9 @@ Found ${results.length} matching models:
|
|
|
34666
35483
|
async function printAllModels(jsonOutput, forceUpdate) {
|
|
34667
35484
|
let models = [];
|
|
34668
35485
|
const [ollamaModels, zenModels] = await Promise.all([fetchOllamaModels(), fetchZenModels()]);
|
|
34669
|
-
if (!forceUpdate &&
|
|
35486
|
+
if (!forceUpdate && existsSync13(ALL_MODELS_JSON_PATH)) {
|
|
34670
35487
|
try {
|
|
34671
|
-
const cacheData = JSON.parse(
|
|
35488
|
+
const cacheData = JSON.parse(readFileSync11(ALL_MODELS_JSON_PATH, "utf-8"));
|
|
34672
35489
|
const lastUpdated = new Date(cacheData.lastUpdated);
|
|
34673
35490
|
const now = new Date;
|
|
34674
35491
|
const ageInDays = (now.getTime() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
|
|
@@ -34688,8 +35505,8 @@ async function printAllModels(jsonOutput, forceUpdate) {
|
|
|
34688
35505
|
throw new Error(`API returned ${response.status}`);
|
|
34689
35506
|
const data = await response.json();
|
|
34690
35507
|
models = data.data;
|
|
34691
|
-
|
|
34692
|
-
|
|
35508
|
+
mkdirSync6(CLAUDISH_CACHE_DIR2, { recursive: true });
|
|
35509
|
+
writeFileSync6(ALL_MODELS_JSON_PATH, JSON.stringify({
|
|
34693
35510
|
lastUpdated: new Date().toISOString(),
|
|
34694
35511
|
models
|
|
34695
35512
|
}), "utf-8");
|
|
@@ -34869,12 +35686,12 @@ async function printAllModels(jsonOutput, forceUpdate) {
|
|
|
34869
35686
|
console.log("Top models: claudish --top-models");
|
|
34870
35687
|
}
|
|
34871
35688
|
function isCacheStale() {
|
|
34872
|
-
const cachePath =
|
|
34873
|
-
if (!
|
|
35689
|
+
const cachePath = existsSync13(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
|
|
35690
|
+
if (!existsSync13(cachePath)) {
|
|
34874
35691
|
return true;
|
|
34875
35692
|
}
|
|
34876
35693
|
try {
|
|
34877
|
-
const jsonContent =
|
|
35694
|
+
const jsonContent = readFileSync11(cachePath, "utf-8");
|
|
34878
35695
|
const data = JSON.parse(jsonContent);
|
|
34879
35696
|
if (!data.lastUpdated) {
|
|
34880
35697
|
return true;
|
|
@@ -34953,10 +35770,10 @@ async function updateModelsFromOpenRouter() {
|
|
|
34953
35770
|
providers.add(provider);
|
|
34954
35771
|
}
|
|
34955
35772
|
let version2 = "1.2.0";
|
|
34956
|
-
const existingPath =
|
|
34957
|
-
if (
|
|
35773
|
+
const existingPath = existsSync13(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
|
|
35774
|
+
if (existsSync13(existingPath)) {
|
|
34958
35775
|
try {
|
|
34959
|
-
const existing = JSON.parse(
|
|
35776
|
+
const existing = JSON.parse(readFileSync11(existingPath, "utf-8"));
|
|
34960
35777
|
version2 = existing.version || version2;
|
|
34961
35778
|
} catch {}
|
|
34962
35779
|
}
|
|
@@ -34966,8 +35783,8 @@ async function updateModelsFromOpenRouter() {
|
|
|
34966
35783
|
source: "https://openrouter.ai/models?categories=programming&fmt=cards&order=top-weekly",
|
|
34967
35784
|
models: recommendations
|
|
34968
35785
|
};
|
|
34969
|
-
|
|
34970
|
-
|
|
35786
|
+
mkdirSync6(CLAUDISH_CACHE_DIR2, { recursive: true });
|
|
35787
|
+
writeFileSync6(CACHED_MODELS_PATH, JSON.stringify(updatedData, null, 2), "utf-8");
|
|
34971
35788
|
console.error(`\u2705 Updated ${recommendations.length} models (last updated: ${updatedData.lastUpdated})`);
|
|
34972
35789
|
} catch (error46) {
|
|
34973
35790
|
console.error(`\u274C Failed to update models: ${error46 instanceof Error ? error46.message : String(error46)}`);
|
|
@@ -34985,8 +35802,8 @@ async function checkAndUpdateModelsCache(forceUpdate = false) {
|
|
|
34985
35802
|
await updateModelsFromOpenRouter();
|
|
34986
35803
|
} else {
|
|
34987
35804
|
try {
|
|
34988
|
-
const cachePath =
|
|
34989
|
-
const data = JSON.parse(
|
|
35805
|
+
const cachePath = existsSync13(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
|
|
35806
|
+
const data = JSON.parse(readFileSync11(cachePath, "utf-8"));
|
|
34990
35807
|
console.error(`\u2713 Using cached models (last updated: ${data.lastUpdated})`);
|
|
34991
35808
|
} catch {}
|
|
34992
35809
|
}
|
|
@@ -35293,6 +36110,7 @@ OPTIONS:
|
|
|
35293
36110
|
-p, --profile <name> Use named profile for model mapping (default: uses default profile)
|
|
35294
36111
|
--port <port> Proxy server port (default: random)
|
|
35295
36112
|
-d, --debug Enable debug logging to file (logs/claudish_*.log)
|
|
36113
|
+
--no-logs Disable always-on structural logging (~/.claudish/logs/)
|
|
35296
36114
|
--log-level <level> Log verbosity: debug (full), info (truncated), minimal (labels only)
|
|
35297
36115
|
-q, --quiet Suppress [claudish] log messages (default in single-shot mode)
|
|
35298
36116
|
-v, --verbose Show [claudish] log messages (default in interactive mode)
|
|
@@ -35544,8 +36362,8 @@ MORE INFO:
|
|
|
35544
36362
|
}
|
|
35545
36363
|
function printAIAgentGuide() {
|
|
35546
36364
|
try {
|
|
35547
|
-
const guidePath =
|
|
35548
|
-
const guideContent =
|
|
36365
|
+
const guidePath = join13(__dirname4, "../AI_AGENT_GUIDE.md");
|
|
36366
|
+
const guideContent = readFileSync11(guidePath, "utf-8");
|
|
35549
36367
|
console.log(guideContent);
|
|
35550
36368
|
} catch (error46) {
|
|
35551
36369
|
console.error("Error reading AI Agent Guide:");
|
|
@@ -35561,19 +36379,19 @@ async function initializeClaudishSkill() {
|
|
|
35561
36379
|
console.log(`\uD83D\uDD27 Initializing Claudish skill in current project...
|
|
35562
36380
|
`);
|
|
35563
36381
|
const cwd = process.cwd();
|
|
35564
|
-
const claudeDir =
|
|
35565
|
-
const skillsDir =
|
|
35566
|
-
const claudishSkillDir =
|
|
35567
|
-
const skillFile =
|
|
35568
|
-
if (
|
|
36382
|
+
const claudeDir = join13(cwd, ".claude");
|
|
36383
|
+
const skillsDir = join13(claudeDir, "skills");
|
|
36384
|
+
const claudishSkillDir = join13(skillsDir, "claudish-usage");
|
|
36385
|
+
const skillFile = join13(claudishSkillDir, "SKILL.md");
|
|
36386
|
+
if (existsSync13(skillFile)) {
|
|
35569
36387
|
console.log("\u2705 Claudish skill already installed at:");
|
|
35570
36388
|
console.log(` ${skillFile}
|
|
35571
36389
|
`);
|
|
35572
36390
|
console.log("\uD83D\uDCA1 To reinstall, delete the file and run 'claudish --init' again.");
|
|
35573
36391
|
return;
|
|
35574
36392
|
}
|
|
35575
|
-
const sourceSkillPath =
|
|
35576
|
-
if (!
|
|
36393
|
+
const sourceSkillPath = join13(__dirname4, "../skills/claudish-usage/SKILL.md");
|
|
36394
|
+
if (!existsSync13(sourceSkillPath)) {
|
|
35577
36395
|
console.error("\u274C Error: Claudish skill file not found in installation.");
|
|
35578
36396
|
console.error(` Expected at: ${sourceSkillPath}`);
|
|
35579
36397
|
console.error(`
|
|
@@ -35582,16 +36400,16 @@ async function initializeClaudishSkill() {
|
|
|
35582
36400
|
process.exit(1);
|
|
35583
36401
|
}
|
|
35584
36402
|
try {
|
|
35585
|
-
if (!
|
|
35586
|
-
|
|
36403
|
+
if (!existsSync13(claudeDir)) {
|
|
36404
|
+
mkdirSync6(claudeDir, { recursive: true });
|
|
35587
36405
|
console.log("\uD83D\uDCC1 Created .claude/ directory");
|
|
35588
36406
|
}
|
|
35589
|
-
if (!
|
|
35590
|
-
|
|
36407
|
+
if (!existsSync13(skillsDir)) {
|
|
36408
|
+
mkdirSync6(skillsDir, { recursive: true });
|
|
35591
36409
|
console.log("\uD83D\uDCC1 Created .claude/skills/ directory");
|
|
35592
36410
|
}
|
|
35593
|
-
if (!
|
|
35594
|
-
|
|
36411
|
+
if (!existsSync13(claudishSkillDir)) {
|
|
36412
|
+
mkdirSync6(claudishSkillDir, { recursive: true });
|
|
35595
36413
|
console.log("\uD83D\uDCC1 Created .claude/skills/claudish-usage/ directory");
|
|
35596
36414
|
}
|
|
35597
36415
|
copyFileSync(sourceSkillPath, skillFile);
|
|
@@ -35633,9 +36451,9 @@ function printAvailableModels() {
|
|
|
35633
36451
|
let lastUpdated = "unknown";
|
|
35634
36452
|
let models = [];
|
|
35635
36453
|
try {
|
|
35636
|
-
const cachePath =
|
|
35637
|
-
if (
|
|
35638
|
-
const data = JSON.parse(
|
|
36454
|
+
const cachePath = existsSync13(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
|
|
36455
|
+
if (existsSync13(cachePath)) {
|
|
36456
|
+
const data = JSON.parse(readFileSync11(cachePath, "utf-8"));
|
|
35639
36457
|
lastUpdated = data.lastUpdated || "unknown";
|
|
35640
36458
|
models = data.models || [];
|
|
35641
36459
|
}
|
|
@@ -35684,9 +36502,9 @@ Force update: claudish --list-models --force-update
|
|
|
35684
36502
|
`);
|
|
35685
36503
|
}
|
|
35686
36504
|
function printAvailableModelsJSON() {
|
|
35687
|
-
const jsonPath =
|
|
36505
|
+
const jsonPath = existsSync13(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
|
|
35688
36506
|
try {
|
|
35689
|
-
const jsonContent =
|
|
36507
|
+
const jsonContent = readFileSync11(jsonPath, "utf-8");
|
|
35690
36508
|
const data = JSON.parse(jsonContent);
|
|
35691
36509
|
console.log(JSON.stringify(data, null, 2));
|
|
35692
36510
|
} catch (error46) {
|
|
@@ -35771,7 +36589,7 @@ async function fetchGLMCodingModels() {
|
|
|
35771
36589
|
return [];
|
|
35772
36590
|
}
|
|
35773
36591
|
}
|
|
35774
|
-
var __filename4, __dirname4, VERSION = "5.
|
|
36592
|
+
var __filename4, __dirname4, VERSION = "5.16.0", CACHE_MAX_AGE_DAYS2 = 2, CLAUDISH_CACHE_DIR2, BUNDLED_MODELS_PATH, CACHED_MODELS_PATH, ALL_MODELS_JSON_PATH;
|
|
35775
36593
|
var init_cli = __esm(() => {
|
|
35776
36594
|
init_config();
|
|
35777
36595
|
init_model_loader();
|
|
@@ -35783,13 +36601,13 @@ var init_cli = __esm(() => {
|
|
|
35783
36601
|
__filename4 = fileURLToPath3(import.meta.url);
|
|
35784
36602
|
__dirname4 = dirname3(__filename4);
|
|
35785
36603
|
try {
|
|
35786
|
-
const packageJson = JSON.parse(
|
|
36604
|
+
const packageJson = JSON.parse(readFileSync11(join13(__dirname4, "../package.json"), "utf-8"));
|
|
35787
36605
|
VERSION = packageJson.version;
|
|
35788
36606
|
} catch {}
|
|
35789
|
-
CLAUDISH_CACHE_DIR2 =
|
|
35790
|
-
BUNDLED_MODELS_PATH =
|
|
35791
|
-
CACHED_MODELS_PATH =
|
|
35792
|
-
ALL_MODELS_JSON_PATH =
|
|
36607
|
+
CLAUDISH_CACHE_DIR2 = join13(homedir12(), ".claudish");
|
|
36608
|
+
BUNDLED_MODELS_PATH = join13(__dirname4, "../recommended-models.json");
|
|
36609
|
+
CACHED_MODELS_PATH = join13(CLAUDISH_CACHE_DIR2, "recommended-models.json");
|
|
36610
|
+
ALL_MODELS_JSON_PATH = join13(CLAUDISH_CACHE_DIR2, "all-models.json");
|
|
35793
36611
|
});
|
|
35794
36612
|
|
|
35795
36613
|
// src/update-checker.ts
|
|
@@ -35801,9 +36619,9 @@ __export(exports_update_checker, {
|
|
|
35801
36619
|
checkForUpdates: () => checkForUpdates
|
|
35802
36620
|
});
|
|
35803
36621
|
import { execSync } from "child_process";
|
|
35804
|
-
import { existsSync as
|
|
35805
|
-
import { homedir as
|
|
35806
|
-
import { join as
|
|
36622
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync7, readFileSync as readFileSync12, unlinkSync as unlinkSync5, writeFileSync as writeFileSync7 } from "fs";
|
|
36623
|
+
import { homedir as homedir13, platform as platform2, tmpdir } from "os";
|
|
36624
|
+
import { join as join14 } from "path";
|
|
35807
36625
|
import { createInterface } from "readline";
|
|
35808
36626
|
function getUpdateCommand() {
|
|
35809
36627
|
const scriptPath = process.argv[1] || "";
|
|
@@ -35815,27 +36633,27 @@ function getUpdateCommand() {
|
|
|
35815
36633
|
function getCacheFilePath() {
|
|
35816
36634
|
let cacheDir;
|
|
35817
36635
|
if (isWindows) {
|
|
35818
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
35819
|
-
cacheDir =
|
|
36636
|
+
const localAppData = process.env.LOCALAPPDATA || join14(homedir13(), "AppData", "Local");
|
|
36637
|
+
cacheDir = join14(localAppData, "claudish");
|
|
35820
36638
|
} else {
|
|
35821
|
-
cacheDir =
|
|
36639
|
+
cacheDir = join14(homedir13(), ".cache", "claudish");
|
|
35822
36640
|
}
|
|
35823
36641
|
try {
|
|
35824
|
-
if (!
|
|
35825
|
-
|
|
36642
|
+
if (!existsSync14(cacheDir)) {
|
|
36643
|
+
mkdirSync7(cacheDir, { recursive: true });
|
|
35826
36644
|
}
|
|
35827
|
-
return
|
|
36645
|
+
return join14(cacheDir, "update-check.json");
|
|
35828
36646
|
} catch {
|
|
35829
|
-
return
|
|
36647
|
+
return join14(tmpdir(), "claudish-update-check.json");
|
|
35830
36648
|
}
|
|
35831
36649
|
}
|
|
35832
36650
|
function readCache() {
|
|
35833
36651
|
try {
|
|
35834
36652
|
const cachePath = getCacheFilePath();
|
|
35835
|
-
if (!
|
|
36653
|
+
if (!existsSync14(cachePath)) {
|
|
35836
36654
|
return null;
|
|
35837
36655
|
}
|
|
35838
|
-
const data = JSON.parse(
|
|
36656
|
+
const data = JSON.parse(readFileSync12(cachePath, "utf-8"));
|
|
35839
36657
|
return data;
|
|
35840
36658
|
} catch {
|
|
35841
36659
|
return null;
|
|
@@ -35848,7 +36666,7 @@ function writeCache(latestVersion) {
|
|
|
35848
36666
|
lastCheck: Date.now(),
|
|
35849
36667
|
latestVersion
|
|
35850
36668
|
};
|
|
35851
|
-
|
|
36669
|
+
writeFileSync7(cachePath, JSON.stringify(data), "utf-8");
|
|
35852
36670
|
} catch {}
|
|
35853
36671
|
}
|
|
35854
36672
|
function isCacheValid(cache) {
|
|
@@ -35858,8 +36676,8 @@ function isCacheValid(cache) {
|
|
|
35858
36676
|
function clearCache() {
|
|
35859
36677
|
try {
|
|
35860
36678
|
const cachePath = getCacheFilePath();
|
|
35861
|
-
if (
|
|
35862
|
-
|
|
36679
|
+
if (existsSync14(cachePath)) {
|
|
36680
|
+
unlinkSync5(cachePath);
|
|
35863
36681
|
}
|
|
35864
36682
|
} catch {}
|
|
35865
36683
|
}
|
|
@@ -35895,7 +36713,7 @@ async function fetchLatestVersion() {
|
|
|
35895
36713
|
}
|
|
35896
36714
|
}
|
|
35897
36715
|
function promptUser(question) {
|
|
35898
|
-
return new Promise((
|
|
36716
|
+
return new Promise((resolve2) => {
|
|
35899
36717
|
const rl = createInterface({
|
|
35900
36718
|
input: process.stdin,
|
|
35901
36719
|
output: process.stderr
|
|
@@ -35903,7 +36721,7 @@ function promptUser(question) {
|
|
|
35903
36721
|
rl.question(question, (answer) => {
|
|
35904
36722
|
rl.close();
|
|
35905
36723
|
const normalized = answer.toLowerCase().trim();
|
|
35906
|
-
|
|
36724
|
+
resolve2(normalized === "y" || normalized === "yes");
|
|
35907
36725
|
});
|
|
35908
36726
|
});
|
|
35909
36727
|
}
|
|
@@ -36014,7 +36832,7 @@ function getUpdateCommand2(method) {
|
|
|
36014
36832
|
}
|
|
36015
36833
|
}
|
|
36016
36834
|
function promptUser2(question) {
|
|
36017
|
-
return new Promise((
|
|
36835
|
+
return new Promise((resolve2) => {
|
|
36018
36836
|
const rl = createInterface2({
|
|
36019
36837
|
input: process.stdin,
|
|
36020
36838
|
output: process.stdout
|
|
@@ -36022,7 +36840,7 @@ function promptUser2(question) {
|
|
|
36022
36840
|
rl.question(question, (answer) => {
|
|
36023
36841
|
rl.close();
|
|
36024
36842
|
const normalized = answer.toLowerCase().trim();
|
|
36025
|
-
|
|
36843
|
+
resolve2(normalized === "y" || normalized === "yes" || normalized === "");
|
|
36026
36844
|
});
|
|
36027
36845
|
});
|
|
36028
36846
|
}
|
|
@@ -37708,13 +38526,13 @@ var PromisePolyfill;
|
|
|
37708
38526
|
var init_promise_polyfill = __esm(() => {
|
|
37709
38527
|
PromisePolyfill = class PromisePolyfill extends Promise {
|
|
37710
38528
|
static withResolver() {
|
|
37711
|
-
let
|
|
38529
|
+
let resolve2;
|
|
37712
38530
|
let reject;
|
|
37713
38531
|
const promise3 = new Promise((res, rej) => {
|
|
37714
|
-
|
|
38532
|
+
resolve2 = res;
|
|
37715
38533
|
reject = rej;
|
|
37716
38534
|
});
|
|
37717
|
-
return { promise: promise3, resolve, reject };
|
|
38535
|
+
return { promise: promise3, resolve: resolve2, reject };
|
|
37718
38536
|
}
|
|
37719
38537
|
};
|
|
37720
38538
|
});
|
|
@@ -37751,7 +38569,7 @@ function createPrompt(view) {
|
|
|
37751
38569
|
output
|
|
37752
38570
|
});
|
|
37753
38571
|
const screen = new ScreenManager(rl);
|
|
37754
|
-
const { promise: promise3, resolve, reject } = PromisePolyfill.withResolver();
|
|
38572
|
+
const { promise: promise3, resolve: resolve2, reject } = PromisePolyfill.withResolver();
|
|
37755
38573
|
const cancel = () => reject(new CancelPromptError);
|
|
37756
38574
|
if (signal) {
|
|
37757
38575
|
const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
|
|
@@ -37778,7 +38596,7 @@ function createPrompt(view) {
|
|
|
37778
38596
|
cycle(() => {
|
|
37779
38597
|
try {
|
|
37780
38598
|
const nextView = view(config3, (value) => {
|
|
37781
|
-
setImmediate(() =>
|
|
38599
|
+
setImmediate(() => resolve2(value));
|
|
37782
38600
|
});
|
|
37783
38601
|
if (nextView === undefined) {
|
|
37784
38602
|
const callerFilename = callSites[1]?.getFileName();
|
|
@@ -38339,14 +39157,14 @@ __export(exports_model_selector, {
|
|
|
38339
39157
|
promptForApiKey: () => promptForApiKey,
|
|
38340
39158
|
confirmAction: () => confirmAction
|
|
38341
39159
|
});
|
|
38342
|
-
import { readFileSync as
|
|
38343
|
-
import { join as
|
|
38344
|
-
import { homedir as
|
|
39160
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync8, existsSync as existsSync15, mkdirSync as mkdirSync8 } from "fs";
|
|
39161
|
+
import { join as join15, dirname as dirname4 } from "path";
|
|
39162
|
+
import { homedir as homedir14 } from "os";
|
|
38345
39163
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
38346
39164
|
function loadRecommendedModels2() {
|
|
38347
|
-
if (
|
|
39165
|
+
if (existsSync15(RECOMMENDED_MODELS_JSON_PATH)) {
|
|
38348
39166
|
try {
|
|
38349
|
-
const content =
|
|
39167
|
+
const content = readFileSync13(RECOMMENDED_MODELS_JSON_PATH, "utf-8");
|
|
38350
39168
|
const data = JSON.parse(content);
|
|
38351
39169
|
return (data.models || []).map((model) => ({
|
|
38352
39170
|
...model,
|
|
@@ -38359,9 +39177,9 @@ function loadRecommendedModels2() {
|
|
|
38359
39177
|
return [];
|
|
38360
39178
|
}
|
|
38361
39179
|
async function fetchAllModels(forceUpdate = false) {
|
|
38362
|
-
if (!forceUpdate &&
|
|
39180
|
+
if (!forceUpdate && existsSync15(ALL_MODELS_JSON_PATH2)) {
|
|
38363
39181
|
try {
|
|
38364
|
-
const cacheData = JSON.parse(
|
|
39182
|
+
const cacheData = JSON.parse(readFileSync13(ALL_MODELS_JSON_PATH2, "utf-8"));
|
|
38365
39183
|
const lastUpdated = new Date(cacheData.lastUpdated);
|
|
38366
39184
|
const now = new Date;
|
|
38367
39185
|
const ageInDays = (now.getTime() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
|
|
@@ -38377,8 +39195,8 @@ async function fetchAllModels(forceUpdate = false) {
|
|
|
38377
39195
|
throw new Error(`API returned ${response.status}`);
|
|
38378
39196
|
const data = await response.json();
|
|
38379
39197
|
const models = data.data;
|
|
38380
|
-
|
|
38381
|
-
|
|
39198
|
+
mkdirSync8(CLAUDISH_CACHE_DIR3, { recursive: true });
|
|
39199
|
+
writeFileSync8(ALL_MODELS_JSON_PATH2, JSON.stringify({
|
|
38382
39200
|
lastUpdated: new Date().toISOString(),
|
|
38383
39201
|
models
|
|
38384
39202
|
}), "utf-8");
|
|
@@ -38863,11 +39681,11 @@ async function fetchOllamaCloudModels() {
|
|
|
38863
39681
|
}
|
|
38864
39682
|
}
|
|
38865
39683
|
function shouldRefreshForFreeModels() {
|
|
38866
|
-
if (!
|
|
39684
|
+
if (!existsSync15(ALL_MODELS_JSON_PATH2)) {
|
|
38867
39685
|
return true;
|
|
38868
39686
|
}
|
|
38869
39687
|
try {
|
|
38870
|
-
const cacheData = JSON.parse(
|
|
39688
|
+
const cacheData = JSON.parse(readFileSync13(ALL_MODELS_JSON_PATH2, "utf-8"));
|
|
38871
39689
|
const lastUpdated = new Date(cacheData.lastUpdated);
|
|
38872
39690
|
const now = new Date;
|
|
38873
39691
|
const ageInHours = (now.getTime() - lastUpdated.getTime()) / (1000 * 60 * 60);
|
|
@@ -39468,9 +40286,9 @@ var init_model_selector = __esm(() => {
|
|
|
39468
40286
|
init_model_loader();
|
|
39469
40287
|
__filename5 = fileURLToPath4(import.meta.url);
|
|
39470
40288
|
__dirname5 = dirname4(__filename5);
|
|
39471
|
-
CLAUDISH_CACHE_DIR3 =
|
|
39472
|
-
ALL_MODELS_JSON_PATH2 =
|
|
39473
|
-
RECOMMENDED_MODELS_JSON_PATH =
|
|
40289
|
+
CLAUDISH_CACHE_DIR3 = join15(homedir14(), ".claudish");
|
|
40290
|
+
ALL_MODELS_JSON_PATH2 = join15(CLAUDISH_CACHE_DIR3, "all-models.json");
|
|
40291
|
+
RECOMMENDED_MODELS_JSON_PATH = join15(__dirname5, "../recommended-models.json");
|
|
39474
40292
|
PROVIDER_FILTER_ALIASES = {
|
|
39475
40293
|
zen: "Zen",
|
|
39476
40294
|
openrouter: "OpenRouter",
|
|
@@ -40328,11 +41146,11 @@ async function runConsentPrompt(ctx) {
|
|
|
40328
41146
|
Does NOT send: prompts, paths, API keys, or credentials.
|
|
40329
41147
|
Disable anytime: claudish telemetry off
|
|
40330
41148
|
`);
|
|
40331
|
-
const answer = await new Promise((
|
|
41149
|
+
const answer = await new Promise((resolve2) => {
|
|
40332
41150
|
const rl = createInterface4({ input: process.stdin, output: process.stderr });
|
|
40333
41151
|
rl.question("Send anonymous error report? [y/N] ", (ans) => {
|
|
40334
41152
|
rl.close();
|
|
40335
|
-
|
|
41153
|
+
resolve2(ans.trim().toLowerCase());
|
|
40336
41154
|
});
|
|
40337
41155
|
});
|
|
40338
41156
|
const accepted = answer === "y" || answer === "yes";
|
|
@@ -40516,25 +41334,25 @@ var init_telemetry = __esm(() => {
|
|
|
40516
41334
|
|
|
40517
41335
|
// src/stats-buffer.ts
|
|
40518
41336
|
import {
|
|
40519
|
-
existsSync as
|
|
40520
|
-
mkdirSync as
|
|
40521
|
-
readFileSync as
|
|
41337
|
+
existsSync as existsSync16,
|
|
41338
|
+
mkdirSync as mkdirSync9,
|
|
41339
|
+
readFileSync as readFileSync14,
|
|
40522
41340
|
renameSync,
|
|
40523
|
-
unlinkSync as
|
|
40524
|
-
writeFileSync as
|
|
41341
|
+
unlinkSync as unlinkSync6,
|
|
41342
|
+
writeFileSync as writeFileSync9
|
|
40525
41343
|
} from "fs";
|
|
40526
|
-
import { homedir as
|
|
40527
|
-
import { join as
|
|
41344
|
+
import { homedir as homedir15 } from "os";
|
|
41345
|
+
import { join as join16 } from "path";
|
|
40528
41346
|
function ensureDir() {
|
|
40529
|
-
if (!
|
|
40530
|
-
|
|
41347
|
+
if (!existsSync16(CLAUDISH_DIR)) {
|
|
41348
|
+
mkdirSync9(CLAUDISH_DIR, { recursive: true });
|
|
40531
41349
|
}
|
|
40532
41350
|
}
|
|
40533
41351
|
function readFromDisk() {
|
|
40534
41352
|
try {
|
|
40535
|
-
if (!
|
|
41353
|
+
if (!existsSync16(BUFFER_FILE))
|
|
40536
41354
|
return [];
|
|
40537
|
-
const raw =
|
|
41355
|
+
const raw = readFileSync14(BUFFER_FILE, "utf-8");
|
|
40538
41356
|
const parsed = JSON.parse(raw);
|
|
40539
41357
|
if (!Array.isArray(parsed.events))
|
|
40540
41358
|
return [];
|
|
@@ -40558,8 +41376,8 @@ function writeToDisk(events) {
|
|
|
40558
41376
|
ensureDir();
|
|
40559
41377
|
const trimmed = enforceSizeCap([...events]);
|
|
40560
41378
|
const payload = { version: 1, events: trimmed };
|
|
40561
|
-
const tmpFile =
|
|
40562
|
-
|
|
41379
|
+
const tmpFile = join16(CLAUDISH_DIR, `stats-buffer.tmp.${process.pid}.json`);
|
|
41380
|
+
writeFileSync9(tmpFile, JSON.stringify(payload, null, 2), "utf-8");
|
|
40563
41381
|
renameSync(tmpFile, BUFFER_FILE);
|
|
40564
41382
|
memoryCache = trimmed;
|
|
40565
41383
|
} catch {}
|
|
@@ -40603,8 +41421,8 @@ function clearBuffer() {
|
|
|
40603
41421
|
try {
|
|
40604
41422
|
memoryCache = [];
|
|
40605
41423
|
eventsSinceLastFlush = 0;
|
|
40606
|
-
if (
|
|
40607
|
-
|
|
41424
|
+
if (existsSync16(BUFFER_FILE)) {
|
|
41425
|
+
unlinkSync6(BUFFER_FILE);
|
|
40608
41426
|
}
|
|
40609
41427
|
} catch {}
|
|
40610
41428
|
}
|
|
@@ -40632,8 +41450,8 @@ function syncFlushOnExit() {
|
|
|
40632
41450
|
var BUFFER_MAX_BYTES, CLAUDISH_DIR, BUFFER_FILE, memoryCache = null, eventsSinceLastFlush = 0, lastFlushTime, flushScheduled = false;
|
|
40633
41451
|
var init_stats_buffer = __esm(() => {
|
|
40634
41452
|
BUFFER_MAX_BYTES = 64 * 1024;
|
|
40635
|
-
CLAUDISH_DIR =
|
|
40636
|
-
BUFFER_FILE =
|
|
41453
|
+
CLAUDISH_DIR = join16(homedir15(), ".claudish");
|
|
41454
|
+
BUFFER_FILE = join16(CLAUDISH_DIR, "stats-buffer.json");
|
|
40637
41455
|
lastFlushTime = Date.now();
|
|
40638
41456
|
process.on("exit", syncFlushOnExit);
|
|
40639
41457
|
process.on("SIGTERM", () => {
|
|
@@ -41118,16 +41936,16 @@ import { EventEmitter } from "events";
|
|
|
41118
41936
|
import { Buffer as Buffer2 } from "buffer";
|
|
41119
41937
|
import { Buffer as Buffer3 } from "buffer";
|
|
41120
41938
|
import { EventEmitter as EventEmitter2 } from "events";
|
|
41121
|
-
import { resolve, dirname as dirname5 } from "path";
|
|
41939
|
+
import { resolve as resolve2, dirname as dirname5 } from "path";
|
|
41122
41940
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
41123
|
-
import { resolve as
|
|
41124
|
-
import { existsSync as
|
|
41125
|
-
import { basename, join as
|
|
41941
|
+
import { resolve as resolve22, isAbsolute, parse as parse6 } from "path";
|
|
41942
|
+
import { existsSync as existsSync17 } from "fs";
|
|
41943
|
+
import { basename, join as join17 } from "path";
|
|
41126
41944
|
import os from "os";
|
|
41127
41945
|
import path from "path";
|
|
41128
41946
|
import { EventEmitter as EventEmitter3 } from "events";
|
|
41129
41947
|
import { dlopen, toArrayBuffer as toArrayBuffer4, JSCallback, ptr as ptr4 } from "bun:ffi";
|
|
41130
|
-
import { existsSync as existsSync22, writeFileSync as
|
|
41948
|
+
import { existsSync as existsSync22, writeFileSync as writeFileSync10 } from "fs";
|
|
41131
41949
|
import { EventEmitter as EventEmitter4 } from "events";
|
|
41132
41950
|
import { toArrayBuffer, ptr } from "bun:ffi";
|
|
41133
41951
|
import { ptr as ptr2, toArrayBuffer as toArrayBuffer2 } from "bun:ffi";
|
|
@@ -43463,24 +44281,24 @@ function getParsers() {
|
|
|
43463
44281
|
{
|
|
43464
44282
|
filetype: "javascript",
|
|
43465
44283
|
queries: {
|
|
43466
|
-
highlights: [
|
|
44284
|
+
highlights: [resolve2(dirname5(fileURLToPath5(import.meta.url)), highlights_default)]
|
|
43467
44285
|
},
|
|
43468
|
-
wasm:
|
|
44286
|
+
wasm: resolve2(dirname5(fileURLToPath5(import.meta.url)), tree_sitter_javascript_default)
|
|
43469
44287
|
},
|
|
43470
44288
|
{
|
|
43471
44289
|
filetype: "typescript",
|
|
43472
44290
|
queries: {
|
|
43473
|
-
highlights: [
|
|
44291
|
+
highlights: [resolve2(dirname5(fileURLToPath5(import.meta.url)), highlights_default2)]
|
|
43474
44292
|
},
|
|
43475
|
-
wasm:
|
|
44293
|
+
wasm: resolve2(dirname5(fileURLToPath5(import.meta.url)), tree_sitter_typescript_default)
|
|
43476
44294
|
},
|
|
43477
44295
|
{
|
|
43478
44296
|
filetype: "markdown",
|
|
43479
44297
|
queries: {
|
|
43480
|
-
highlights: [
|
|
43481
|
-
injections: [
|
|
44298
|
+
highlights: [resolve2(dirname5(fileURLToPath5(import.meta.url)), highlights_default3)],
|
|
44299
|
+
injections: [resolve2(dirname5(fileURLToPath5(import.meta.url)), injections_default)]
|
|
43482
44300
|
},
|
|
43483
|
-
wasm:
|
|
44301
|
+
wasm: resolve2(dirname5(fileURLToPath5(import.meta.url)), tree_sitter_markdown_default),
|
|
43484
44302
|
injectionMapping: {
|
|
43485
44303
|
nodeTypes: {
|
|
43486
44304
|
inline: "markdown_inline",
|
|
@@ -43499,16 +44317,16 @@ function getParsers() {
|
|
|
43499
44317
|
{
|
|
43500
44318
|
filetype: "markdown_inline",
|
|
43501
44319
|
queries: {
|
|
43502
|
-
highlights: [
|
|
44320
|
+
highlights: [resolve2(dirname5(fileURLToPath5(import.meta.url)), highlights_default4)]
|
|
43503
44321
|
},
|
|
43504
|
-
wasm:
|
|
44322
|
+
wasm: resolve2(dirname5(fileURLToPath5(import.meta.url)), tree_sitter_markdown_inline_default)
|
|
43505
44323
|
},
|
|
43506
44324
|
{
|
|
43507
44325
|
filetype: "zig",
|
|
43508
44326
|
queries: {
|
|
43509
|
-
highlights: [
|
|
44327
|
+
highlights: [resolve2(dirname5(fileURLToPath5(import.meta.url)), highlights_default5)]
|
|
43510
44328
|
},
|
|
43511
|
-
wasm:
|
|
44329
|
+
wasm: resolve2(dirname5(fileURLToPath5(import.meta.url)), tree_sitter_zig_default)
|
|
43512
44330
|
}
|
|
43513
44331
|
];
|
|
43514
44332
|
}
|
|
@@ -43521,7 +44339,7 @@ function getBunfsRootPath() {
|
|
|
43521
44339
|
return process.platform === "win32" ? "B:\\~BUN\\root" : "/$bunfs/root";
|
|
43522
44340
|
}
|
|
43523
44341
|
function normalizeBunfsPath(fileName) {
|
|
43524
|
-
return
|
|
44342
|
+
return join17(getBunfsRootPath(), basename(fileName));
|
|
43525
44343
|
}
|
|
43526
44344
|
function isValidDirectoryName(name) {
|
|
43527
44345
|
if (!name || typeof name !== "string") {
|
|
@@ -46473,7 +47291,7 @@ function convertToDebugSymbols(symbols) {
|
|
|
46473
47291
|
if (env.OTUI_DEBUG_FFI && globalFFILogPath) {
|
|
46474
47292
|
const logPath = globalFFILogPath;
|
|
46475
47293
|
const writeSync3 = (msg) => {
|
|
46476
|
-
|
|
47294
|
+
writeFileSync10(logPath, msg + `
|
|
46477
47295
|
`, { flag: "a" });
|
|
46478
47296
|
};
|
|
46479
47297
|
Object.entries(symbols).forEach(([key, value]) => {
|
|
@@ -53717,7 +54535,7 @@ var init_index_0wbvecnk = __esm(async () => {
|
|
|
53717
54535
|
worker_path = this.options.workerPath;
|
|
53718
54536
|
} else {
|
|
53719
54537
|
worker_path = new URL("./parser.worker.js", import.meta.url).href;
|
|
53720
|
-
if (!
|
|
54538
|
+
if (!existsSync17(resolve22(import.meta.dirname, "parser.worker.js"))) {
|
|
53721
54539
|
worker_path = new URL("./parser.worker.ts", import.meta.url).href;
|
|
53722
54540
|
}
|
|
53723
54541
|
}
|
|
@@ -53783,7 +54601,7 @@ var init_index_0wbvecnk = __esm(async () => {
|
|
|
53783
54601
|
return normalizeBunfsPath(parse6(path2).base);
|
|
53784
54602
|
}
|
|
53785
54603
|
if (!isAbsolute(path2)) {
|
|
53786
|
-
return
|
|
54604
|
+
return resolve22(path2);
|
|
53787
54605
|
}
|
|
53788
54606
|
return path2;
|
|
53789
54607
|
}
|
|
@@ -82869,9 +83687,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
82869
83687
|
}
|
|
82870
83688
|
function getWrappedDisplayName(outerType, innerType, wrapperName, fallbackName) {
|
|
82871
83689
|
var displayName = outerType === null || outerType === undefined ? undefined : outerType.displayName;
|
|
82872
|
-
return displayName || "".concat(wrapperName, "(").concat(
|
|
83690
|
+
return displayName || "".concat(wrapperName, "(").concat(getDisplayName2(innerType, fallbackName), ")");
|
|
82873
83691
|
}
|
|
82874
|
-
function
|
|
83692
|
+
function getDisplayName2(type) {
|
|
82875
83693
|
var fallbackName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "Anonymous";
|
|
82876
83694
|
var nameFromCache = cachedDisplayNames.get(type);
|
|
82877
83695
|
if (nameFromCache != null) {
|
|
@@ -83414,7 +84232,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
83414
84232
|
if (typeof type === "string") {
|
|
83415
84233
|
return type;
|
|
83416
84234
|
} else if (typeof type === "function") {
|
|
83417
|
-
return
|
|
84235
|
+
return getDisplayName2(type, "Anonymous");
|
|
83418
84236
|
} else if (type != null) {
|
|
83419
84237
|
return "NotImplementedInDevtools";
|
|
83420
84238
|
} else {
|
|
@@ -89342,7 +90160,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
89342
90160
|
case IncompleteFunctionComponent:
|
|
89343
90161
|
case FunctionComponent:
|
|
89344
90162
|
case IndeterminateComponent:
|
|
89345
|
-
return
|
|
90163
|
+
return getDisplayName2(resolvedType);
|
|
89346
90164
|
case ForwardRef:
|
|
89347
90165
|
return getWrappedDisplayName(elementType, resolvedType, "ForwardRef", "Anonymous");
|
|
89348
90166
|
case HostRoot:
|
|
@@ -94297,7 +95115,7 @@ The error thrown in the component is:
|
|
|
94297
95115
|
if (typeof elementType === "string") {
|
|
94298
95116
|
displayName = elementType;
|
|
94299
95117
|
} else if (typeof elementType === "function") {
|
|
94300
|
-
displayName =
|
|
95118
|
+
displayName = getDisplayName2(elementType);
|
|
94301
95119
|
}
|
|
94302
95120
|
}
|
|
94303
95121
|
return {
|
|
@@ -98429,24 +99247,163 @@ var init_tui = __esm(async () => {
|
|
|
98429
99247
|
}
|
|
98430
99248
|
});
|
|
98431
99249
|
|
|
99250
|
+
// src/team-cli.ts
|
|
99251
|
+
var exports_team_cli = {};
|
|
99252
|
+
__export(exports_team_cli, {
|
|
99253
|
+
teamCommand: () => teamCommand
|
|
99254
|
+
});
|
|
99255
|
+
import { readFileSync as readFileSync15 } from "fs";
|
|
99256
|
+
import { join as join18 } from "path";
|
|
99257
|
+
function getFlag(args, flag) {
|
|
99258
|
+
const idx = args.indexOf(flag);
|
|
99259
|
+
if (idx === -1 || idx + 1 >= args.length)
|
|
99260
|
+
return;
|
|
99261
|
+
return args[idx + 1];
|
|
99262
|
+
}
|
|
99263
|
+
function hasFlag(args, flag) {
|
|
99264
|
+
return args.includes(flag);
|
|
99265
|
+
}
|
|
99266
|
+
function printStatus(status) {
|
|
99267
|
+
const modelIds = Object.keys(status.models).sort();
|
|
99268
|
+
console.log(`
|
|
99269
|
+
Team Status (started: ${status.startedAt})`);
|
|
99270
|
+
console.log("\u2500".repeat(60));
|
|
99271
|
+
for (const id of modelIds) {
|
|
99272
|
+
const m2 = status.models[id];
|
|
99273
|
+
const duration3 = m2.startedAt && m2.completedAt ? `${Math.round((new Date(m2.completedAt).getTime() - new Date(m2.startedAt).getTime()) / 1000)}s` : m2.startedAt ? "running" : "pending";
|
|
99274
|
+
const size = m2.outputSize > 0 ? ` (${m2.outputSize} bytes)` : "";
|
|
99275
|
+
console.log(` ${id} ${m2.state.padEnd(10)} ${duration3}${size}`);
|
|
99276
|
+
}
|
|
99277
|
+
console.log("");
|
|
99278
|
+
}
|
|
99279
|
+
function printHelp2() {
|
|
99280
|
+
console.log(`
|
|
99281
|
+
Usage: claudish team <subcommand> [options]
|
|
99282
|
+
|
|
99283
|
+
Subcommands:
|
|
99284
|
+
run Run multiple models on a task in parallel
|
|
99285
|
+
judge Blind-judge existing model outputs
|
|
99286
|
+
run-and-judge Run models then judge their outputs
|
|
99287
|
+
status Show current session status
|
|
99288
|
+
|
|
99289
|
+
Options (run / run-and-judge):
|
|
99290
|
+
--path <dir> Session directory (default: .)
|
|
99291
|
+
--models <a,b,...> Comma-separated model IDs to run
|
|
99292
|
+
--input <text> Task prompt (or create input.md in --path beforehand)
|
|
99293
|
+
--timeout <secs> Timeout per model in seconds (default: 300)
|
|
99294
|
+
|
|
99295
|
+
Options (judge / run-and-judge):
|
|
99296
|
+
--judges <a,b,...> Comma-separated judge model IDs (default: same as runners)
|
|
99297
|
+
|
|
99298
|
+
Options (status):
|
|
99299
|
+
--path <dir> Session directory (default: .)
|
|
99300
|
+
|
|
99301
|
+
Examples:
|
|
99302
|
+
claudish team run --path ./review --models minimax-m2.5,kimi-k2.5 --input "Review this code"
|
|
99303
|
+
claudish team judge --path ./review
|
|
99304
|
+
claudish team run-and-judge --path ./review --models gpt-5.4,gemini-3.1-pro-preview --input "Evaluate this design"
|
|
99305
|
+
claudish team status --path ./review
|
|
99306
|
+
`);
|
|
99307
|
+
}
|
|
99308
|
+
async function teamCommand(args) {
|
|
99309
|
+
const subcommand = args[0];
|
|
99310
|
+
if (!subcommand || hasFlag(args, "--help") || hasFlag(args, "-h")) {
|
|
99311
|
+
printHelp2();
|
|
99312
|
+
process.exit(0);
|
|
99313
|
+
}
|
|
99314
|
+
const rawSessionPath = getFlag(args, "--path") ?? ".";
|
|
99315
|
+
let sessionPath;
|
|
99316
|
+
try {
|
|
99317
|
+
sessionPath = validateSessionPath(rawSessionPath);
|
|
99318
|
+
} catch (err) {
|
|
99319
|
+
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
99320
|
+
process.exit(1);
|
|
99321
|
+
}
|
|
99322
|
+
const modelsRaw = getFlag(args, "--models");
|
|
99323
|
+
const judgesRaw = getFlag(args, "--judges");
|
|
99324
|
+
const input = getFlag(args, "--input");
|
|
99325
|
+
const timeoutStr = getFlag(args, "--timeout");
|
|
99326
|
+
const timeout = timeoutStr ? parseInt(timeoutStr, 10) : 300;
|
|
99327
|
+
const models = modelsRaw ? modelsRaw.split(",").map((m2) => m2.trim()).filter(Boolean) : [];
|
|
99328
|
+
const judges = judgesRaw ? judgesRaw.split(",").map((m2) => m2.trim()).filter(Boolean) : undefined;
|
|
99329
|
+
switch (subcommand) {
|
|
99330
|
+
case "run": {
|
|
99331
|
+
if (models.length === 0) {
|
|
99332
|
+
console.error("Error: --models is required for 'run'");
|
|
99333
|
+
process.exit(1);
|
|
99334
|
+
}
|
|
99335
|
+
setupSession(sessionPath, models, input);
|
|
99336
|
+
const runStatus = await runModels(sessionPath, {
|
|
99337
|
+
timeout,
|
|
99338
|
+
onStatusChange: (id, s) => {
|
|
99339
|
+
process.stderr.write(`[team] ${id}: ${s.state}
|
|
99340
|
+
`);
|
|
99341
|
+
}
|
|
99342
|
+
});
|
|
99343
|
+
printStatus(runStatus);
|
|
99344
|
+
break;
|
|
99345
|
+
}
|
|
99346
|
+
case "judge": {
|
|
99347
|
+
const verdict = await judgeResponses(sessionPath, { judges });
|
|
99348
|
+
console.log(readFileSync15(join18(sessionPath, "verdict.md"), "utf-8"));
|
|
99349
|
+
break;
|
|
99350
|
+
}
|
|
99351
|
+
case "run-and-judge": {
|
|
99352
|
+
if (models.length === 0) {
|
|
99353
|
+
console.error("Error: --models is required for 'run-and-judge'");
|
|
99354
|
+
process.exit(1);
|
|
99355
|
+
}
|
|
99356
|
+
setupSession(sessionPath, models, input);
|
|
99357
|
+
const status = await runModels(sessionPath, {
|
|
99358
|
+
timeout,
|
|
99359
|
+
onStatusChange: (id, s) => {
|
|
99360
|
+
process.stderr.write(`[team] ${id}: ${s.state}
|
|
99361
|
+
`);
|
|
99362
|
+
}
|
|
99363
|
+
});
|
|
99364
|
+
printStatus(status);
|
|
99365
|
+
await judgeResponses(sessionPath, { judges });
|
|
99366
|
+
console.log(readFileSync15(join18(sessionPath, "verdict.md"), "utf-8"));
|
|
99367
|
+
break;
|
|
99368
|
+
}
|
|
99369
|
+
case "status": {
|
|
99370
|
+
const status = getStatus(sessionPath);
|
|
99371
|
+
printStatus(status);
|
|
99372
|
+
break;
|
|
99373
|
+
}
|
|
99374
|
+
default: {
|
|
99375
|
+
console.error(`Unknown team subcommand: ${subcommand}`);
|
|
99376
|
+
printHelp2();
|
|
99377
|
+
process.exit(1);
|
|
99378
|
+
}
|
|
99379
|
+
}
|
|
99380
|
+
}
|
|
99381
|
+
var init_team_cli = __esm(() => {
|
|
99382
|
+
init_team_orchestrator();
|
|
99383
|
+
});
|
|
99384
|
+
|
|
98432
99385
|
// src/claude-runner.ts
|
|
98433
99386
|
var exports_claude_runner = {};
|
|
98434
99387
|
__export(exports_claude_runner, {
|
|
98435
99388
|
runClaudeWithProxy: () => runClaudeWithProxy,
|
|
98436
99389
|
checkClaudeInstalled: () => checkClaudeInstalled
|
|
98437
99390
|
});
|
|
98438
|
-
import { spawn } from "child_process";
|
|
98439
|
-
import { writeFileSync as
|
|
98440
|
-
import { tmpdir as tmpdir2, homedir as
|
|
98441
|
-
import { join as
|
|
99391
|
+
import { spawn as spawn2 } from "child_process";
|
|
99392
|
+
import { writeFileSync as writeFileSync11, unlinkSync as unlinkSync7, mkdirSync as mkdirSync10, existsSync as existsSync18, readFileSync as readFileSync16 } from "fs";
|
|
99393
|
+
import { tmpdir as tmpdir2, homedir as homedir16 } from "os";
|
|
99394
|
+
import { join as join19 } from "path";
|
|
99395
|
+
function hasNativeAnthropicMapping(config3) {
|
|
99396
|
+
const models = [config3.model, config3.modelOpus, config3.modelSonnet, config3.modelHaiku, config3.modelSubagent];
|
|
99397
|
+
return models.some((m2) => m2 && parseModelSpec(m2).provider === "native-anthropic");
|
|
99398
|
+
}
|
|
98442
99399
|
function isWindows2() {
|
|
98443
99400
|
return process.platform === "win32";
|
|
98444
99401
|
}
|
|
98445
99402
|
function createStatusLineScript(tokenFilePath) {
|
|
98446
99403
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
|
|
98447
|
-
const claudishDir =
|
|
99404
|
+
const claudishDir = join19(homeDir, ".claudish");
|
|
98448
99405
|
const timestamp = Date.now();
|
|
98449
|
-
const scriptPath =
|
|
99406
|
+
const scriptPath = join19(claudishDir, `status-${timestamp}.js`);
|
|
98450
99407
|
const escapedTokenPath = tokenFilePath.replace(/\\/g, "\\\\");
|
|
98451
99408
|
const script = `
|
|
98452
99409
|
const fs = require('fs');
|
|
@@ -98526,18 +99483,18 @@ process.stdin.on('end', () => {
|
|
|
98526
99483
|
}
|
|
98527
99484
|
});
|
|
98528
99485
|
`;
|
|
98529
|
-
|
|
99486
|
+
writeFileSync11(scriptPath, script, "utf-8");
|
|
98530
99487
|
return scriptPath;
|
|
98531
99488
|
}
|
|
98532
99489
|
function createTempSettingsFile(modelDisplay, port) {
|
|
98533
99490
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
|
|
98534
|
-
const claudishDir =
|
|
99491
|
+
const claudishDir = join19(homeDir, ".claudish");
|
|
98535
99492
|
try {
|
|
98536
|
-
|
|
99493
|
+
mkdirSync10(claudishDir, { recursive: true });
|
|
98537
99494
|
} catch {}
|
|
98538
99495
|
const timestamp = Date.now();
|
|
98539
|
-
const tempPath =
|
|
98540
|
-
const tokenFilePath =
|
|
99496
|
+
const tempPath = join19(claudishDir, `settings-${timestamp}.json`);
|
|
99497
|
+
const tokenFilePath = join19(claudishDir, `tokens-${port}.json`);
|
|
98541
99498
|
let statusCommand;
|
|
98542
99499
|
if (isWindows2()) {
|
|
98543
99500
|
const scriptPath = createStatusLineScript(tokenFilePath);
|
|
@@ -98559,7 +99516,7 @@ function createTempSettingsFile(modelDisplay, port) {
|
|
|
98559
99516
|
padding: 0
|
|
98560
99517
|
};
|
|
98561
99518
|
const settings = { statusLine };
|
|
98562
|
-
|
|
99519
|
+
writeFileSync11(tempPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
98563
99520
|
return { path: tempPath, statusLine };
|
|
98564
99521
|
}
|
|
98565
99522
|
function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine) {
|
|
@@ -98573,11 +99530,11 @@ function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine) {
|
|
|
98573
99530
|
if (userSettingsValue.trimStart().startsWith("{")) {
|
|
98574
99531
|
userSettings = JSON.parse(userSettingsValue);
|
|
98575
99532
|
} else {
|
|
98576
|
-
const rawUserSettings =
|
|
99533
|
+
const rawUserSettings = readFileSync16(userSettingsValue, "utf-8");
|
|
98577
99534
|
userSettings = JSON.parse(rawUserSettings);
|
|
98578
99535
|
}
|
|
98579
99536
|
userSettings.statusLine = statusLine;
|
|
98580
|
-
|
|
99537
|
+
writeFileSync11(tempSettingsPath, JSON.stringify(userSettings, null, 2), "utf-8");
|
|
98581
99538
|
} catch {
|
|
98582
99539
|
if (!config3.quiet) {
|
|
98583
99540
|
console.warn(`[claudish] Warning: could not merge user settings: ${userSettingsValue}`);
|
|
@@ -98585,7 +99542,7 @@ function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine) {
|
|
|
98585
99542
|
}
|
|
98586
99543
|
config3.claudeArgs.splice(idx, 2);
|
|
98587
99544
|
}
|
|
98588
|
-
async function runClaudeWithProxy(config3, proxyUrl) {
|
|
99545
|
+
async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
|
|
98589
99546
|
const hasProfileMappings = config3.modelOpus || config3.modelSonnet || config3.modelHaiku || config3.modelSubagent;
|
|
98590
99547
|
const modelId = config3.model || (hasProfileMappings || config3.monitor ? undefined : "unknown");
|
|
98591
99548
|
const portMatch = proxyUrl.match(/:(\d+)/);
|
|
@@ -98636,14 +99593,19 @@ async function runClaudeWithProxy(config3, proxyUrl) {
|
|
|
98636
99593
|
env2[ENV.ANTHROPIC_MODEL] = modelId;
|
|
98637
99594
|
env2[ENV.ANTHROPIC_SMALL_FAST_MODEL] = modelId;
|
|
98638
99595
|
}
|
|
98639
|
-
|
|
98640
|
-
|
|
99596
|
+
if (hasNativeAnthropicMapping(config3)) {} else {
|
|
99597
|
+
env2.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY || "sk-ant-api03-placeholder-not-used-proxy-handles-auth-with-openrouter-key-xxxxxxxxxxxxxxxxxxxxx";
|
|
99598
|
+
env2.ANTHROPIC_AUTH_TOKEN = process.env.ANTHROPIC_AUTH_TOKEN || "placeholder-token-not-used-proxy-handles-auth";
|
|
99599
|
+
}
|
|
98641
99600
|
}
|
|
98642
99601
|
const log2 = (message) => {
|
|
98643
99602
|
if (!config3.quiet) {
|
|
98644
99603
|
console.log(message);
|
|
98645
99604
|
}
|
|
98646
99605
|
};
|
|
99606
|
+
if (!config3.monitor && hasNativeAnthropicMapping(config3)) {
|
|
99607
|
+
log2("[claudish] Native Claude model detected \u2014 using Claude Code subscription credentials");
|
|
99608
|
+
}
|
|
98647
99609
|
if (config3.interactive) {
|
|
98648
99610
|
log2(`
|
|
98649
99611
|
[claudish] Model: ${modelDisplayName}
|
|
@@ -98660,30 +99622,30 @@ async function runClaudeWithProxy(config3, proxyUrl) {
|
|
|
98660
99622
|
console.error("Install it from: https://claude.com/claude-code");
|
|
98661
99623
|
console.error(`
|
|
98662
99624
|
Or set CLAUDE_PATH to your custom installation:`);
|
|
98663
|
-
const home =
|
|
98664
|
-
const localPath = isWindows2() ?
|
|
99625
|
+
const home = homedir16();
|
|
99626
|
+
const localPath = isWindows2() ? join19(home, ".claude", "local", "claude.exe") : join19(home, ".claude", "local", "claude");
|
|
98665
99627
|
console.error(` export CLAUDE_PATH=${localPath}`);
|
|
98666
99628
|
process.exit(1);
|
|
98667
99629
|
}
|
|
98668
99630
|
const needsShell = isWindows2() && claudeBinary.endsWith(".cmd");
|
|
98669
99631
|
const spawnCommand = needsShell ? `"${claudeBinary}"` : claudeBinary;
|
|
98670
|
-
const proc =
|
|
99632
|
+
const proc = spawn2(spawnCommand, claudeArgs, {
|
|
98671
99633
|
env: env2,
|
|
98672
99634
|
stdio: "inherit",
|
|
98673
99635
|
shell: needsShell
|
|
98674
99636
|
});
|
|
98675
|
-
setupSignalHandlers(proc, tempSettingsPath, config3.quiet);
|
|
99637
|
+
setupSignalHandlers(proc, tempSettingsPath, config3.quiet, onCleanup);
|
|
98676
99638
|
const exitCode = await new Promise((resolve3) => {
|
|
98677
99639
|
proc.on("exit", (code) => {
|
|
98678
99640
|
resolve3(code ?? 1);
|
|
98679
99641
|
});
|
|
98680
99642
|
});
|
|
98681
99643
|
try {
|
|
98682
|
-
|
|
99644
|
+
unlinkSync7(tempSettingsPath);
|
|
98683
99645
|
} catch (error46) {}
|
|
98684
99646
|
return exitCode;
|
|
98685
99647
|
}
|
|
98686
|
-
function setupSignalHandlers(proc, tempSettingsPath, quiet) {
|
|
99648
|
+
function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
|
|
98687
99649
|
const signals2 = isWindows2() ? ["SIGINT", "SIGTERM"] : ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
98688
99650
|
for (const signal of signals2) {
|
|
98689
99651
|
process.on(signal, () => {
|
|
@@ -98692,8 +99654,13 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet) {
|
|
|
98692
99654
|
[claudish] Received ${signal}, shutting down...`);
|
|
98693
99655
|
}
|
|
98694
99656
|
proc.kill();
|
|
99657
|
+
if (onCleanup) {
|
|
99658
|
+
try {
|
|
99659
|
+
onCleanup();
|
|
99660
|
+
} catch {}
|
|
99661
|
+
}
|
|
98695
99662
|
try {
|
|
98696
|
-
|
|
99663
|
+
unlinkSync7(tempSettingsPath);
|
|
98697
99664
|
} catch {}
|
|
98698
99665
|
process.exit(0);
|
|
98699
99666
|
});
|
|
@@ -98702,23 +99669,23 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet) {
|
|
|
98702
99669
|
async function findClaudeBinary() {
|
|
98703
99670
|
const isWindows3 = process.platform === "win32";
|
|
98704
99671
|
if (process.env.CLAUDE_PATH) {
|
|
98705
|
-
if (
|
|
99672
|
+
if (existsSync18(process.env.CLAUDE_PATH)) {
|
|
98706
99673
|
return process.env.CLAUDE_PATH;
|
|
98707
99674
|
}
|
|
98708
99675
|
}
|
|
98709
|
-
const home =
|
|
98710
|
-
const localPath = isWindows3 ?
|
|
98711
|
-
if (
|
|
99676
|
+
const home = homedir16();
|
|
99677
|
+
const localPath = isWindows3 ? join19(home, ".claude", "local", "claude.exe") : join19(home, ".claude", "local", "claude");
|
|
99678
|
+
if (existsSync18(localPath)) {
|
|
98712
99679
|
return localPath;
|
|
98713
99680
|
}
|
|
98714
99681
|
if (isWindows3) {
|
|
98715
99682
|
const windowsPaths = [
|
|
98716
|
-
|
|
98717
|
-
|
|
98718
|
-
|
|
99683
|
+
join19(home, "AppData", "Roaming", "npm", "claude.cmd"),
|
|
99684
|
+
join19(home, ".npm-global", "claude.cmd"),
|
|
99685
|
+
join19(home, "node_modules", ".bin", "claude.cmd")
|
|
98719
99686
|
];
|
|
98720
99687
|
for (const path2 of windowsPaths) {
|
|
98721
|
-
if (
|
|
99688
|
+
if (existsSync18(path2)) {
|
|
98722
99689
|
return path2;
|
|
98723
99690
|
}
|
|
98724
99691
|
}
|
|
@@ -98726,21 +99693,21 @@ async function findClaudeBinary() {
|
|
|
98726
99693
|
const commonPaths = [
|
|
98727
99694
|
"/usr/local/bin/claude",
|
|
98728
99695
|
"/opt/homebrew/bin/claude",
|
|
98729
|
-
|
|
98730
|
-
|
|
98731
|
-
|
|
99696
|
+
join19(home, ".npm-global/bin/claude"),
|
|
99697
|
+
join19(home, ".local/bin/claude"),
|
|
99698
|
+
join19(home, "node_modules/.bin/claude"),
|
|
98732
99699
|
"/data/data/com.termux/files/usr/bin/claude",
|
|
98733
|
-
|
|
99700
|
+
join19(home, "../usr/bin/claude")
|
|
98734
99701
|
];
|
|
98735
99702
|
for (const path2 of commonPaths) {
|
|
98736
|
-
if (
|
|
99703
|
+
if (existsSync18(path2)) {
|
|
98737
99704
|
return path2;
|
|
98738
99705
|
}
|
|
98739
99706
|
}
|
|
98740
99707
|
}
|
|
98741
99708
|
try {
|
|
98742
99709
|
const shellCommand = isWindows3 ? "where claude" : "command -v claude";
|
|
98743
|
-
const proc =
|
|
99710
|
+
const proc = spawn2(shellCommand, [], {
|
|
98744
99711
|
stdio: "pipe",
|
|
98745
99712
|
shell: true
|
|
98746
99713
|
});
|
|
@@ -98772,6 +99739,106 @@ async function checkClaudeInstalled() {
|
|
|
98772
99739
|
}
|
|
98773
99740
|
var init_claude_runner = __esm(() => {
|
|
98774
99741
|
init_config();
|
|
99742
|
+
init_model_parser();
|
|
99743
|
+
});
|
|
99744
|
+
|
|
99745
|
+
// src/diag-output.ts
|
|
99746
|
+
var exports_diag_output = {};
|
|
99747
|
+
__export(exports_diag_output, {
|
|
99748
|
+
createDiagOutput: () => createDiagOutput,
|
|
99749
|
+
TmuxDiagOutput: () => TmuxDiagOutput,
|
|
99750
|
+
NullDiagOutput: () => NullDiagOutput,
|
|
99751
|
+
LogFileDiagOutput: () => LogFileDiagOutput
|
|
99752
|
+
});
|
|
99753
|
+
import { createWriteStream as createWriteStream2, mkdirSync as mkdirSync11, writeFileSync as writeFileSync12, unlinkSync as unlinkSync8 } from "fs";
|
|
99754
|
+
import { execFileSync } from "child_process";
|
|
99755
|
+
import { homedir as homedir17 } from "os";
|
|
99756
|
+
import { join as join20 } from "path";
|
|
99757
|
+
function getClaudishDir() {
|
|
99758
|
+
const dir = join20(homedir17(), ".claudish");
|
|
99759
|
+
try {
|
|
99760
|
+
mkdirSync11(dir, { recursive: true });
|
|
99761
|
+
} catch {}
|
|
99762
|
+
return dir;
|
|
99763
|
+
}
|
|
99764
|
+
function getDiagLogPath() {
|
|
99765
|
+
return join20(getClaudishDir(), `diag-${process.pid}.log`);
|
|
99766
|
+
}
|
|
99767
|
+
|
|
99768
|
+
class LogFileDiagOutput {
|
|
99769
|
+
logPath;
|
|
99770
|
+
stream;
|
|
99771
|
+
constructor() {
|
|
99772
|
+
this.logPath = getDiagLogPath();
|
|
99773
|
+
try {
|
|
99774
|
+
writeFileSync12(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
|
|
99775
|
+
`);
|
|
99776
|
+
} catch {}
|
|
99777
|
+
this.stream = createWriteStream2(this.logPath, { flags: "a" });
|
|
99778
|
+
this.stream.on("error", () => {});
|
|
99779
|
+
}
|
|
99780
|
+
write(msg) {
|
|
99781
|
+
const timestamp = new Date().toISOString();
|
|
99782
|
+
const line = `[${timestamp}] ${msg}
|
|
99783
|
+
`;
|
|
99784
|
+
try {
|
|
99785
|
+
this.stream.write(line);
|
|
99786
|
+
} catch {}
|
|
99787
|
+
}
|
|
99788
|
+
cleanup() {
|
|
99789
|
+
try {
|
|
99790
|
+
this.stream.end();
|
|
99791
|
+
} catch {}
|
|
99792
|
+
try {
|
|
99793
|
+
unlinkSync8(this.logPath);
|
|
99794
|
+
} catch {}
|
|
99795
|
+
}
|
|
99796
|
+
getLogPath() {
|
|
99797
|
+
return this.logPath;
|
|
99798
|
+
}
|
|
99799
|
+
}
|
|
99800
|
+
|
|
99801
|
+
class NullDiagOutput {
|
|
99802
|
+
write(_msg) {}
|
|
99803
|
+
cleanup() {}
|
|
99804
|
+
}
|
|
99805
|
+
function createDiagOutput(options) {
|
|
99806
|
+
if (!options.interactive) {
|
|
99807
|
+
return new NullDiagOutput;
|
|
99808
|
+
}
|
|
99809
|
+
if (process.env.TMUX) {
|
|
99810
|
+
return new TmuxDiagOutput;
|
|
99811
|
+
}
|
|
99812
|
+
return new LogFileDiagOutput;
|
|
99813
|
+
}
|
|
99814
|
+
var TmuxDiagOutput;
|
|
99815
|
+
var init_diag_output = __esm(() => {
|
|
99816
|
+
TmuxDiagOutput = class TmuxDiagOutput extends LogFileDiagOutput {
|
|
99817
|
+
paneId = null;
|
|
99818
|
+
constructor() {
|
|
99819
|
+
super();
|
|
99820
|
+
this.openTmuxPane();
|
|
99821
|
+
}
|
|
99822
|
+
openTmuxPane() {
|
|
99823
|
+
try {
|
|
99824
|
+
const output = execFileSync("tmux", ["split-window", "-v", "-l", "5", "-d", "-P", "-F", "#{pane_id}", "tail", "-f", this.logPath], { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
|
|
99825
|
+
this.paneId = output.trim();
|
|
99826
|
+
} catch {
|
|
99827
|
+
this.paneId = null;
|
|
99828
|
+
}
|
|
99829
|
+
}
|
|
99830
|
+
cleanup() {
|
|
99831
|
+
if (this.paneId) {
|
|
99832
|
+
try {
|
|
99833
|
+
execFileSync("tmux", ["kill-pane", "-t", this.paneId], {
|
|
99834
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
99835
|
+
});
|
|
99836
|
+
} catch {}
|
|
99837
|
+
this.paneId = null;
|
|
99838
|
+
}
|
|
99839
|
+
super.cleanup();
|
|
99840
|
+
}
|
|
99841
|
+
};
|
|
98775
99842
|
});
|
|
98776
99843
|
|
|
98777
99844
|
// src/port-manager.ts
|
|
@@ -101360,8 +102427,10 @@ class OpenRouterProvider {
|
|
|
101360
102427
|
streamFormat = "openai-sse";
|
|
101361
102428
|
apiKey;
|
|
101362
102429
|
queue;
|
|
101363
|
-
|
|
102430
|
+
modelId;
|
|
102431
|
+
constructor(apiKey, modelId) {
|
|
101364
102432
|
this.apiKey = apiKey;
|
|
102433
|
+
this.modelId = modelId || "";
|
|
101365
102434
|
this.queue = OpenRouterRequestQueue.getInstance();
|
|
101366
102435
|
}
|
|
101367
102436
|
overrideStreamFormat() {
|
|
@@ -101380,10 +102449,16 @@ class OpenRouterProvider {
|
|
|
101380
102449
|
async enqueueRequest(fetchFn) {
|
|
101381
102450
|
return this.queue.enqueue(fetchFn);
|
|
101382
102451
|
}
|
|
102452
|
+
getContextWindow() {
|
|
102453
|
+
const models = this.modelId ? getCachedOpenRouterModels() : null;
|
|
102454
|
+
const model = models?.find((m2) => m2.id === this.modelId);
|
|
102455
|
+
return model?.context_length || model?.top_provider?.context_length || 200000;
|
|
102456
|
+
}
|
|
101383
102457
|
}
|
|
101384
102458
|
var OPENROUTER_API_URL2 = "https://openrouter.ai/api/v1/chat/completions";
|
|
101385
102459
|
var init_openrouter2 = __esm(() => {
|
|
101386
102460
|
init_openrouter_queue();
|
|
102461
|
+
init_model_loader();
|
|
101387
102462
|
});
|
|
101388
102463
|
|
|
101389
102464
|
// src/adapters/openrouter-adapter.ts
|
|
@@ -102349,9 +103424,9 @@ var init_middleware = __esm(() => {
|
|
|
102349
103424
|
});
|
|
102350
103425
|
|
|
102351
103426
|
// src/handlers/shared/token-tracker.ts
|
|
102352
|
-
import { mkdirSync as
|
|
102353
|
-
import { homedir as
|
|
102354
|
-
import { join as
|
|
103427
|
+
import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync13 } from "fs";
|
|
103428
|
+
import { homedir as homedir18 } from "os";
|
|
103429
|
+
import { join as join21 } from "path";
|
|
102355
103430
|
|
|
102356
103431
|
class TokenTracker {
|
|
102357
103432
|
port;
|
|
@@ -102465,9 +103540,9 @@ class TokenTracker {
|
|
|
102465
103540
|
is_free: isFreeModel,
|
|
102466
103541
|
is_estimated: isEstimate || false
|
|
102467
103542
|
};
|
|
102468
|
-
const claudishDir =
|
|
102469
|
-
|
|
102470
|
-
|
|
103543
|
+
const claudishDir = join21(homedir18(), ".claudish");
|
|
103544
|
+
mkdirSync12(claudishDir, { recursive: true });
|
|
103545
|
+
writeFileSync13(join21(claudishDir, `tokens-${this.port}.json`), JSON.stringify(data), "utf-8");
|
|
102471
103546
|
} catch (e) {
|
|
102472
103547
|
log(`[TokenTracker] Error writing token file: ${e}`);
|
|
102473
103548
|
}
|
|
@@ -103519,9 +104594,9 @@ class ComposedHandler {
|
|
|
103519
104594
|
});
|
|
103520
104595
|
return c.json({ error: { type: "connection_error", message: err.message } }, 503);
|
|
103521
104596
|
}
|
|
103522
|
-
|
|
103523
|
-
|
|
103524
|
-
|
|
104597
|
+
}
|
|
104598
|
+
if (this.provider.getContextWindow) {
|
|
104599
|
+
this.tokenTracker.setContextWindow(this.provider.getContextWindow());
|
|
103525
104600
|
}
|
|
103526
104601
|
if (this.provider.transformPayload) {
|
|
103527
104602
|
requestPayload = this.provider.transformPayload(requestPayload);
|
|
@@ -103888,9 +104963,9 @@ var init_composed_handler = __esm(() => {
|
|
|
103888
104963
|
});
|
|
103889
104964
|
|
|
103890
104965
|
// src/services/pricing-cache.ts
|
|
103891
|
-
import { readFileSync as
|
|
103892
|
-
import { homedir as
|
|
103893
|
-
import { join as
|
|
104966
|
+
import { readFileSync as readFileSync17, writeFileSync as writeFileSync14, existsSync as existsSync19, mkdirSync as mkdirSync13, statSync as statSync2 } from "fs";
|
|
104967
|
+
import { homedir as homedir19 } from "os";
|
|
104968
|
+
import { join as join22 } from "path";
|
|
103894
104969
|
function getDynamicPricingSync(provider, modelName) {
|
|
103895
104970
|
if (provider === "openrouter") {
|
|
103896
104971
|
const direct = pricingMap.get(modelName);
|
|
@@ -103955,12 +105030,12 @@ async function warmPricingCache() {
|
|
|
103955
105030
|
}
|
|
103956
105031
|
function loadDiskCache() {
|
|
103957
105032
|
try {
|
|
103958
|
-
if (!
|
|
105033
|
+
if (!existsSync19(CACHE_FILE))
|
|
103959
105034
|
return false;
|
|
103960
|
-
const stat =
|
|
105035
|
+
const stat = statSync2(CACHE_FILE);
|
|
103961
105036
|
const age = Date.now() - stat.mtimeMs;
|
|
103962
105037
|
const isFresh = age < CACHE_TTL_MS;
|
|
103963
|
-
const raw2 =
|
|
105038
|
+
const raw2 = readFileSync17(CACHE_FILE, "utf-8");
|
|
103964
105039
|
const data = JSON.parse(raw2);
|
|
103965
105040
|
for (const [key, pricing] of Object.entries(data)) {
|
|
103966
105041
|
pricingMap.set(key, pricing);
|
|
@@ -103972,12 +105047,12 @@ function loadDiskCache() {
|
|
|
103972
105047
|
}
|
|
103973
105048
|
function saveDiskCache() {
|
|
103974
105049
|
try {
|
|
103975
|
-
|
|
105050
|
+
mkdirSync13(CACHE_DIR, { recursive: true });
|
|
103976
105051
|
const data = {};
|
|
103977
105052
|
for (const [key, pricing] of pricingMap) {
|
|
103978
105053
|
data[key] = pricing;
|
|
103979
105054
|
}
|
|
103980
|
-
|
|
105055
|
+
writeFileSync14(CACHE_FILE, JSON.stringify(data), "utf-8");
|
|
103981
105056
|
} catch (error46) {
|
|
103982
105057
|
log(`[PricingCache] Error saving disk cache: ${error46}`);
|
|
103983
105058
|
}
|
|
@@ -104007,8 +105082,8 @@ var init_pricing_cache = __esm(() => {
|
|
|
104007
105082
|
init_model_loader();
|
|
104008
105083
|
init_remote_provider_types();
|
|
104009
105084
|
pricingMap = new Map;
|
|
104010
|
-
CACHE_DIR =
|
|
104011
|
-
CACHE_FILE =
|
|
105085
|
+
CACHE_DIR = join22(homedir19(), ".claudish");
|
|
105086
|
+
CACHE_FILE = join22(CACHE_DIR, "pricing-cache.json");
|
|
104012
105087
|
CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
104013
105088
|
PROVIDER_TO_OR_PREFIX = {
|
|
104014
105089
|
openai: ["openai/"],
|
|
@@ -104467,12 +105542,12 @@ class AnthropicCompatProvider {
|
|
|
104467
105542
|
}
|
|
104468
105543
|
if (this.provider.name === "kimi-coding" && !this.apiKey) {
|
|
104469
105544
|
try {
|
|
104470
|
-
const { existsSync:
|
|
104471
|
-
const { join:
|
|
104472
|
-
const { homedir:
|
|
104473
|
-
const credPath =
|
|
104474
|
-
if (
|
|
104475
|
-
const data = JSON.parse(
|
|
105545
|
+
const { existsSync: existsSync20, readFileSync: readFileSync18 } = await import("fs");
|
|
105546
|
+
const { join: join23 } = await import("path");
|
|
105547
|
+
const { homedir: homedir20 } = await import("os");
|
|
105548
|
+
const credPath = join23(homedir20(), ".claudish", "kimi-oauth.json");
|
|
105549
|
+
if (existsSync20(credPath)) {
|
|
105550
|
+
const data = JSON.parse(readFileSync18(credPath, "utf-8"));
|
|
104476
105551
|
if (data.access_token && data.refresh_token) {
|
|
104477
105552
|
const { KimiOAuth: KimiOAuth2 } = await Promise.resolve().then(() => (init_kimi_oauth(), exports_kimi_oauth));
|
|
104478
105553
|
const oauth = KimiOAuth2.getInstance();
|
|
@@ -104589,12 +105664,18 @@ var init_anthropic_passthrough_adapter = __esm(() => {
|
|
|
104589
105664
|
if (model.includes("kimi-k2.5") || model.includes("kimi-k2-5"))
|
|
104590
105665
|
return 262144;
|
|
104591
105666
|
if (model.includes("kimi-k2"))
|
|
104592
|
-
return
|
|
105667
|
+
return 131000;
|
|
104593
105668
|
if (this.providerName === "kimi" || this.providerName === "kimi-coding" || model.includes("kimi")) {
|
|
104594
105669
|
return 131072;
|
|
104595
105670
|
}
|
|
105671
|
+
if (model.includes("minimax-01") || model.includes("minimax-m1"))
|
|
105672
|
+
return 1e6;
|
|
105673
|
+
if (model.includes("minimax-m2.7"))
|
|
105674
|
+
return 204800;
|
|
105675
|
+
if (model.includes("minimax-m2"))
|
|
105676
|
+
return 196608;
|
|
104596
105677
|
if (this.providerName === "minimax" || this.providerName === "minimax-coding") {
|
|
104597
|
-
return
|
|
105678
|
+
return 196608;
|
|
104598
105679
|
}
|
|
104599
105680
|
return 128000;
|
|
104600
105681
|
}
|
|
@@ -104775,10 +105856,10 @@ var init_litellm2 = __esm(() => {
|
|
|
104775
105856
|
});
|
|
104776
105857
|
|
|
104777
105858
|
// src/adapters/litellm-adapter.ts
|
|
104778
|
-
import { existsSync as
|
|
105859
|
+
import { existsSync as existsSync20, readFileSync as readFileSync18 } from "fs";
|
|
104779
105860
|
import { createHash as createHash5 } from "crypto";
|
|
104780
|
-
import { homedir as
|
|
104781
|
-
import { join as
|
|
105861
|
+
import { homedir as homedir20 } from "os";
|
|
105862
|
+
import { join as join23 } from "path";
|
|
104782
105863
|
var INLINE_IMAGE_MODEL_PATTERNS, LiteLLMAdapter;
|
|
104783
105864
|
var init_litellm_adapter = __esm(() => {
|
|
104784
105865
|
init_base_adapter();
|
|
@@ -104874,10 +105955,10 @@ var init_litellm_adapter = __esm(() => {
|
|
|
104874
105955
|
checkVisionSupport() {
|
|
104875
105956
|
try {
|
|
104876
105957
|
const hash2 = createHash5("sha256").update(this.baseUrl).digest("hex").substring(0, 16);
|
|
104877
|
-
const cachePath =
|
|
104878
|
-
if (!
|
|
105958
|
+
const cachePath = join23(homedir20(), ".claudish", `litellm-models-${hash2}.json`);
|
|
105959
|
+
if (!existsSync20(cachePath))
|
|
104879
105960
|
return true;
|
|
104880
|
-
const cacheData = JSON.parse(
|
|
105961
|
+
const cacheData = JSON.parse(readFileSync18(cachePath, "utf-8"));
|
|
104881
105962
|
const model = cacheData.models?.find((m2) => m2.name === this.modelId);
|
|
104882
105963
|
if (model && model.supportsVision === false) {
|
|
104883
105964
|
log(`[LiteLLMAdapter] Model ${this.modelId} does not support vision`);
|
|
@@ -104894,9 +105975,9 @@ var init_litellm_adapter = __esm(() => {
|
|
|
104894
105975
|
// src/auth/vertex-auth.ts
|
|
104895
105976
|
import { exec as exec4 } from "child_process";
|
|
104896
105977
|
import { promisify as promisify3 } from "util";
|
|
104897
|
-
import { existsSync as
|
|
104898
|
-
import { homedir as
|
|
104899
|
-
import { join as
|
|
105978
|
+
import { existsSync as existsSync21 } from "fs";
|
|
105979
|
+
import { homedir as homedir21 } from "os";
|
|
105980
|
+
import { join as join24 } from "path";
|
|
104900
105981
|
|
|
104901
105982
|
class VertexAuthManager {
|
|
104902
105983
|
cachedToken = null;
|
|
@@ -104950,8 +106031,8 @@ class VertexAuthManager {
|
|
|
104950
106031
|
}
|
|
104951
106032
|
async tryADC() {
|
|
104952
106033
|
try {
|
|
104953
|
-
const adcPath =
|
|
104954
|
-
if (!
|
|
106034
|
+
const adcPath = join24(homedir21(), ".config/gcloud/application_default_credentials.json");
|
|
106035
|
+
if (!existsSync21(adcPath)) {
|
|
104955
106036
|
log("[VertexAuth] ADC credentials file not found");
|
|
104956
106037
|
return null;
|
|
104957
106038
|
}
|
|
@@ -104975,7 +106056,7 @@ class VertexAuthManager {
|
|
|
104975
106056
|
if (!credPath) {
|
|
104976
106057
|
return null;
|
|
104977
106058
|
}
|
|
104978
|
-
if (!
|
|
106059
|
+
if (!existsSync21(credPath)) {
|
|
104979
106060
|
throw new Error(`Service account file not found: ${credPath}
|
|
104980
106061
|
|
|
104981
106062
|
Check GOOGLE_APPLICATION_CREDENTIALS path.`);
|
|
@@ -105014,8 +106095,8 @@ function validateVertexOAuthConfig() {
|
|
|
105014
106095
|
` + ` export VERTEX_PROJECT='your-gcp-project-id'
|
|
105015
106096
|
` + " export VERTEX_LOCATION='us-central1' # optional";
|
|
105016
106097
|
}
|
|
105017
|
-
const adcPath =
|
|
105018
|
-
const hasADC =
|
|
106098
|
+
const adcPath = join24(homedir21(), ".config/gcloud/application_default_credentials.json");
|
|
106099
|
+
const hasADC = existsSync21(adcPath);
|
|
105019
106100
|
const hasServiceAccount = !!process.env.GOOGLE_APPLICATION_CREDENTIALS;
|
|
105020
106101
|
if (!hasADC && !hasServiceAccount) {
|
|
105021
106102
|
return `No Vertex AI credentials found.
|
|
@@ -105343,7 +106424,7 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
|
|
|
105343
106424
|
const parsed = parseModelSpec(targetModel);
|
|
105344
106425
|
const modelId = targetModel.includes("@") ? parsed.model : targetModel;
|
|
105345
106426
|
if (!openRouterHandlers.has(modelId)) {
|
|
105346
|
-
const orProvider = new OpenRouterProvider(openrouterApiKey || "");
|
|
106427
|
+
const orProvider = new OpenRouterProvider(openrouterApiKey || "", modelId);
|
|
105347
106428
|
const orAdapter = new OpenRouterAdapter(modelId);
|
|
105348
106429
|
openRouterHandlers.set(modelId, new ComposedHandler(orProvider, modelId, modelId, port, {
|
|
105349
106430
|
adapter: orAdapter,
|
|
@@ -105651,16 +106732,16 @@ var init_proxy_server = __esm(() => {
|
|
|
105651
106732
|
|
|
105652
106733
|
// src/index.ts
|
|
105653
106734
|
var import_dotenv2 = __toESM(require_main(), 1);
|
|
105654
|
-
import { existsSync as
|
|
105655
|
-
import { homedir as
|
|
105656
|
-
import { join as
|
|
106735
|
+
import { existsSync as existsSync23, readFileSync as readFileSync20 } from "fs";
|
|
106736
|
+
import { homedir as homedir22 } from "os";
|
|
106737
|
+
import { join as join25 } from "path";
|
|
105657
106738
|
import_dotenv2.config({ quiet: true });
|
|
105658
106739
|
function loadStoredApiKeys() {
|
|
105659
106740
|
try {
|
|
105660
|
-
const configPath =
|
|
105661
|
-
if (!
|
|
106741
|
+
const configPath = join25(homedir22(), ".claudish", "config.json");
|
|
106742
|
+
if (!existsSync23(configPath))
|
|
105662
106743
|
return;
|
|
105663
|
-
const raw2 =
|
|
106744
|
+
const raw2 = readFileSync20(configPath, "utf-8");
|
|
105664
106745
|
const cfg = JSON.parse(raw2);
|
|
105665
106746
|
if (cfg.apiKeys) {
|
|
105666
106747
|
for (const [envVar, value] of Object.entries(cfg.apiKeys)) {
|
|
@@ -105698,6 +106779,7 @@ var isProfileCommand = args[0] === "profile" || args.some((a, i) => a === "profi
|
|
|
105698
106779
|
var isTelemetryCommand = args[0] === "telemetry";
|
|
105699
106780
|
var isStatsCommand = args[0] === "stats";
|
|
105700
106781
|
var isConfigCommand = args[0] === "config";
|
|
106782
|
+
var isTeamCommand = args[0] === "team";
|
|
105701
106783
|
if (isMcpMode) {
|
|
105702
106784
|
Promise.resolve().then(() => (init_mcp_server(), exports_mcp_server)).then((mcp) => mcp.startMcpServer());
|
|
105703
106785
|
} else if (isGeminiLogin) {
|
|
@@ -105776,6 +106858,8 @@ if (isMcpMode) {
|
|
|
105776
106858
|
});
|
|
105777
106859
|
} else if (isConfigCommand) {
|
|
105778
106860
|
init_tui().then(() => exports_tui).then((m2) => m2.startConfigTui().catch(handlePromptExit));
|
|
106861
|
+
} else if (isTeamCommand) {
|
|
106862
|
+
Promise.resolve().then(() => (init_team_cli(), exports_team_cli)).then((m2) => m2.teamCommand(args.slice(1)));
|
|
105779
106863
|
} else {
|
|
105780
106864
|
runCli();
|
|
105781
106865
|
}
|
|
@@ -105790,7 +106874,8 @@ async function runCli() {
|
|
|
105790
106874
|
getMissingKeyResolutions: getMissingKeyResolutions2,
|
|
105791
106875
|
getMissingKeysError: getMissingKeysError2
|
|
105792
106876
|
} = await Promise.resolve().then(() => (init_provider_resolver(), exports_provider_resolver));
|
|
105793
|
-
const { initLogger: initLogger2, getLogFilePath: getLogFilePath2,
|
|
106877
|
+
const { initLogger: initLogger2, getLogFilePath: getLogFilePath2, getAlwaysOnLogPath: getAlwaysOnLogPath2, setDiagOutput: setDiagOutput2 } = await Promise.resolve().then(() => (init_logger(), exports_logger));
|
|
106878
|
+
const { createDiagOutput: createDiagOutput2, LogFileDiagOutput: LogFileDiagOutput2 } = await Promise.resolve().then(() => (init_diag_output(), exports_diag_output));
|
|
105794
106879
|
const { findAvailablePort: findAvailablePort2 } = await Promise.resolve().then(() => (init_port_manager(), exports_port_manager));
|
|
105795
106880
|
const { createProxyServer: createProxyServer2 } = await Promise.resolve().then(() => (init_proxy_server(), exports_proxy_server));
|
|
105796
106881
|
const { checkForUpdates: checkForUpdates2 } = await Promise.resolve().then(() => (init_update_checker(), exports_update_checker));
|
|
@@ -105803,7 +106888,7 @@ async function runCli() {
|
|
|
105803
106888
|
}
|
|
105804
106889
|
try {
|
|
105805
106890
|
const cliConfig = await parseArgs2(process.argv.slice(2));
|
|
105806
|
-
initLogger2(cliConfig.debug, cliConfig.logLevel);
|
|
106891
|
+
initLogger2(cliConfig.debug, cliConfig.logLevel, cliConfig.noLogs);
|
|
105807
106892
|
const { initTelemetry: initTelemetry2 } = await Promise.resolve().then(() => (init_telemetry(), exports_telemetry));
|
|
105808
106893
|
initTelemetry2(cliConfig);
|
|
105809
106894
|
const { initStats: initStats2, showMonthlyBanner: showMonthlyBanner2 } = await Promise.resolve().then(() => (init_stats(), exports_stats));
|
|
@@ -105908,14 +106993,19 @@ async function runCli() {
|
|
|
105908
106993
|
quiet: cliConfig.quiet,
|
|
105909
106994
|
isInteractive: cliConfig.interactive
|
|
105910
106995
|
});
|
|
106996
|
+
const diag = createDiagOutput2({ interactive: cliConfig.interactive });
|
|
105911
106997
|
if (cliConfig.interactive) {
|
|
105912
|
-
|
|
106998
|
+
setDiagOutput2(diag);
|
|
106999
|
+
if (!process.env.TMUX && !cliConfig.quiet && diag instanceof LogFileDiagOutput2) {
|
|
107000
|
+
console.log(`[claudish] Diagnostic log: ${diag.getLogPath()}`);
|
|
107001
|
+
}
|
|
105913
107002
|
}
|
|
105914
107003
|
let exitCode = 0;
|
|
105915
107004
|
try {
|
|
105916
|
-
exitCode = await runClaudeWithProxy2(cliConfig, proxy.url);
|
|
107005
|
+
exitCode = await runClaudeWithProxy2(cliConfig, proxy.url, () => diag.cleanup());
|
|
105917
107006
|
} finally {
|
|
105918
|
-
|
|
107007
|
+
setDiagOutput2(null);
|
|
107008
|
+
diag.cleanup();
|
|
105919
107009
|
if (!cliConfig.quiet) {
|
|
105920
107010
|
console.log(`
|
|
105921
107011
|
[claudish] Shutting down proxy server...`);
|
|
@@ -105926,6 +107016,12 @@ async function runCli() {
|
|
|
105926
107016
|
console.log(`[claudish] Done
|
|
105927
107017
|
`);
|
|
105928
107018
|
}
|
|
107019
|
+
const sessionLogPath = getAlwaysOnLogPath2();
|
|
107020
|
+
if (exitCode !== 0 && sessionLogPath && !cliConfig.quiet) {
|
|
107021
|
+
console.error(`
|
|
107022
|
+
[claudish] Session ended with errors. Log: ${sessionLogPath}`);
|
|
107023
|
+
console.error(`[claudish] To review: /debug-logs ${sessionLogPath}`);
|
|
107024
|
+
}
|
|
105929
107025
|
process.exit(exitCode);
|
|
105930
107026
|
} catch (error46) {
|
|
105931
107027
|
console.error("[claudish] Fatal error:", error46);
|