claudish 6.8.1 → 6.9.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 +324 -460
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -34490,7 +34490,7 @@ async function fetchGLMCodingModels() {
|
|
|
34490
34490
|
return [];
|
|
34491
34491
|
}
|
|
34492
34492
|
}
|
|
34493
|
-
var __filename4, __dirname4, VERSION = "6.
|
|
34493
|
+
var __filename4, __dirname4, VERSION = "6.9.0", CACHE_MAX_AGE_DAYS2 = 2, CLAUDISH_CACHE_DIR2, BUNDLED_MODELS_PATH, CACHED_MODELS_PATH, ALL_MODELS_JSON_PATH;
|
|
34494
34494
|
var init_cli = __esm(() => {
|
|
34495
34495
|
init_config();
|
|
34496
34496
|
init_model_loader();
|
|
@@ -95666,431 +95666,16 @@ var init_tui = __esm(async () => {
|
|
|
95666
95666
|
}
|
|
95667
95667
|
});
|
|
95668
95668
|
|
|
95669
|
-
// src/team-grid.ts
|
|
95670
|
-
var exports_team_grid = {};
|
|
95671
|
-
__export(exports_team_grid, {
|
|
95672
|
-
runWithGrid: () => runWithGrid
|
|
95673
|
-
});
|
|
95674
|
-
import { spawn as spawn3 } from "child_process";
|
|
95675
|
-
import {
|
|
95676
|
-
appendFileSync,
|
|
95677
|
-
existsSync as existsSync26,
|
|
95678
|
-
mkdirSync as mkdirSync14,
|
|
95679
|
-
readFileSync as readFileSync21,
|
|
95680
|
-
unlinkSync as unlinkSync8,
|
|
95681
|
-
writeFileSync as writeFileSync15
|
|
95682
|
-
} from "fs";
|
|
95683
|
-
import { dirname as dirname6, join as join27 } from "path";
|
|
95684
|
-
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
95685
|
-
import { execSync as execSync3 } from "child_process";
|
|
95686
|
-
function formatElapsed(ms) {
|
|
95687
|
-
const s = Math.floor(ms / 1000);
|
|
95688
|
-
if (s < 60)
|
|
95689
|
-
return `${s}s`;
|
|
95690
|
-
const m2 = Math.floor(s / 60);
|
|
95691
|
-
const rem = s % 60;
|
|
95692
|
-
return `${m2}m ${rem}s`;
|
|
95693
|
-
}
|
|
95694
|
-
function findMagmuxBinary() {
|
|
95695
|
-
const thisFile = fileURLToPath6(import.meta.url);
|
|
95696
|
-
const thisDir = dirname6(thisFile);
|
|
95697
|
-
const pkgRoot = join27(thisDir, "..");
|
|
95698
|
-
const platform3 = process.platform;
|
|
95699
|
-
const arch = process.arch;
|
|
95700
|
-
const builtMagmux = join27(pkgRoot, "native", "magmux", "magmux");
|
|
95701
|
-
if (existsSync26(builtMagmux))
|
|
95702
|
-
return builtMagmux;
|
|
95703
|
-
const bundledMagmux = join27(pkgRoot, "native", "magmux", `magmux-${platform3}-${arch}`);
|
|
95704
|
-
if (existsSync26(bundledMagmux))
|
|
95705
|
-
return bundledMagmux;
|
|
95706
|
-
try {
|
|
95707
|
-
const pkgName = `@claudish/magmux-${platform3}-${arch}`;
|
|
95708
|
-
let searchDir = pkgRoot;
|
|
95709
|
-
for (let i = 0;i < 5; i++) {
|
|
95710
|
-
const candidate = join27(searchDir, "node_modules", pkgName, "bin", "magmux");
|
|
95711
|
-
if (existsSync26(candidate))
|
|
95712
|
-
return candidate;
|
|
95713
|
-
const parent = dirname6(searchDir);
|
|
95714
|
-
if (parent === searchDir)
|
|
95715
|
-
break;
|
|
95716
|
-
searchDir = parent;
|
|
95717
|
-
}
|
|
95718
|
-
} catch {}
|
|
95719
|
-
try {
|
|
95720
|
-
const result = execSync3("which magmux", { encoding: "utf-8" }).trim();
|
|
95721
|
-
if (result)
|
|
95722
|
-
return result;
|
|
95723
|
-
} catch {}
|
|
95724
|
-
throw new Error(`magmux not found. Install it:
|
|
95725
|
-
brew install MadAppGang/tap/magmux`);
|
|
95726
|
-
}
|
|
95727
|
-
function renderGridStatusBar(counts) {
|
|
95728
|
-
const elapsed = formatElapsed(counts.elapsedMs);
|
|
95729
|
-
const { done, running, failed, total, allDone } = counts;
|
|
95730
|
-
if (allDone) {
|
|
95731
|
-
if (failed > 0) {
|
|
95732
|
-
return [
|
|
95733
|
-
"C: claudish team",
|
|
95734
|
-
`G: ${done} done`,
|
|
95735
|
-
`R: ${failed} failed`,
|
|
95736
|
-
`D: ${elapsed}`,
|
|
95737
|
-
"R: \u2717 issues",
|
|
95738
|
-
"D: ctrl-g q to quit"
|
|
95739
|
-
].join("\t");
|
|
95740
|
-
}
|
|
95741
|
-
return [
|
|
95742
|
-
"C: claudish team",
|
|
95743
|
-
`G: ${total} done`,
|
|
95744
|
-
`D: ${elapsed}`,
|
|
95745
|
-
"G: \u2713 complete",
|
|
95746
|
-
"D: ctrl-g q to quit"
|
|
95747
|
-
].join("\t");
|
|
95748
|
-
}
|
|
95749
|
-
return [
|
|
95750
|
-
"C: claudish team",
|
|
95751
|
-
`G: ${done} done`,
|
|
95752
|
-
`C: ${running} running`,
|
|
95753
|
-
`R: ${failed} failed`,
|
|
95754
|
-
`D: ${elapsed}`
|
|
95755
|
-
].join("\t");
|
|
95756
|
-
}
|
|
95757
|
-
function pollStatus(state) {
|
|
95758
|
-
const { statusCache, statusPath, sessionPath, anonIds, startTime, timeoutMs, statusbarPath } = state;
|
|
95759
|
-
const elapsedMs = Date.now() - startTime;
|
|
95760
|
-
let changed = false;
|
|
95761
|
-
let done = 0;
|
|
95762
|
-
let running = 0;
|
|
95763
|
-
let failed = 0;
|
|
95764
|
-
for (const anonId of anonIds) {
|
|
95765
|
-
const current = statusCache.models[anonId];
|
|
95766
|
-
if (current.state === "COMPLETED" || current.state === "FAILED" || current.state === "TIMEOUT") {
|
|
95767
|
-
if (current.state === "COMPLETED")
|
|
95768
|
-
done++;
|
|
95769
|
-
else
|
|
95770
|
-
failed++;
|
|
95771
|
-
continue;
|
|
95772
|
-
}
|
|
95773
|
-
const exitCodePath = join27(sessionPath, "work", anonId, ".exit-code");
|
|
95774
|
-
if (existsSync26(exitCodePath)) {
|
|
95775
|
-
const codeStr = readFileSync21(exitCodePath, "utf-8").trim();
|
|
95776
|
-
const code = parseInt(codeStr, 10);
|
|
95777
|
-
const isSuccess = code === 0;
|
|
95778
|
-
const newState = {
|
|
95779
|
-
...current,
|
|
95780
|
-
state: isSuccess ? "COMPLETED" : "FAILED",
|
|
95781
|
-
exitCode: code,
|
|
95782
|
-
startedAt: current.startedAt ?? new Date().toISOString(),
|
|
95783
|
-
completedAt: new Date().toISOString(),
|
|
95784
|
-
outputSize: 0
|
|
95785
|
-
};
|
|
95786
|
-
statusCache.models[anonId] = newState;
|
|
95787
|
-
changed = true;
|
|
95788
|
-
if (isSuccess)
|
|
95789
|
-
done++;
|
|
95790
|
-
else
|
|
95791
|
-
failed++;
|
|
95792
|
-
} else {
|
|
95793
|
-
if (!state.interactive && elapsedMs > timeoutMs) {
|
|
95794
|
-
const newState = {
|
|
95795
|
-
...current,
|
|
95796
|
-
state: "TIMEOUT",
|
|
95797
|
-
startedAt: current.startedAt ?? new Date().toISOString(),
|
|
95798
|
-
completedAt: new Date().toISOString(),
|
|
95799
|
-
outputSize: 0
|
|
95800
|
-
};
|
|
95801
|
-
statusCache.models[anonId] = newState;
|
|
95802
|
-
changed = true;
|
|
95803
|
-
failed++;
|
|
95804
|
-
} else {
|
|
95805
|
-
if (current.state === "PENDING" && elapsedMs > 1000) {
|
|
95806
|
-
statusCache.models[anonId] = {
|
|
95807
|
-
...current,
|
|
95808
|
-
state: "RUNNING",
|
|
95809
|
-
startedAt: current.startedAt ?? new Date().toISOString()
|
|
95810
|
-
};
|
|
95811
|
-
changed = true;
|
|
95812
|
-
}
|
|
95813
|
-
running++;
|
|
95814
|
-
}
|
|
95815
|
-
}
|
|
95816
|
-
}
|
|
95817
|
-
if (changed) {
|
|
95818
|
-
writeFileSync15(statusPath, JSON.stringify(statusCache, null, 2), "utf-8");
|
|
95819
|
-
}
|
|
95820
|
-
const total = anonIds.length;
|
|
95821
|
-
const allDone = done + failed >= total;
|
|
95822
|
-
if (allDone && !state.completedAtMs) {
|
|
95823
|
-
state.completedAtMs = elapsedMs;
|
|
95824
|
-
}
|
|
95825
|
-
const counts = {
|
|
95826
|
-
done,
|
|
95827
|
-
running,
|
|
95828
|
-
failed,
|
|
95829
|
-
total,
|
|
95830
|
-
elapsedMs: state.completedAtMs ?? elapsedMs,
|
|
95831
|
-
allDone
|
|
95832
|
-
};
|
|
95833
|
-
appendFileSync(statusbarPath, renderGridStatusBar(counts) + `
|
|
95834
|
-
`);
|
|
95835
|
-
return allDone;
|
|
95836
|
-
}
|
|
95837
|
-
async function runWithGrid(sessionPath, models, input, opts) {
|
|
95838
|
-
const timeoutMs = (opts?.timeout ?? 300) * 1000;
|
|
95839
|
-
const interactive = opts?.interactive ?? false;
|
|
95840
|
-
const manifest = setupSession(sessionPath, models, input);
|
|
95841
|
-
mkdirSync14(join27(sessionPath, "errors"), { recursive: true });
|
|
95842
|
-
for (const anonId of Object.keys(manifest.models)) {
|
|
95843
|
-
const stale = join27(sessionPath, "work", anonId, ".exit-code");
|
|
95844
|
-
try {
|
|
95845
|
-
unlinkSync8(stale);
|
|
95846
|
-
} catch {}
|
|
95847
|
-
}
|
|
95848
|
-
const gridfilePath = join27(sessionPath, "gridfile.txt");
|
|
95849
|
-
const prompt = readFileSync21(join27(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''");
|
|
95850
|
-
const gridLines = Object.entries(manifest.models).map(([anonId]) => {
|
|
95851
|
-
const errorLog = join27(sessionPath, "errors", `${anonId}.log`);
|
|
95852
|
-
const exitCodeFile = join27(sessionPath, "work", anonId, ".exit-code");
|
|
95853
|
-
const model = manifest.models[anonId].model;
|
|
95854
|
-
const paneIndex = Object.keys(manifest.models).indexOf(anonId);
|
|
95855
|
-
if (interactive) {
|
|
95856
|
-
return `claudish --model ${model} --dangerously-skip-permissions '${prompt}'`;
|
|
95857
|
-
}
|
|
95858
|
-
return [
|
|
95859
|
-
`claudish --model ${model} -y -v '${prompt}' 2>${errorLog};`,
|
|
95860
|
-
`_ec=$?; echo $_ec > ${exitCodeFile};`,
|
|
95861
|
-
`if [ -n "$MAGMUX_SOCK" ]; then`,
|
|
95862
|
-
` if [ $_ec -eq 0 ]; then`,
|
|
95863
|
-
` echo '{"cmd":"tint","pane":${paneIndex},"color":"green"}' | nc -U "$MAGMUX_SOCK" -w 1 2>/dev/null;`,
|
|
95864
|
-
` echo '{"cmd":"overlay","pane":${paneIndex},"text":"DONE","color":"green"}' | nc -U "$MAGMUX_SOCK" -w 1 2>/dev/null;`,
|
|
95865
|
-
` else`,
|
|
95866
|
-
` echo '{"cmd":"tint","pane":${paneIndex},"color":"red"}' | nc -U "$MAGMUX_SOCK" -w 1 2>/dev/null;`,
|
|
95867
|
-
` echo '{"cmd":"overlay","pane":${paneIndex},"text":"FAIL","color":"red"}' | nc -U "$MAGMUX_SOCK" -w 1 2>/dev/null;`,
|
|
95868
|
-
` fi;`,
|
|
95869
|
-
`fi;`,
|
|
95870
|
-
`exec sleep 86400`
|
|
95871
|
-
].join(" ");
|
|
95872
|
-
});
|
|
95873
|
-
writeFileSync15(gridfilePath, gridLines.join(`
|
|
95874
|
-
`) + `
|
|
95875
|
-
`, "utf-8");
|
|
95876
|
-
const magmuxPath = findMagmuxBinary();
|
|
95877
|
-
const statusbarPath = join27(sessionPath, "statusbar.txt");
|
|
95878
|
-
const statusPath = join27(sessionPath, "status.json");
|
|
95879
|
-
const statusCache = JSON.parse(readFileSync21(statusPath, "utf-8"));
|
|
95880
|
-
const anonIds = Object.keys(manifest.models);
|
|
95881
|
-
const startTime = Date.now();
|
|
95882
|
-
appendFileSync(statusbarPath, renderGridStatusBar({
|
|
95883
|
-
done: 0,
|
|
95884
|
-
running: 0,
|
|
95885
|
-
failed: 0,
|
|
95886
|
-
total: anonIds.length,
|
|
95887
|
-
elapsedMs: 0,
|
|
95888
|
-
allDone: false
|
|
95889
|
-
}) + `
|
|
95890
|
-
`);
|
|
95891
|
-
const pollState = {
|
|
95892
|
-
statusCache,
|
|
95893
|
-
statusPath,
|
|
95894
|
-
sessionPath,
|
|
95895
|
-
anonIds,
|
|
95896
|
-
startTime,
|
|
95897
|
-
timeoutMs,
|
|
95898
|
-
statusbarPath,
|
|
95899
|
-
completedAtMs: null,
|
|
95900
|
-
interactive
|
|
95901
|
-
};
|
|
95902
|
-
const pollInterval = setInterval(() => {
|
|
95903
|
-
pollStatus(pollState);
|
|
95904
|
-
}, 500);
|
|
95905
|
-
const spawnArgs = ["-g", gridfilePath, "-S", statusbarPath];
|
|
95906
|
-
if (!interactive) {
|
|
95907
|
-
spawnArgs.push("-w");
|
|
95908
|
-
}
|
|
95909
|
-
const proc = spawn3(magmuxPath, spawnArgs, {
|
|
95910
|
-
stdio: "inherit",
|
|
95911
|
-
env: { ...process.env }
|
|
95912
|
-
});
|
|
95913
|
-
await new Promise((resolve4) => {
|
|
95914
|
-
proc.on("exit", () => resolve4());
|
|
95915
|
-
proc.on("error", () => resolve4());
|
|
95916
|
-
});
|
|
95917
|
-
clearInterval(pollInterval);
|
|
95918
|
-
pollStatus(pollState);
|
|
95919
|
-
return JSON.parse(readFileSync21(statusPath, "utf-8"));
|
|
95920
|
-
}
|
|
95921
|
-
var init_team_grid = __esm(() => {
|
|
95922
|
-
init_team_orchestrator();
|
|
95923
|
-
});
|
|
95924
|
-
|
|
95925
|
-
// src/team-cli.ts
|
|
95926
|
-
var exports_team_cli = {};
|
|
95927
|
-
__export(exports_team_cli, {
|
|
95928
|
-
teamCommand: () => teamCommand
|
|
95929
|
-
});
|
|
95930
|
-
import { readFileSync as readFileSync22 } from "fs";
|
|
95931
|
-
import { join as join28 } from "path";
|
|
95932
|
-
function getFlag(args, flag) {
|
|
95933
|
-
const idx = args.indexOf(flag);
|
|
95934
|
-
if (idx === -1 || idx + 1 >= args.length)
|
|
95935
|
-
return;
|
|
95936
|
-
return args[idx + 1];
|
|
95937
|
-
}
|
|
95938
|
-
function hasFlag(args, flag) {
|
|
95939
|
-
return args.includes(flag);
|
|
95940
|
-
}
|
|
95941
|
-
function printStatus(status) {
|
|
95942
|
-
const modelIds = Object.keys(status.models).sort();
|
|
95943
|
-
console.log(`
|
|
95944
|
-
Team Status (started: ${status.startedAt})`);
|
|
95945
|
-
console.log("\u2500".repeat(60));
|
|
95946
|
-
for (const id of modelIds) {
|
|
95947
|
-
const m2 = status.models[id];
|
|
95948
|
-
const duration3 = m2.startedAt && m2.completedAt ? `${Math.round((new Date(m2.completedAt).getTime() - new Date(m2.startedAt).getTime()) / 1000)}s` : m2.startedAt ? "running" : "pending";
|
|
95949
|
-
const size = m2.outputSize > 0 ? ` (${m2.outputSize} bytes)` : "";
|
|
95950
|
-
console.log(` ${id} ${m2.state.padEnd(10)} ${duration3}${size}`);
|
|
95951
|
-
}
|
|
95952
|
-
console.log("");
|
|
95953
|
-
}
|
|
95954
|
-
function printHelp2() {
|
|
95955
|
-
console.log(`
|
|
95956
|
-
Usage: claudish team <subcommand> [options]
|
|
95957
|
-
|
|
95958
|
-
Subcommands:
|
|
95959
|
-
run Run multiple models on a task in parallel
|
|
95960
|
-
judge Blind-judge existing model outputs
|
|
95961
|
-
run-and-judge Run models then judge their outputs
|
|
95962
|
-
status Show current session status
|
|
95963
|
-
|
|
95964
|
-
Options (run / run-and-judge):
|
|
95965
|
-
--path <dir> Session directory (default: .)
|
|
95966
|
-
--models <a,b,...> Comma-separated model IDs to run
|
|
95967
|
-
--input <text> Task prompt (or create input.md in --path beforehand)
|
|
95968
|
-
--timeout <secs> Timeout per model in seconds (default: 300)
|
|
95969
|
-
--grid Show all models in a magmux grid with live output + status bar
|
|
95970
|
-
|
|
95971
|
-
Options (judge / run-and-judge):
|
|
95972
|
-
--judges <a,b,...> Comma-separated judge model IDs (default: same as runners)
|
|
95973
|
-
|
|
95974
|
-
Options (status):
|
|
95975
|
-
--path <dir> Session directory (default: .)
|
|
95976
|
-
|
|
95977
|
-
Examples:
|
|
95978
|
-
claudish team run --path ./review --models minimax-m2.5,kimi-k2.5 --input "Review this code"
|
|
95979
|
-
claudish team run --grid --models kimi-k2.5,gpt-5.4,gemini-3.1-pro --input "Solve this"
|
|
95980
|
-
claudish team judge --path ./review
|
|
95981
|
-
claudish team run-and-judge --path ./review --models gpt-5.4,gemini-3.1-pro-preview --input "Evaluate this design"
|
|
95982
|
-
claudish team status --path ./review
|
|
95983
|
-
`);
|
|
95984
|
-
}
|
|
95985
|
-
async function teamCommand(args) {
|
|
95986
|
-
if (hasFlag(args, "--help") || hasFlag(args, "-h")) {
|
|
95987
|
-
printHelp2();
|
|
95988
|
-
process.exit(0);
|
|
95989
|
-
}
|
|
95990
|
-
const firstArg = args[0] ?? "";
|
|
95991
|
-
const legacySubs = ["run", "judge", "run-and-judge", "status"];
|
|
95992
|
-
const subcommand = legacySubs.includes(firstArg) ? firstArg : "run";
|
|
95993
|
-
const rawSessionPath = getFlag(args, "--path") ?? ".";
|
|
95994
|
-
let sessionPath;
|
|
95995
|
-
try {
|
|
95996
|
-
sessionPath = validateSessionPath(rawSessionPath);
|
|
95997
|
-
} catch (err) {
|
|
95998
|
-
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
95999
|
-
process.exit(1);
|
|
96000
|
-
}
|
|
96001
|
-
const modelsRaw = getFlag(args, "--models");
|
|
96002
|
-
const judgesRaw = getFlag(args, "--judges");
|
|
96003
|
-
const mode = getFlag(args, "--mode") ?? "default";
|
|
96004
|
-
const timeoutStr = getFlag(args, "--timeout");
|
|
96005
|
-
const timeout = timeoutStr ? parseInt(timeoutStr, 10) : 300;
|
|
96006
|
-
let input = getFlag(args, "--input");
|
|
96007
|
-
if (!input) {
|
|
96008
|
-
const flagsWithValues = ["--models", "--judges", "--mode", "--path", "--timeout", "--input"];
|
|
96009
|
-
const positionals = args.filter((a, i) => {
|
|
96010
|
-
if (legacySubs.includes(a) && i === 0)
|
|
96011
|
-
return false;
|
|
96012
|
-
if (a.startsWith("--"))
|
|
96013
|
-
return false;
|
|
96014
|
-
const prev = args[i - 1];
|
|
96015
|
-
if (prev && flagsWithValues.includes(prev))
|
|
96016
|
-
return false;
|
|
96017
|
-
return true;
|
|
96018
|
-
});
|
|
96019
|
-
if (positionals.length > 0)
|
|
96020
|
-
input = positionals.join(" ");
|
|
96021
|
-
}
|
|
96022
|
-
const models = modelsRaw ? modelsRaw.split(",").map((m2) => m2.trim()).filter(Boolean) : [];
|
|
96023
|
-
const judges = judgesRaw ? judgesRaw.split(",").map((m2) => m2.trim()).filter(Boolean) : undefined;
|
|
96024
|
-
const effectiveMode = hasFlag(args, "--interactive") ? "interactive" : hasFlag(args, "--grid") ? "default" : mode;
|
|
96025
|
-
switch (subcommand) {
|
|
96026
|
-
case "run": {
|
|
96027
|
-
if (models.length === 0) {
|
|
96028
|
-
console.error("Error: --models is required");
|
|
96029
|
-
printHelp2();
|
|
96030
|
-
process.exit(1);
|
|
96031
|
-
}
|
|
96032
|
-
if (effectiveMode === "json") {
|
|
96033
|
-
setupSession(sessionPath, models, input);
|
|
96034
|
-
const runStatus = await runModels(sessionPath, {
|
|
96035
|
-
timeout,
|
|
96036
|
-
onStatusChange: (id, s) => {
|
|
96037
|
-
process.stderr.write(`[team] ${id}: ${s.state}
|
|
96038
|
-
`);
|
|
96039
|
-
}
|
|
96040
|
-
});
|
|
96041
|
-
printStatus(runStatus);
|
|
96042
|
-
} else {
|
|
96043
|
-
const { runWithGrid: runWithGrid2 } = await Promise.resolve().then(() => (init_team_grid(), exports_team_grid));
|
|
96044
|
-
const interactive = effectiveMode === "interactive";
|
|
96045
|
-
const gridStatus = await runWithGrid2(sessionPath, models, input ?? "", { timeout, interactive });
|
|
96046
|
-
printStatus(gridStatus);
|
|
96047
|
-
}
|
|
96048
|
-
break;
|
|
96049
|
-
}
|
|
96050
|
-
case "judge": {
|
|
96051
|
-
await judgeResponses(sessionPath, { judges });
|
|
96052
|
-
console.log(readFileSync22(join28(sessionPath, "verdict.md"), "utf-8"));
|
|
96053
|
-
break;
|
|
96054
|
-
}
|
|
96055
|
-
case "run-and-judge": {
|
|
96056
|
-
if (models.length === 0) {
|
|
96057
|
-
console.error("Error: --models is required");
|
|
96058
|
-
process.exit(1);
|
|
96059
|
-
}
|
|
96060
|
-
setupSession(sessionPath, models, input);
|
|
96061
|
-
const status = await runModels(sessionPath, {
|
|
96062
|
-
timeout,
|
|
96063
|
-
onStatusChange: (id, s) => {
|
|
96064
|
-
process.stderr.write(`[team] ${id}: ${s.state}
|
|
96065
|
-
`);
|
|
96066
|
-
}
|
|
96067
|
-
});
|
|
96068
|
-
printStatus(status);
|
|
96069
|
-
await judgeResponses(sessionPath, { judges });
|
|
96070
|
-
console.log(readFileSync22(join28(sessionPath, "verdict.md"), "utf-8"));
|
|
96071
|
-
break;
|
|
96072
|
-
}
|
|
96073
|
-
case "status": {
|
|
96074
|
-
const statusResult = getStatus(sessionPath);
|
|
96075
|
-
printStatus(statusResult);
|
|
96076
|
-
break;
|
|
96077
|
-
}
|
|
96078
|
-
}
|
|
96079
|
-
}
|
|
96080
|
-
var init_team_cli = __esm(() => {
|
|
96081
|
-
init_team_orchestrator();
|
|
96082
|
-
});
|
|
96083
|
-
|
|
96084
95669
|
// src/claude-runner.ts
|
|
96085
95670
|
var exports_claude_runner = {};
|
|
96086
95671
|
__export(exports_claude_runner, {
|
|
96087
95672
|
runClaudeWithProxy: () => runClaudeWithProxy,
|
|
96088
95673
|
checkClaudeInstalled: () => checkClaudeInstalled
|
|
96089
95674
|
});
|
|
96090
|
-
import { spawn as
|
|
96091
|
-
import { writeFileSync as
|
|
95675
|
+
import { spawn as spawn3 } from "child_process";
|
|
95676
|
+
import { writeFileSync as writeFileSync15, unlinkSync as unlinkSync8, mkdirSync as mkdirSync14, existsSync as existsSync26, readFileSync as readFileSync21 } from "fs";
|
|
96092
95677
|
import { tmpdir as tmpdir2, homedir as homedir25 } from "os";
|
|
96093
|
-
import { join as
|
|
95678
|
+
import { join as join27 } from "path";
|
|
96094
95679
|
function hasNativeAnthropicMapping(config3) {
|
|
96095
95680
|
const models = [
|
|
96096
95681
|
config3.model,
|
|
@@ -96106,9 +95691,9 @@ function isWindows2() {
|
|
|
96106
95691
|
}
|
|
96107
95692
|
function createStatusLineScript(tokenFilePath) {
|
|
96108
95693
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
|
|
96109
|
-
const claudishDir =
|
|
95694
|
+
const claudishDir = join27(homeDir, ".claudish");
|
|
96110
95695
|
const timestamp = Date.now();
|
|
96111
|
-
const scriptPath =
|
|
95696
|
+
const scriptPath = join27(claudishDir, `status-${timestamp}.js`);
|
|
96112
95697
|
const escapedTokenPath = tokenFilePath.replace(/\\/g, "\\\\");
|
|
96113
95698
|
const script = `
|
|
96114
95699
|
const fs = require('fs');
|
|
@@ -96197,18 +95782,18 @@ process.stdin.on('end', () => {
|
|
|
96197
95782
|
}
|
|
96198
95783
|
});
|
|
96199
95784
|
`;
|
|
96200
|
-
|
|
95785
|
+
writeFileSync15(scriptPath, script, "utf-8");
|
|
96201
95786
|
return scriptPath;
|
|
96202
95787
|
}
|
|
96203
95788
|
function createTempSettingsFile(modelDisplay, port) {
|
|
96204
95789
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
|
|
96205
|
-
const claudishDir =
|
|
95790
|
+
const claudishDir = join27(homeDir, ".claudish");
|
|
96206
95791
|
try {
|
|
96207
|
-
|
|
95792
|
+
mkdirSync14(claudishDir, { recursive: true });
|
|
96208
95793
|
} catch {}
|
|
96209
95794
|
const timestamp = Date.now();
|
|
96210
|
-
const tempPath =
|
|
96211
|
-
const tokenFilePath =
|
|
95795
|
+
const tempPath = join27(claudishDir, `settings-${timestamp}.json`);
|
|
95796
|
+
const tokenFilePath = join27(claudishDir, `tokens-${port}.json`);
|
|
96212
95797
|
let statusCommand;
|
|
96213
95798
|
if (isWindows2()) {
|
|
96214
95799
|
const scriptPath = createStatusLineScript(tokenFilePath);
|
|
@@ -96230,7 +95815,7 @@ function createTempSettingsFile(modelDisplay, port) {
|
|
|
96230
95815
|
padding: 0
|
|
96231
95816
|
};
|
|
96232
95817
|
const settings = { statusLine };
|
|
96233
|
-
|
|
95818
|
+
writeFileSync15(tempPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
96234
95819
|
return { path: tempPath, statusLine };
|
|
96235
95820
|
}
|
|
96236
95821
|
function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine) {
|
|
@@ -96244,11 +95829,11 @@ function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine) {
|
|
|
96244
95829
|
if (userSettingsValue.trimStart().startsWith("{")) {
|
|
96245
95830
|
userSettings = JSON.parse(userSettingsValue);
|
|
96246
95831
|
} else {
|
|
96247
|
-
const rawUserSettings =
|
|
95832
|
+
const rawUserSettings = readFileSync21(userSettingsValue, "utf-8");
|
|
96248
95833
|
userSettings = JSON.parse(rawUserSettings);
|
|
96249
95834
|
}
|
|
96250
95835
|
userSettings.statusLine = statusLine;
|
|
96251
|
-
|
|
95836
|
+
writeFileSync15(tempSettingsPath, JSON.stringify(userSettings, null, 2), "utf-8");
|
|
96252
95837
|
} catch {
|
|
96253
95838
|
if (!config3.quiet) {
|
|
96254
95839
|
console.warn(`[claudish] Warning: could not merge user settings: ${userSettingsValue}`);
|
|
@@ -96337,13 +95922,13 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
|
|
|
96337
95922
|
console.error(`
|
|
96338
95923
|
Or set CLAUDE_PATH to your custom installation:`);
|
|
96339
95924
|
const home = homedir25();
|
|
96340
|
-
const localPath = isWindows2() ?
|
|
95925
|
+
const localPath = isWindows2() ? join27(home, ".claude", "local", "claude.exe") : join27(home, ".claude", "local", "claude");
|
|
96341
95926
|
console.error(` export CLAUDE_PATH=${localPath}`);
|
|
96342
95927
|
process.exit(1);
|
|
96343
95928
|
}
|
|
96344
95929
|
const needsShell = isWindows2() && claudeBinary.endsWith(".cmd");
|
|
96345
95930
|
const spawnCommand = needsShell ? `"${claudeBinary}"` : claudeBinary;
|
|
96346
|
-
const proc =
|
|
95931
|
+
const proc = spawn3(spawnCommand, claudeArgs, {
|
|
96347
95932
|
env: env2,
|
|
96348
95933
|
stdio: "inherit",
|
|
96349
95934
|
shell: needsShell
|
|
@@ -96355,7 +95940,7 @@ Or set CLAUDE_PATH to your custom installation:`);
|
|
|
96355
95940
|
});
|
|
96356
95941
|
});
|
|
96357
95942
|
try {
|
|
96358
|
-
|
|
95943
|
+
unlinkSync8(tempSettingsPath);
|
|
96359
95944
|
} catch {}
|
|
96360
95945
|
return exitCode;
|
|
96361
95946
|
}
|
|
@@ -96374,7 +95959,7 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
|
|
|
96374
95959
|
} catch {}
|
|
96375
95960
|
}
|
|
96376
95961
|
try {
|
|
96377
|
-
|
|
95962
|
+
unlinkSync8(tempSettingsPath);
|
|
96378
95963
|
} catch {}
|
|
96379
95964
|
process.exit(0);
|
|
96380
95965
|
});
|
|
@@ -96383,23 +95968,23 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
|
|
|
96383
95968
|
async function findClaudeBinary() {
|
|
96384
95969
|
const isWindows3 = process.platform === "win32";
|
|
96385
95970
|
if (process.env.CLAUDE_PATH) {
|
|
96386
|
-
if (
|
|
95971
|
+
if (existsSync26(process.env.CLAUDE_PATH)) {
|
|
96387
95972
|
return process.env.CLAUDE_PATH;
|
|
96388
95973
|
}
|
|
96389
95974
|
}
|
|
96390
95975
|
const home = homedir25();
|
|
96391
|
-
const localPath = isWindows3 ?
|
|
96392
|
-
if (
|
|
95976
|
+
const localPath = isWindows3 ? join27(home, ".claude", "local", "claude.exe") : join27(home, ".claude", "local", "claude");
|
|
95977
|
+
if (existsSync26(localPath)) {
|
|
96393
95978
|
return localPath;
|
|
96394
95979
|
}
|
|
96395
95980
|
if (isWindows3) {
|
|
96396
95981
|
const windowsPaths = [
|
|
96397
|
-
|
|
96398
|
-
|
|
96399
|
-
|
|
95982
|
+
join27(home, "AppData", "Roaming", "npm", "claude.cmd"),
|
|
95983
|
+
join27(home, ".npm-global", "claude.cmd"),
|
|
95984
|
+
join27(home, "node_modules", ".bin", "claude.cmd")
|
|
96400
95985
|
];
|
|
96401
95986
|
for (const path2 of windowsPaths) {
|
|
96402
|
-
if (
|
|
95987
|
+
if (existsSync26(path2)) {
|
|
96403
95988
|
return path2;
|
|
96404
95989
|
}
|
|
96405
95990
|
}
|
|
@@ -96407,21 +95992,21 @@ async function findClaudeBinary() {
|
|
|
96407
95992
|
const commonPaths = [
|
|
96408
95993
|
"/usr/local/bin/claude",
|
|
96409
95994
|
"/opt/homebrew/bin/claude",
|
|
96410
|
-
|
|
96411
|
-
|
|
96412
|
-
|
|
95995
|
+
join27(home, ".npm-global/bin/claude"),
|
|
95996
|
+
join27(home, ".local/bin/claude"),
|
|
95997
|
+
join27(home, "node_modules/.bin/claude"),
|
|
96413
95998
|
"/data/data/com.termux/files/usr/bin/claude",
|
|
96414
|
-
|
|
95999
|
+
join27(home, "../usr/bin/claude")
|
|
96415
96000
|
];
|
|
96416
96001
|
for (const path2 of commonPaths) {
|
|
96417
|
-
if (
|
|
96002
|
+
if (existsSync26(path2)) {
|
|
96418
96003
|
return path2;
|
|
96419
96004
|
}
|
|
96420
96005
|
}
|
|
96421
96006
|
}
|
|
96422
96007
|
try {
|
|
96423
96008
|
const shellCommand = isWindows3 ? "where claude" : "command -v claude";
|
|
96424
|
-
const proc =
|
|
96009
|
+
const proc = spawn3(shellCommand, [], {
|
|
96425
96010
|
stdio: "pipe",
|
|
96426
96011
|
shell: true
|
|
96427
96012
|
});
|
|
@@ -96463,18 +96048,18 @@ __export(exports_diag_output, {
|
|
|
96463
96048
|
NullDiagOutput: () => NullDiagOutput,
|
|
96464
96049
|
LogFileDiagOutput: () => LogFileDiagOutput
|
|
96465
96050
|
});
|
|
96466
|
-
import { createWriteStream as createWriteStream3, mkdirSync as
|
|
96051
|
+
import { createWriteStream as createWriteStream3, mkdirSync as mkdirSync15, writeFileSync as writeFileSync16, unlinkSync as unlinkSync9 } from "fs";
|
|
96467
96052
|
import { homedir as homedir26 } from "os";
|
|
96468
|
-
import { join as
|
|
96053
|
+
import { join as join28 } from "path";
|
|
96469
96054
|
function getClaudishDir() {
|
|
96470
|
-
const dir =
|
|
96055
|
+
const dir = join28(homedir26(), ".claudish");
|
|
96471
96056
|
try {
|
|
96472
|
-
|
|
96057
|
+
mkdirSync15(dir, { recursive: true });
|
|
96473
96058
|
} catch {}
|
|
96474
96059
|
return dir;
|
|
96475
96060
|
}
|
|
96476
96061
|
function getDiagLogPath() {
|
|
96477
|
-
return
|
|
96062
|
+
return join28(getClaudishDir(), `diag-${process.pid}.log`);
|
|
96478
96063
|
}
|
|
96479
96064
|
|
|
96480
96065
|
class LogFileDiagOutput {
|
|
@@ -96483,7 +96068,7 @@ class LogFileDiagOutput {
|
|
|
96483
96068
|
constructor() {
|
|
96484
96069
|
this.logPath = getDiagLogPath();
|
|
96485
96070
|
try {
|
|
96486
|
-
|
|
96071
|
+
writeFileSync16(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
|
|
96487
96072
|
`);
|
|
96488
96073
|
} catch {}
|
|
96489
96074
|
this.stream = createWriteStream3(this.logPath, { flags: "a" });
|
|
@@ -96502,7 +96087,7 @@ class LogFileDiagOutput {
|
|
|
96502
96087
|
this.stream.end();
|
|
96503
96088
|
} catch {}
|
|
96504
96089
|
try {
|
|
96505
|
-
|
|
96090
|
+
unlinkSync9(this.logPath);
|
|
96506
96091
|
} catch {}
|
|
96507
96092
|
}
|
|
96508
96093
|
getLogPath() {
|
|
@@ -96526,18 +96111,274 @@ function createDiagOutput(options) {
|
|
|
96526
96111
|
}
|
|
96527
96112
|
var init_diag_output = () => {};
|
|
96528
96113
|
|
|
96114
|
+
// src/team-grid.ts
|
|
96115
|
+
var exports_team_grid = {};
|
|
96116
|
+
__export(exports_team_grid, {
|
|
96117
|
+
runWithGrid: () => runWithGrid
|
|
96118
|
+
});
|
|
96119
|
+
import { spawn as spawn4 } from "child_process";
|
|
96120
|
+
import {
|
|
96121
|
+
appendFileSync,
|
|
96122
|
+
existsSync as existsSync28,
|
|
96123
|
+
mkdirSync as mkdirSync16,
|
|
96124
|
+
readFileSync as readFileSync22,
|
|
96125
|
+
unlinkSync as unlinkSync10,
|
|
96126
|
+
writeFileSync as writeFileSync17
|
|
96127
|
+
} from "fs";
|
|
96128
|
+
import { dirname as dirname6, join as join29 } from "path";
|
|
96129
|
+
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
96130
|
+
import { execSync as execSync3 } from "child_process";
|
|
96131
|
+
function formatElapsed(ms) {
|
|
96132
|
+
const s = Math.floor(ms / 1000);
|
|
96133
|
+
if (s < 60)
|
|
96134
|
+
return `${s}s`;
|
|
96135
|
+
const m2 = Math.floor(s / 60);
|
|
96136
|
+
const rem = s % 60;
|
|
96137
|
+
return `${m2}m ${rem}s`;
|
|
96138
|
+
}
|
|
96139
|
+
function findMagmuxBinary() {
|
|
96140
|
+
const thisFile = fileURLToPath6(import.meta.url);
|
|
96141
|
+
const thisDir = dirname6(thisFile);
|
|
96142
|
+
const pkgRoot = join29(thisDir, "..");
|
|
96143
|
+
const platform3 = process.platform;
|
|
96144
|
+
const arch = process.arch;
|
|
96145
|
+
const builtMagmux = join29(pkgRoot, "native", "magmux", "magmux");
|
|
96146
|
+
if (existsSync28(builtMagmux))
|
|
96147
|
+
return builtMagmux;
|
|
96148
|
+
const bundledMagmux = join29(pkgRoot, "native", "magmux", `magmux-${platform3}-${arch}`);
|
|
96149
|
+
if (existsSync28(bundledMagmux))
|
|
96150
|
+
return bundledMagmux;
|
|
96151
|
+
try {
|
|
96152
|
+
const pkgName = `@claudish/magmux-${platform3}-${arch}`;
|
|
96153
|
+
let searchDir = pkgRoot;
|
|
96154
|
+
for (let i = 0;i < 5; i++) {
|
|
96155
|
+
const candidate = join29(searchDir, "node_modules", pkgName, "bin", "magmux");
|
|
96156
|
+
if (existsSync28(candidate))
|
|
96157
|
+
return candidate;
|
|
96158
|
+
const parent = dirname6(searchDir);
|
|
96159
|
+
if (parent === searchDir)
|
|
96160
|
+
break;
|
|
96161
|
+
searchDir = parent;
|
|
96162
|
+
}
|
|
96163
|
+
} catch {}
|
|
96164
|
+
try {
|
|
96165
|
+
const result = execSync3("which magmux", { encoding: "utf-8" }).trim();
|
|
96166
|
+
if (result)
|
|
96167
|
+
return result;
|
|
96168
|
+
} catch {}
|
|
96169
|
+
throw new Error(`magmux not found. Install it:
|
|
96170
|
+
brew install MadAppGang/tap/magmux`);
|
|
96171
|
+
}
|
|
96172
|
+
function renderGridStatusBar(counts) {
|
|
96173
|
+
const elapsed = formatElapsed(counts.elapsedMs);
|
|
96174
|
+
const { done, running, failed, total, allDone } = counts;
|
|
96175
|
+
if (allDone) {
|
|
96176
|
+
if (failed > 0) {
|
|
96177
|
+
return [
|
|
96178
|
+
"C: claudish team",
|
|
96179
|
+
`G: ${done} done`,
|
|
96180
|
+
`R: ${failed} failed`,
|
|
96181
|
+
`D: ${elapsed}`,
|
|
96182
|
+
"R: \u2717 issues",
|
|
96183
|
+
"D: ctrl-g q to quit"
|
|
96184
|
+
].join("\t");
|
|
96185
|
+
}
|
|
96186
|
+
return [
|
|
96187
|
+
"C: claudish team",
|
|
96188
|
+
`G: ${total} done`,
|
|
96189
|
+
`D: ${elapsed}`,
|
|
96190
|
+
"G: \u2713 complete",
|
|
96191
|
+
"D: ctrl-g q to quit"
|
|
96192
|
+
].join("\t");
|
|
96193
|
+
}
|
|
96194
|
+
return [
|
|
96195
|
+
"C: claudish team",
|
|
96196
|
+
`G: ${done} done`,
|
|
96197
|
+
`C: ${running} running`,
|
|
96198
|
+
`R: ${failed} failed`,
|
|
96199
|
+
`D: ${elapsed}`
|
|
96200
|
+
].join("\t");
|
|
96201
|
+
}
|
|
96202
|
+
function pollStatus(state) {
|
|
96203
|
+
const { statusCache, statusPath, sessionPath, anonIds, startTime, timeoutMs, statusbarPath } = state;
|
|
96204
|
+
const elapsedMs = Date.now() - startTime;
|
|
96205
|
+
let changed = false;
|
|
96206
|
+
let done = 0;
|
|
96207
|
+
let running = 0;
|
|
96208
|
+
let failed = 0;
|
|
96209
|
+
for (const anonId of anonIds) {
|
|
96210
|
+
const current = statusCache.models[anonId];
|
|
96211
|
+
if (current.state === "COMPLETED" || current.state === "FAILED" || current.state === "TIMEOUT") {
|
|
96212
|
+
if (current.state === "COMPLETED")
|
|
96213
|
+
done++;
|
|
96214
|
+
else
|
|
96215
|
+
failed++;
|
|
96216
|
+
continue;
|
|
96217
|
+
}
|
|
96218
|
+
const exitCodePath = join29(sessionPath, "work", anonId, ".exit-code");
|
|
96219
|
+
if (existsSync28(exitCodePath)) {
|
|
96220
|
+
const codeStr = readFileSync22(exitCodePath, "utf-8").trim();
|
|
96221
|
+
const code = parseInt(codeStr, 10);
|
|
96222
|
+
const isSuccess = code === 0;
|
|
96223
|
+
const newState = {
|
|
96224
|
+
...current,
|
|
96225
|
+
state: isSuccess ? "COMPLETED" : "FAILED",
|
|
96226
|
+
exitCode: code,
|
|
96227
|
+
startedAt: current.startedAt ?? new Date().toISOString(),
|
|
96228
|
+
completedAt: new Date().toISOString(),
|
|
96229
|
+
outputSize: 0
|
|
96230
|
+
};
|
|
96231
|
+
statusCache.models[anonId] = newState;
|
|
96232
|
+
changed = true;
|
|
96233
|
+
if (isSuccess)
|
|
96234
|
+
done++;
|
|
96235
|
+
else
|
|
96236
|
+
failed++;
|
|
96237
|
+
} else {
|
|
96238
|
+
if (!state.interactive && elapsedMs > timeoutMs) {
|
|
96239
|
+
const newState = {
|
|
96240
|
+
...current,
|
|
96241
|
+
state: "TIMEOUT",
|
|
96242
|
+
startedAt: current.startedAt ?? new Date().toISOString(),
|
|
96243
|
+
completedAt: new Date().toISOString(),
|
|
96244
|
+
outputSize: 0
|
|
96245
|
+
};
|
|
96246
|
+
statusCache.models[anonId] = newState;
|
|
96247
|
+
changed = true;
|
|
96248
|
+
failed++;
|
|
96249
|
+
} else {
|
|
96250
|
+
if (current.state === "PENDING" && elapsedMs > 1000) {
|
|
96251
|
+
statusCache.models[anonId] = {
|
|
96252
|
+
...current,
|
|
96253
|
+
state: "RUNNING",
|
|
96254
|
+
startedAt: current.startedAt ?? new Date().toISOString()
|
|
96255
|
+
};
|
|
96256
|
+
changed = true;
|
|
96257
|
+
}
|
|
96258
|
+
running++;
|
|
96259
|
+
}
|
|
96260
|
+
}
|
|
96261
|
+
}
|
|
96262
|
+
if (changed) {
|
|
96263
|
+
writeFileSync17(statusPath, JSON.stringify(statusCache, null, 2), "utf-8");
|
|
96264
|
+
}
|
|
96265
|
+
const total = anonIds.length;
|
|
96266
|
+
const allDone = done + failed >= total;
|
|
96267
|
+
if (allDone && !state.completedAtMs) {
|
|
96268
|
+
state.completedAtMs = elapsedMs;
|
|
96269
|
+
}
|
|
96270
|
+
const counts = {
|
|
96271
|
+
done,
|
|
96272
|
+
running,
|
|
96273
|
+
failed,
|
|
96274
|
+
total,
|
|
96275
|
+
elapsedMs: state.completedAtMs ?? elapsedMs,
|
|
96276
|
+
allDone
|
|
96277
|
+
};
|
|
96278
|
+
appendFileSync(statusbarPath, renderGridStatusBar(counts) + `
|
|
96279
|
+
`);
|
|
96280
|
+
return allDone;
|
|
96281
|
+
}
|
|
96282
|
+
async function runWithGrid(sessionPath, models, input, opts) {
|
|
96283
|
+
const timeoutMs = (opts?.timeout ?? 300) * 1000;
|
|
96284
|
+
const interactive = opts?.interactive ?? false;
|
|
96285
|
+
const manifest = setupSession(sessionPath, models, input);
|
|
96286
|
+
mkdirSync16(join29(sessionPath, "errors"), { recursive: true });
|
|
96287
|
+
for (const anonId of Object.keys(manifest.models)) {
|
|
96288
|
+
const stale = join29(sessionPath, "work", anonId, ".exit-code");
|
|
96289
|
+
try {
|
|
96290
|
+
unlinkSync10(stale);
|
|
96291
|
+
} catch {}
|
|
96292
|
+
}
|
|
96293
|
+
const gridfilePath = join29(sessionPath, "gridfile.txt");
|
|
96294
|
+
const prompt = readFileSync22(join29(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''").replace(/\n/g, " ");
|
|
96295
|
+
const gridLines = Object.entries(manifest.models).map(([anonId]) => {
|
|
96296
|
+
const errorLog = join29(sessionPath, "errors", `${anonId}.log`);
|
|
96297
|
+
const exitCodeFile = join29(sessionPath, "work", anonId, ".exit-code");
|
|
96298
|
+
const model = manifest.models[anonId].model;
|
|
96299
|
+
const paneIndex = Object.keys(manifest.models).indexOf(anonId);
|
|
96300
|
+
if (interactive) {
|
|
96301
|
+
return `claudish --model ${model} --dangerously-skip-permissions '${prompt}'`;
|
|
96302
|
+
}
|
|
96303
|
+
return [
|
|
96304
|
+
`claudish --model ${model} -y -v '${prompt}' 2>${errorLog};`,
|
|
96305
|
+
`_ec=$?; echo $_ec > ${exitCodeFile};`,
|
|
96306
|
+
`if [ -n "$MAGMUX_SOCK" ]; then`,
|
|
96307
|
+
` if [ $_ec -eq 0 ]; then`,
|
|
96308
|
+
` echo '{"cmd":"tint","pane":${paneIndex},"color":"green"}' | nc -U "$MAGMUX_SOCK" -w 1 2>/dev/null;`,
|
|
96309
|
+
` echo '{"cmd":"overlay","pane":${paneIndex},"text":"DONE","color":"green"}' | nc -U "$MAGMUX_SOCK" -w 1 2>/dev/null;`,
|
|
96310
|
+
` else`,
|
|
96311
|
+
` echo '{"cmd":"tint","pane":${paneIndex},"color":"red"}' | nc -U "$MAGMUX_SOCK" -w 1 2>/dev/null;`,
|
|
96312
|
+
` echo '{"cmd":"overlay","pane":${paneIndex},"text":"FAIL","color":"red"}' | nc -U "$MAGMUX_SOCK" -w 1 2>/dev/null;`,
|
|
96313
|
+
` fi;`,
|
|
96314
|
+
`fi;`,
|
|
96315
|
+
`exec sleep 86400`
|
|
96316
|
+
].join(" ");
|
|
96317
|
+
});
|
|
96318
|
+
writeFileSync17(gridfilePath, gridLines.join(`
|
|
96319
|
+
`) + `
|
|
96320
|
+
`, "utf-8");
|
|
96321
|
+
const magmuxPath = findMagmuxBinary();
|
|
96322
|
+
const statusbarPath = join29(sessionPath, "statusbar.txt");
|
|
96323
|
+
const statusPath = join29(sessionPath, "status.json");
|
|
96324
|
+
const statusCache = JSON.parse(readFileSync22(statusPath, "utf-8"));
|
|
96325
|
+
const anonIds = Object.keys(manifest.models);
|
|
96326
|
+
const startTime = Date.now();
|
|
96327
|
+
appendFileSync(statusbarPath, renderGridStatusBar({
|
|
96328
|
+
done: 0,
|
|
96329
|
+
running: 0,
|
|
96330
|
+
failed: 0,
|
|
96331
|
+
total: anonIds.length,
|
|
96332
|
+
elapsedMs: 0,
|
|
96333
|
+
allDone: false
|
|
96334
|
+
}) + `
|
|
96335
|
+
`);
|
|
96336
|
+
const pollState = {
|
|
96337
|
+
statusCache,
|
|
96338
|
+
statusPath,
|
|
96339
|
+
sessionPath,
|
|
96340
|
+
anonIds,
|
|
96341
|
+
startTime,
|
|
96342
|
+
timeoutMs,
|
|
96343
|
+
statusbarPath,
|
|
96344
|
+
completedAtMs: null,
|
|
96345
|
+
interactive
|
|
96346
|
+
};
|
|
96347
|
+
const pollInterval = setInterval(() => {
|
|
96348
|
+
pollStatus(pollState);
|
|
96349
|
+
}, 500);
|
|
96350
|
+
const spawnArgs = ["-g", gridfilePath, "-S", statusbarPath];
|
|
96351
|
+
if (!interactive) {
|
|
96352
|
+
spawnArgs.push("-w");
|
|
96353
|
+
}
|
|
96354
|
+
const proc = spawn4(magmuxPath, spawnArgs, {
|
|
96355
|
+
stdio: "inherit",
|
|
96356
|
+
env: { ...process.env }
|
|
96357
|
+
});
|
|
96358
|
+
await new Promise((resolve4) => {
|
|
96359
|
+
proc.on("exit", () => resolve4());
|
|
96360
|
+
proc.on("error", () => resolve4());
|
|
96361
|
+
});
|
|
96362
|
+
clearInterval(pollInterval);
|
|
96363
|
+
pollStatus(pollState);
|
|
96364
|
+
return JSON.parse(readFileSync22(statusPath, "utf-8"));
|
|
96365
|
+
}
|
|
96366
|
+
var init_team_grid = __esm(() => {
|
|
96367
|
+
init_team_orchestrator();
|
|
96368
|
+
});
|
|
96369
|
+
|
|
96529
96370
|
// src/index.ts
|
|
96530
96371
|
var import_dotenv3 = __toESM(require_main(), 1);
|
|
96531
|
-
import { existsSync as existsSync29, readFileSync as
|
|
96372
|
+
import { existsSync as existsSync29, readFileSync as readFileSync23 } from "fs";
|
|
96532
96373
|
import { homedir as homedir27 } from "os";
|
|
96533
|
-
import { join as
|
|
96374
|
+
import { join as join30 } from "path";
|
|
96534
96375
|
import_dotenv3.config({ quiet: true });
|
|
96535
96376
|
function loadStoredApiKeys() {
|
|
96536
96377
|
try {
|
|
96537
|
-
const configPath =
|
|
96378
|
+
const configPath = join30(homedir27(), ".claudish", "config.json");
|
|
96538
96379
|
if (!existsSync29(configPath))
|
|
96539
96380
|
return;
|
|
96540
|
-
const raw2 =
|
|
96381
|
+
const raw2 = readFileSync23(configPath, "utf-8");
|
|
96541
96382
|
const cfg = JSON.parse(raw2);
|
|
96542
96383
|
if (cfg.apiKeys) {
|
|
96543
96384
|
for (const [envVar, value] of Object.entries(cfg.apiKeys)) {
|
|
@@ -96572,7 +96413,6 @@ var firstPositional = args.find((a) => !a.startsWith("-"));
|
|
|
96572
96413
|
var isTelemetryCommand = firstPositional === "telemetry";
|
|
96573
96414
|
var isStatsCommand = firstPositional === "stats";
|
|
96574
96415
|
var isConfigCommand = firstPositional === "config";
|
|
96575
|
-
var isTeamCommand = firstPositional === "team";
|
|
96576
96416
|
var isLoginCommand = firstPositional === "login";
|
|
96577
96417
|
var isLogoutCommand = firstPositional === "logout";
|
|
96578
96418
|
var isQuotaCommand = firstPositional === "quota" || firstPositional === "usage";
|
|
@@ -96621,8 +96461,6 @@ if (isMcpMode) {
|
|
|
96621
96461
|
});
|
|
96622
96462
|
} else if (isConfigCommand) {
|
|
96623
96463
|
init_tui().then(() => exports_tui).then((m2) => m2.startConfigTui().catch(handlePromptExit));
|
|
96624
|
-
} else if (isTeamCommand) {
|
|
96625
|
-
Promise.resolve().then(() => (init_team_cli(), exports_team_cli)).then((m2) => m2.teamCommand(args.slice(1)));
|
|
96626
96464
|
} else {
|
|
96627
96465
|
runCli();
|
|
96628
96466
|
}
|
|
@@ -96651,6 +96489,32 @@ async function runCli() {
|
|
|
96651
96489
|
}
|
|
96652
96490
|
try {
|
|
96653
96491
|
const cliConfig = await parseArgs2(process.argv.slice(2));
|
|
96492
|
+
if (cliConfig.team && cliConfig.team.length > 0) {
|
|
96493
|
+
const { runWithGrid: runWithGrid2 } = await Promise.resolve().then(() => (init_team_grid(), exports_team_grid));
|
|
96494
|
+
let prompt = cliConfig.claudeArgs.join(" ");
|
|
96495
|
+
if (cliConfig.inputFile) {
|
|
96496
|
+
prompt = readFileSync23(cliConfig.inputFile, "utf-8");
|
|
96497
|
+
}
|
|
96498
|
+
if (!prompt.trim()) {
|
|
96499
|
+
console.error("Error: --team requires a prompt (positional args or -f <file>)");
|
|
96500
|
+
process.exit(1);
|
|
96501
|
+
}
|
|
96502
|
+
const interactive = cliConfig.teamMode !== "json";
|
|
96503
|
+
const sessionPath = join30(process.cwd(), `.claudish-team-${Date.now()}`);
|
|
96504
|
+
const status = await runWithGrid2(sessionPath, cliConfig.team, prompt, {
|
|
96505
|
+
timeout: 300,
|
|
96506
|
+
interactive
|
|
96507
|
+
});
|
|
96508
|
+
const modelIds = Object.keys(status.models).sort();
|
|
96509
|
+
console.log(`
|
|
96510
|
+
Team Status`);
|
|
96511
|
+
for (const id of modelIds) {
|
|
96512
|
+
const m2 = status.models[id];
|
|
96513
|
+
const duration3 = m2.startedAt && m2.completedAt ? `${Math.round((new Date(m2.completedAt).getTime() - new Date(m2.startedAt).getTime()) / 1000)}s` : "pending";
|
|
96514
|
+
console.log(` ${id} ${m2.state.padEnd(10)} ${duration3}`);
|
|
96515
|
+
}
|
|
96516
|
+
process.exit(0);
|
|
96517
|
+
}
|
|
96654
96518
|
const rawArgs = process.argv.slice(2);
|
|
96655
96519
|
const explicitNoAutoApprove = rawArgs.includes("--no-auto-approve");
|
|
96656
96520
|
if (cliConfig.autoApprove && !explicitNoAutoApprove && !cliConfig.stdin) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudish",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.9.0",
|
|
4
4
|
"description": "Run Claude Code with any model - OpenRouter, Ollama, LM Studio & local models",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -59,10 +59,10 @@
|
|
|
59
59
|
"ai"
|
|
60
60
|
],
|
|
61
61
|
"optionalDependencies": {
|
|
62
|
-
"@claudish/magmux-darwin-arm64": "6.
|
|
63
|
-
"@claudish/magmux-darwin-x64": "6.
|
|
64
|
-
"@claudish/magmux-linux-arm64": "6.
|
|
65
|
-
"@claudish/magmux-linux-x64": "6.
|
|
62
|
+
"@claudish/magmux-darwin-arm64": "6.9.0",
|
|
63
|
+
"@claudish/magmux-darwin-x64": "6.9.0",
|
|
64
|
+
"@claudish/magmux-linux-arm64": "6.9.0",
|
|
65
|
+
"@claudish/magmux-linux-x64": "6.9.0"
|
|
66
66
|
},
|
|
67
67
|
"author": "Jack Rudenko <i@madappgang.com>",
|
|
68
68
|
"license": "MIT",
|