claudish 14.1.0 → 14.2.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 +744 -313
- package/package.json +5 -5
- package/skills/claudish-usage/SKILL.md +43 -8
package/dist/index.js
CHANGED
|
@@ -575,7 +575,7 @@ var init_onepassword_config = __esm(() => {
|
|
|
575
575
|
});
|
|
576
576
|
|
|
577
577
|
// src/version.ts
|
|
578
|
-
var VERSION = "14.
|
|
578
|
+
var VERSION = "14.2.0";
|
|
579
579
|
|
|
580
580
|
// src/redact.ts
|
|
581
581
|
function isPlaceholder(value) {
|
|
@@ -747,9 +747,9 @@ function scheduleFlush() {
|
|
|
747
747
|
}
|
|
748
748
|
});
|
|
749
749
|
}
|
|
750
|
-
function rotateOldLogs(dir, keep) {
|
|
750
|
+
function rotateOldLogs(dir, keep, name = "claudish") {
|
|
751
751
|
try {
|
|
752
|
-
const files = readdirSync(dir).filter((f) => f.startsWith(
|
|
752
|
+
const files = readdirSync(dir).filter((f) => f.startsWith(`${name}_`) && f.endsWith(".log")).sort().reverse();
|
|
753
753
|
for (const file of files.slice(keep)) {
|
|
754
754
|
try {
|
|
755
755
|
unlinkSync(join2(dir, file));
|
|
@@ -788,7 +788,7 @@ function redactDeep(val, key) {
|
|
|
788
788
|
return val;
|
|
789
789
|
}
|
|
790
790
|
function isStructuralLogWorthy(msg) {
|
|
791
|
-
return msg.startsWith("[SSE:") || msg.startsWith("[Suppressed]") || msg.startsWith("[Proxy]") || msg.startsWith("[Claude Code]") || msg.startsWith("[Fallback]") || msg.startsWith("[Recovery]") || 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]");
|
|
791
|
+
return msg.startsWith("[SSE:") || msg.startsWith("[Suppressed]") || msg.startsWith("[Proxy]") || msg.startsWith("[Claude Code]") || msg.startsWith("[Fallback]") || msg.startsWith("[mcp]") || msg.startsWith("[recommended]") || msg.startsWith("[catalog]") || msg.startsWith("[effort]") || msg.startsWith("[team]") || msg.startsWith("[Recovery]") || 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]");
|
|
792
792
|
}
|
|
793
793
|
function redactLogLine(message, timestamp) {
|
|
794
794
|
if (message.startsWith("[SSE:")) {
|
|
@@ -805,20 +805,24 @@ function logFileStamp() {
|
|
|
805
805
|
const timestamp = new Date().toISOString().replace(/[:.]/g, "-").split("T").join("_").slice(0, -5);
|
|
806
806
|
return `${timestamp}_${process.pid}`;
|
|
807
807
|
}
|
|
808
|
-
function initLogger(debugMode, level = "info", noLogs = false) {
|
|
808
|
+
function initLogger(debugMode, level = "info", noLogs = false, name = "claudish", keep = 20) {
|
|
809
809
|
if (!noLogs) {
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
810
|
+
try {
|
|
811
|
+
const logsDir = join2(homedir2(), ".claudish", "logs");
|
|
812
|
+
if (!existsSync2(logsDir)) {
|
|
813
|
+
mkdirSync(logsDir, { recursive: true });
|
|
814
|
+
}
|
|
815
|
+
alwaysOnLogPath = join2(logsDir, `${name}_${logFileStamp()}.log`);
|
|
816
|
+
writeFileSync2(alwaysOnLogPath, `Claudish Session Log - ${new Date().toISOString()}
|
|
816
817
|
Mode: structural (content redacted)
|
|
817
818
|
${"=".repeat(60)}
|
|
818
819
|
|
|
819
820
|
`);
|
|
820
|
-
|
|
821
|
-
|
|
821
|
+
rotateOldLogs(logsDir, keep, name);
|
|
822
|
+
scheduleFlush();
|
|
823
|
+
} catch {
|
|
824
|
+
alwaysOnLogPath = null;
|
|
825
|
+
}
|
|
822
826
|
}
|
|
823
827
|
if (debugMode) {
|
|
824
828
|
logLevel = level;
|
|
@@ -6621,6 +6625,25 @@ var init_remote_provider_types = __esm(() => {
|
|
|
6621
6625
|
};
|
|
6622
6626
|
});
|
|
6623
6627
|
|
|
6628
|
+
// src/fs-atomic.ts
|
|
6629
|
+
import { randomUUID } from "crypto";
|
|
6630
|
+
import { mkdirSync as mkdirSync6, renameSync, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
6631
|
+
import { dirname as dirname5 } from "path";
|
|
6632
|
+
function writeFileAtomic(path, text) {
|
|
6633
|
+
mkdirSync6(dirname5(path), { recursive: true });
|
|
6634
|
+
const tmp = `${path}.tmp.${process.pid}.${randomUUID()}`;
|
|
6635
|
+
try {
|
|
6636
|
+
writeFileSync6(tmp, text, "utf-8");
|
|
6637
|
+
renameSync(tmp, path);
|
|
6638
|
+
} catch (error) {
|
|
6639
|
+
try {
|
|
6640
|
+
unlinkSync2(tmp);
|
|
6641
|
+
} catch {}
|
|
6642
|
+
throw error;
|
|
6643
|
+
}
|
|
6644
|
+
}
|
|
6645
|
+
var init_fs_atomic = () => {};
|
|
6646
|
+
|
|
6624
6647
|
// src/providers/connection-wire.ts
|
|
6625
6648
|
function isObject(value) {
|
|
6626
6649
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -6729,9 +6752,9 @@ function normaliseCatalogPayload(data) {
|
|
|
6729
6752
|
}
|
|
6730
6753
|
|
|
6731
6754
|
// src/providers/all-models-cache.ts
|
|
6732
|
-
import { existsSync as existsSync7,
|
|
6755
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7, statSync as statSync2 } from "fs";
|
|
6733
6756
|
import { homedir as homedir9 } from "os";
|
|
6734
|
-
import {
|
|
6757
|
+
import { join as join9 } from "path";
|
|
6735
6758
|
function reasoningStatusOf(entry) {
|
|
6736
6759
|
if (entry.reasoningStatus === "known" || entry.reasoningStatus === "unknown") {
|
|
6737
6760
|
return entry.reasoningStatus;
|
|
@@ -6808,7 +6831,10 @@ function readSidecarRegistry(path) {
|
|
|
6808
6831
|
try {
|
|
6809
6832
|
const raw = JSON.parse(readFileSync7(routeRegistryPathFor(path), "utf-8"));
|
|
6810
6833
|
return typeof raw.generationId === "string" && isRouteRegistry(raw.registry) ? raw : null;
|
|
6811
|
-
} catch {
|
|
6834
|
+
} catch (err) {
|
|
6835
|
+
if (err?.code !== "ENOENT") {
|
|
6836
|
+
log(`[catalog] unreadable route registry for ${path}: ${err instanceof Error ? err.message : String(err)}`);
|
|
6837
|
+
}
|
|
6812
6838
|
return null;
|
|
6813
6839
|
}
|
|
6814
6840
|
}
|
|
@@ -6834,7 +6860,8 @@ function readAllModelsCache(path = ALL_MODELS_CACHE_PATH) {
|
|
|
6834
6860
|
let cache;
|
|
6835
6861
|
try {
|
|
6836
6862
|
cache = parseAllModelsCache(JSON.parse(readFileSync7(path, "utf-8")));
|
|
6837
|
-
} catch {
|
|
6863
|
+
} catch (err) {
|
|
6864
|
+
log(`[catalog] unreadable ${path}: ${err instanceof Error ? err.message : String(err)}`);
|
|
6838
6865
|
cache = null;
|
|
6839
6866
|
}
|
|
6840
6867
|
if (cache && !cache.routeRegistry && side) {
|
|
@@ -6849,20 +6876,20 @@ function readAllModelsCache(path = ALL_MODELS_CACHE_PATH) {
|
|
|
6849
6876
|
return cache;
|
|
6850
6877
|
}
|
|
6851
6878
|
function writeRouteRegistry(routeRegistry, path = ALL_MODELS_CACHE_PATH) {
|
|
6852
|
-
|
|
6853
|
-
writeFileSync6(routeRegistryPathFor(path), JSON.stringify(routeRegistry), "utf-8");
|
|
6879
|
+
writeFileAtomic(routeRegistryPathFor(path), JSON.stringify(routeRegistry));
|
|
6854
6880
|
_readMemo.delete(path);
|
|
6855
6881
|
}
|
|
6856
6882
|
function writeAllModelsCache(data, path = ALL_MODELS_CACHE_PATH) {
|
|
6857
|
-
|
|
6858
|
-
writeFileSync6(path, JSON.stringify(data), "utf-8");
|
|
6883
|
+
writeFileAtomic(path, JSON.stringify(data));
|
|
6859
6884
|
if (data.routeRegistry) {
|
|
6860
|
-
|
|
6885
|
+
writeFileAtomic(routeRegistryPathFor(path), JSON.stringify(data.routeRegistry));
|
|
6861
6886
|
}
|
|
6862
6887
|
_readMemo.delete(path);
|
|
6863
6888
|
}
|
|
6864
6889
|
var ALL_MODELS_CACHE_PATH, _readMemo;
|
|
6865
6890
|
var init_all_models_cache = __esm(() => {
|
|
6891
|
+
init_fs_atomic();
|
|
6892
|
+
init_logger();
|
|
6866
6893
|
init_connection_wire();
|
|
6867
6894
|
ALL_MODELS_CACHE_PATH = join9(homedir9(), ".claudish", "cloud-models-catalog-v3.json");
|
|
6868
6895
|
_readMemo = new Map;
|
|
@@ -12412,9 +12439,9 @@ import {
|
|
|
12412
12439
|
mkdirSync as mkdirSync7,
|
|
12413
12440
|
openSync as openSync2,
|
|
12414
12441
|
readFileSync as readFileSync9,
|
|
12415
|
-
renameSync,
|
|
12442
|
+
renameSync as renameSync2,
|
|
12416
12443
|
statSync as statSync3,
|
|
12417
|
-
unlinkSync as
|
|
12444
|
+
unlinkSync as unlinkSync3,
|
|
12418
12445
|
writeSync as writeSync2
|
|
12419
12446
|
} from "fs";
|
|
12420
12447
|
import { dirname as dirname6 } from "path";
|
|
@@ -12443,10 +12470,10 @@ function writeCredentialFileAtomic(path, data) {
|
|
|
12443
12470
|
} finally {
|
|
12444
12471
|
closeSync2(fd);
|
|
12445
12472
|
}
|
|
12446
|
-
|
|
12473
|
+
renameSync2(tmp, path);
|
|
12447
12474
|
} catch (err) {
|
|
12448
12475
|
try {
|
|
12449
|
-
|
|
12476
|
+
unlinkSync3(tmp);
|
|
12450
12477
|
} catch {}
|
|
12451
12478
|
throw err;
|
|
12452
12479
|
}
|
|
@@ -12562,7 +12589,7 @@ class CredentialFileState {
|
|
|
12562
12589
|
}
|
|
12563
12590
|
const path = this.opts.path();
|
|
12564
12591
|
try {
|
|
12565
|
-
|
|
12592
|
+
unlinkSync3(path);
|
|
12566
12593
|
} catch (err) {
|
|
12567
12594
|
if (err?.code !== "ENOENT")
|
|
12568
12595
|
return "unreadable";
|
|
@@ -12630,7 +12657,7 @@ var init_credential_file = __esm(() => {
|
|
|
12630
12657
|
// src/auth/oauth-manager.ts
|
|
12631
12658
|
import { exec as exec2 } from "child_process";
|
|
12632
12659
|
import { createHash as createHash2, randomBytes as randomBytes2 } from "crypto";
|
|
12633
|
-
import { existsSync as existsSync10, mkdirSync as mkdirSync8, unlinkSync as
|
|
12660
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync8, unlinkSync as unlinkSync4 } from "fs";
|
|
12634
12661
|
import { homedir as homedir12 } from "os";
|
|
12635
12662
|
import { join as join12 } from "path";
|
|
12636
12663
|
import { promisify as promisify2 } from "util";
|
|
@@ -12669,7 +12696,7 @@ class OAuthManager {
|
|
|
12669
12696
|
deleteCredentials() {
|
|
12670
12697
|
const credPath = this.getCredentialsPath();
|
|
12671
12698
|
if (existsSync10(credPath)) {
|
|
12672
|
-
|
|
12699
|
+
unlinkSync4(credPath);
|
|
12673
12700
|
log(`[${this.providerName}] Credentials deleted`);
|
|
12674
12701
|
}
|
|
12675
12702
|
}
|
|
@@ -13133,7 +13160,7 @@ var init_clock = __esm(() => {
|
|
|
13133
13160
|
});
|
|
13134
13161
|
|
|
13135
13162
|
// src/recovery/coordinator.ts
|
|
13136
|
-
import { randomUUID } from "crypto";
|
|
13163
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
13137
13164
|
function hostOf2(endpoint) {
|
|
13138
13165
|
try {
|
|
13139
13166
|
return new URL(endpoint).host || endpoint;
|
|
@@ -13220,7 +13247,7 @@ function joinEpisode(seed) {
|
|
|
13220
13247
|
} else {
|
|
13221
13248
|
const nowPerf = clock.now();
|
|
13222
13249
|
ep = {
|
|
13223
|
-
episodeId:
|
|
13250
|
+
episodeId: randomUUID2(),
|
|
13224
13251
|
key,
|
|
13225
13252
|
providerDisplayName: seed.providerDisplayName,
|
|
13226
13253
|
endpoint: seed.endpoint,
|
|
@@ -13713,7 +13740,7 @@ var init_transient_retry = __esm(() => {
|
|
|
13713
13740
|
});
|
|
13714
13741
|
|
|
13715
13742
|
// src/providers/grok/grok-credentials.ts
|
|
13716
|
-
import { existsSync as existsSync11, readFileSync as readFileSync10, renameSync as
|
|
13743
|
+
import { existsSync as existsSync11, readFileSync as readFileSync10, renameSync as renameSync3, writeFileSync as writeFileSync7 } from "fs";
|
|
13717
13744
|
import { homedir as homedir14 } from "os";
|
|
13718
13745
|
import { join as join14 } from "path";
|
|
13719
13746
|
function grokHome() {
|
|
@@ -13843,7 +13870,7 @@ function persistRefreshedToken(scope, refreshedFrom, next) {
|
|
|
13843
13870
|
const tmp = `${path}.claudish.tmp`;
|
|
13844
13871
|
writeFileSync7(tmp, `${JSON.stringify(parsed, null, 2)}
|
|
13845
13872
|
`, { mode: 384 });
|
|
13846
|
-
|
|
13873
|
+
renameSync3(tmp, path);
|
|
13847
13874
|
}
|
|
13848
13875
|
async function performRefresh(cred) {
|
|
13849
13876
|
if (!cred.refreshToken || !cred.clientId) {
|
|
@@ -30875,7 +30902,7 @@ __export(exports_antigravity, {
|
|
|
30875
30902
|
AntigravityProviderTransport: () => AntigravityProviderTransport,
|
|
30876
30903
|
resolveAntigravityServedModel: () => resolveAntigravityServedModel
|
|
30877
30904
|
});
|
|
30878
|
-
import { randomUUID as
|
|
30905
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
30879
30906
|
function antigravityEndpoint() {
|
|
30880
30907
|
return `${antigravityHost()}/v1internal:streamGenerateContent?alt=sse`;
|
|
30881
30908
|
}
|
|
@@ -31057,7 +31084,7 @@ class AntigravityProviderTransport {
|
|
|
31057
31084
|
const envelope = {
|
|
31058
31085
|
model,
|
|
31059
31086
|
project: this.projectId,
|
|
31060
|
-
user_prompt_id:
|
|
31087
|
+
user_prompt_id: randomUUID3(),
|
|
31061
31088
|
request: innerPayload
|
|
31062
31089
|
};
|
|
31063
31090
|
if (this.tierId && this.tierId !== "free-tier") {
|
|
@@ -31320,7 +31347,7 @@ function redactSecrets2(text) {
|
|
|
31320
31347
|
}
|
|
31321
31348
|
|
|
31322
31349
|
// src/auth/credentials/antigravity-credential.ts
|
|
31323
|
-
import { randomUUID as
|
|
31350
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
31324
31351
|
function createActivityRequestId2() {
|
|
31325
31352
|
return Math.random().toString(36).substring(7);
|
|
31326
31353
|
}
|
|
@@ -31354,7 +31381,7 @@ class AntigravityCredentialProvider {
|
|
|
31354
31381
|
const env = {
|
|
31355
31382
|
model: servedModel,
|
|
31356
31383
|
project: projectId,
|
|
31357
|
-
user_prompt_id:
|
|
31384
|
+
user_prompt_id: randomUUID4(),
|
|
31358
31385
|
request: inner
|
|
31359
31386
|
};
|
|
31360
31387
|
if (tierId && tierId !== "free-tier") {
|
|
@@ -31642,7 +31669,7 @@ var init_api_key_credential = __esm(() => {
|
|
|
31642
31669
|
// src/auth/codex-oauth.ts
|
|
31643
31670
|
import { exec as exec3 } from "child_process";
|
|
31644
31671
|
import { createHash as createHash11, randomBytes as randomBytes4 } from "crypto";
|
|
31645
|
-
import { closeSync as closeSync4, existsSync as existsSync16, openSync as openSync4, readFileSync as readFileSync14, unlinkSync as
|
|
31672
|
+
import { closeSync as closeSync4, existsSync as existsSync16, openSync as openSync4, readFileSync as readFileSync14, unlinkSync as unlinkSync5, writeSync as writeSync3 } from "fs";
|
|
31646
31673
|
import { createServer } from "http";
|
|
31647
31674
|
import { homedir as homedir21 } from "os";
|
|
31648
31675
|
import { join as join21 } from "path";
|
|
@@ -31699,7 +31726,7 @@ class CodexOAuth {
|
|
|
31699
31726
|
async logout() {
|
|
31700
31727
|
const credPath = this.getCredentialsPath();
|
|
31701
31728
|
if (existsSync16(credPath)) {
|
|
31702
|
-
|
|
31729
|
+
unlinkSync5(credPath);
|
|
31703
31730
|
log("[CodexOAuth] Credentials deleted");
|
|
31704
31731
|
}
|
|
31705
31732
|
this.credentials = null;
|
|
@@ -32327,7 +32354,7 @@ import {
|
|
|
32327
32354
|
mkdirSync as mkdirSync10,
|
|
32328
32355
|
openSync as openSync5,
|
|
32329
32356
|
readFileSync as readFileSync16,
|
|
32330
|
-
unlinkSync as
|
|
32357
|
+
unlinkSync as unlinkSync6,
|
|
32331
32358
|
writeSync as writeSync4
|
|
32332
32359
|
} from "fs";
|
|
32333
32360
|
import { homedir as homedir23, hostname, platform, release as release2 } from "os";
|
|
@@ -32568,7 +32595,7 @@ Waiting for authorization...`);
|
|
|
32568
32595
|
async logout() {
|
|
32569
32596
|
const credPath = kimiOAuthPath();
|
|
32570
32597
|
if (existsSync17(credPath)) {
|
|
32571
|
-
|
|
32598
|
+
unlinkSync6(credPath);
|
|
32572
32599
|
log("[KimiOAuth] Credentials deleted");
|
|
32573
32600
|
}
|
|
32574
32601
|
this.state.forget();
|
|
@@ -32882,7 +32909,7 @@ import {
|
|
|
32882
32909
|
existsSync as existsSync19,
|
|
32883
32910
|
mkdirSync as mkdirSync11,
|
|
32884
32911
|
readFileSync as readFileSync18,
|
|
32885
|
-
renameSync as
|
|
32912
|
+
renameSync as renameSync4,
|
|
32886
32913
|
rmSync as rmSync3,
|
|
32887
32914
|
writeFileSync as writeFileSync8
|
|
32888
32915
|
} from "fs";
|
|
@@ -32921,7 +32948,7 @@ function writeMuseStore(kind, record, dir = defaultMuseStoreDir()) {
|
|
|
32921
32948
|
writeFileSync8(tmp, `${JSON.stringify(record, null, 2)}
|
|
32922
32949
|
`, { mode: 384 });
|
|
32923
32950
|
chmodSync(tmp, 384);
|
|
32924
|
-
|
|
32951
|
+
renameSync4(tmp, path);
|
|
32925
32952
|
}
|
|
32926
32953
|
function writeBorrowedCopy(accessToken, subsTierName, dir = defaultMuseStoreDir(), now = () => new Date) {
|
|
32927
32954
|
const copy = {
|
|
@@ -34698,7 +34725,14 @@ function startCatalogWarm() {
|
|
|
34698
34725
|
if (_warmPromise)
|
|
34699
34726
|
return _warmPromise;
|
|
34700
34727
|
const promise = refreshCatalog(8000).then((result) => {
|
|
34701
|
-
if (result.kind
|
|
34728
|
+
if (result.kind === "refreshed")
|
|
34729
|
+
return;
|
|
34730
|
+
log(`[catalog] refresh failed: ${result.kind === "fetch_failed" ? result.reason : `incompatible contract ${result.serverContractVersion ?? "unknown"}`}`);
|
|
34731
|
+
if (_warmPromise === promise)
|
|
34732
|
+
_warmPromise = null;
|
|
34733
|
+
}, (err) => {
|
|
34734
|
+
log(`[catalog] refresh threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
34735
|
+
if (_warmPromise === promise)
|
|
34702
34736
|
_warmPromise = null;
|
|
34703
34737
|
});
|
|
34704
34738
|
_warmPromise = promise;
|
|
@@ -34729,13 +34763,20 @@ async function ensureRouteRegistryReady(timeoutMs = 5000) {
|
|
|
34729
34763
|
await waitForCatalogWarm(timeoutMs);
|
|
34730
34764
|
}
|
|
34731
34765
|
async function waitForCatalogWarm(timeoutMs) {
|
|
34766
|
+
let timedOut = false;
|
|
34732
34767
|
await Promise.race([
|
|
34733
34768
|
startCatalogWarm(),
|
|
34734
|
-
new Promise((resolve) => setTimeout(
|
|
34769
|
+
new Promise((resolve) => setTimeout(() => {
|
|
34770
|
+
timedOut = true;
|
|
34771
|
+
resolve();
|
|
34772
|
+
}, timeoutMs))
|
|
34735
34773
|
]);
|
|
34774
|
+
if (timedOut)
|
|
34775
|
+
log(`[catalog] still refreshing after ${timeoutMs} ms; the caller goes on without it`);
|
|
34736
34776
|
}
|
|
34737
34777
|
var DEFAULT_CATALOG_URL = "https://us-central1-claudish-6da10.cloudfunctions.net/queryModels?status=all&catalog=slim&includeRouteVariants=true&limit=1000", MAX_CATALOG_PAGES = 40, CATALOG_PAGE_LIMIT = 1000, _memCache = null, _catalogEntriesForTest, _warmPromise = null;
|
|
34738
34778
|
var init_catalog_client = __esm(() => {
|
|
34779
|
+
init_logger();
|
|
34739
34780
|
init_all_models_cache();
|
|
34740
34781
|
init_catalog_route_bindings();
|
|
34741
34782
|
init_connection_wire();
|
|
@@ -34981,14 +35022,14 @@ var init_proto_codec = __esm(() => {
|
|
|
34981
35022
|
});
|
|
34982
35023
|
|
|
34983
35024
|
// src/providers/devin/devin-request.ts
|
|
34984
|
-
import { randomUUID as
|
|
35025
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
34985
35026
|
function encodeChatMetadata(meta) {
|
|
34986
35027
|
const version = meta.clientVersion ?? DEVIN_CLI_VERSION;
|
|
34987
35028
|
return msg(bytes(1, "devin-cli"), bytes(2, version), bytes(3, meta.apiKey), bytes(4, "en"), bytes(5, meta.platform ?? process.platform), bytes(7, version), bytes(12, "chisel"), bytes(28, "chisel"));
|
|
34988
35029
|
}
|
|
34989
35030
|
function encodeMessage(message) {
|
|
34990
35031
|
const parts = [
|
|
34991
|
-
bytes(1, message.id ??
|
|
35032
|
+
bytes(1, message.id ?? randomUUID5()),
|
|
34992
35033
|
vint(2, DEVIN_ROLE[message.role])
|
|
34993
35034
|
];
|
|
34994
35035
|
if (message.text)
|
|
@@ -37155,8 +37196,8 @@ import {
|
|
|
37155
37196
|
existsSync as existsSync21,
|
|
37156
37197
|
mkdirSync as mkdirSync13,
|
|
37157
37198
|
readFileSync as readFileSync21,
|
|
37158
|
-
renameSync as
|
|
37159
|
-
unlinkSync as
|
|
37199
|
+
renameSync as renameSync5,
|
|
37200
|
+
unlinkSync as unlinkSync7,
|
|
37160
37201
|
writeFileSync as writeFileSync10
|
|
37161
37202
|
} from "fs";
|
|
37162
37203
|
import { homedir as homedir29 } from "os";
|
|
@@ -37197,7 +37238,7 @@ function writeToDisk(events) {
|
|
|
37197
37238
|
const payload = { version: 1, events: trimmed };
|
|
37198
37239
|
const tmpFile = join29(CLAUDISH_DIR, `stats-buffer.tmp.${process.pid}.json`);
|
|
37199
37240
|
writeFileSync10(tmpFile, JSON.stringify(payload, null, 2), "utf-8");
|
|
37200
|
-
|
|
37241
|
+
renameSync5(tmpFile, BUFFER_FILE);
|
|
37201
37242
|
memoryCache = trimmed;
|
|
37202
37243
|
} catch {}
|
|
37203
37244
|
}
|
|
@@ -37240,7 +37281,7 @@ function clearBuffer() {
|
|
|
37240
37281
|
memoryCache = [];
|
|
37241
37282
|
eventsSinceLastFlush = 0;
|
|
37242
37283
|
if (existsSync21(BUFFER_FILE)) {
|
|
37243
|
-
|
|
37284
|
+
unlinkSync7(BUFFER_FILE);
|
|
37244
37285
|
}
|
|
37245
37286
|
} catch {}
|
|
37246
37287
|
}
|
|
@@ -60027,8 +60068,161 @@ var init_cache_ttl = __esm(() => {
|
|
|
60027
60068
|
FIREBASE_CACHE_TTL_MS = FIREBASE_CACHE_TTL_HOURS * 60 * 60 * 1000;
|
|
60028
60069
|
});
|
|
60029
60070
|
|
|
60071
|
+
// src/providers/effort-recommendations.ts
|
|
60072
|
+
import { readFileSync as readFileSync25, statSync as statSync9 } from "fs";
|
|
60073
|
+
function effortRecommendationsPathFor(catalogPath) {
|
|
60074
|
+
return catalogPath.endsWith(".json") ? `${catalogPath.slice(0, -5)}.efforts.json` : `${catalogPath}.efforts.json`;
|
|
60075
|
+
}
|
|
60076
|
+
function isRecord(value) {
|
|
60077
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
60078
|
+
}
|
|
60079
|
+
function parseEffortRecommendations(raw) {
|
|
60080
|
+
const out = {};
|
|
60081
|
+
if (!isRecord(raw))
|
|
60082
|
+
return out;
|
|
60083
|
+
for (const [modelId, byTask] of Object.entries(raw)) {
|
|
60084
|
+
const entries = modelId ? parseModelEntries(byTask) : {};
|
|
60085
|
+
if (Object.keys(entries).length > 0)
|
|
60086
|
+
out[modelId] = entries;
|
|
60087
|
+
}
|
|
60088
|
+
return out;
|
|
60089
|
+
}
|
|
60090
|
+
function parseModelEntries(byTask) {
|
|
60091
|
+
const entries = {};
|
|
60092
|
+
if (!isRecord(byTask))
|
|
60093
|
+
return entries;
|
|
60094
|
+
for (const [taskType, entry] of Object.entries(byTask)) {
|
|
60095
|
+
if (!taskType || !isRecord(entry))
|
|
60096
|
+
continue;
|
|
60097
|
+
if (typeof entry.effort !== "string" || entry.effort === "")
|
|
60098
|
+
continue;
|
|
60099
|
+
const sendableOn = parseSendableOn(entry.sendableOn);
|
|
60100
|
+
if (sendableOn.length === 0)
|
|
60101
|
+
continue;
|
|
60102
|
+
entries[taskType] = typeof entry.basis === "string" ? { effort: entry.effort, basis: entry.basis, sendableOn } : { effort: entry.effort, sendableOn };
|
|
60103
|
+
}
|
|
60104
|
+
return entries;
|
|
60105
|
+
}
|
|
60106
|
+
function nonEmptyString(value) {
|
|
60107
|
+
return typeof value === "string" && value !== "";
|
|
60108
|
+
}
|
|
60109
|
+
function parseSendableOn(raw) {
|
|
60110
|
+
if (!Array.isArray(raw))
|
|
60111
|
+
return [];
|
|
60112
|
+
const out = [];
|
|
60113
|
+
for (const item of raw) {
|
|
60114
|
+
if (!isRecord(item))
|
|
60115
|
+
continue;
|
|
60116
|
+
const { routeId, routeProfileId, externalModelId, encoding } = item;
|
|
60117
|
+
if (!nonEmptyString(routeId) || !nonEmptyString(routeProfileId))
|
|
60118
|
+
continue;
|
|
60119
|
+
if (!nonEmptyString(externalModelId))
|
|
60120
|
+
continue;
|
|
60121
|
+
out.push(typeof encoding === "string" ? { routeId, routeProfileId, externalModelId, encoding } : { routeId, routeProfileId, externalModelId });
|
|
60122
|
+
}
|
|
60123
|
+
return out;
|
|
60124
|
+
}
|
|
60125
|
+
function parseSidecar(raw) {
|
|
60126
|
+
if (!isRecord(raw) || raw.contractVersion !== SIDECAR_CONTRACT_VERSION)
|
|
60127
|
+
return null;
|
|
60128
|
+
if (raw.format !== SIDECAR_FORMAT)
|
|
60129
|
+
return null;
|
|
60130
|
+
if (!isRecord(raw.generations))
|
|
60131
|
+
return null;
|
|
60132
|
+
const generations = {};
|
|
60133
|
+
for (const [generationId, generation] of Object.entries(raw.generations)) {
|
|
60134
|
+
if (!generationId || !isRecord(generation))
|
|
60135
|
+
continue;
|
|
60136
|
+
if (typeof generation.writtenAt !== "number" || !Number.isFinite(generation.writtenAt)) {
|
|
60137
|
+
continue;
|
|
60138
|
+
}
|
|
60139
|
+
generations[generationId] = {
|
|
60140
|
+
writtenAt: generation.writtenAt,
|
|
60141
|
+
efforts: parseEffortRecommendations(generation.efforts)
|
|
60142
|
+
};
|
|
60143
|
+
}
|
|
60144
|
+
return { contractVersion: SIDECAR_CONTRACT_VERSION, format: SIDECAR_FORMAT, generations };
|
|
60145
|
+
}
|
|
60146
|
+
function statOrNull2(path) {
|
|
60147
|
+
try {
|
|
60148
|
+
const { mtimeMs, size } = statSync9(path);
|
|
60149
|
+
return { mtimeMs, size };
|
|
60150
|
+
} catch {
|
|
60151
|
+
return null;
|
|
60152
|
+
}
|
|
60153
|
+
}
|
|
60154
|
+
function readSidecarFile(path) {
|
|
60155
|
+
try {
|
|
60156
|
+
return parseSidecar(JSON.parse(readFileSync25(path, "utf-8")));
|
|
60157
|
+
} catch (err) {
|
|
60158
|
+
if (err?.code !== "ENOENT") {
|
|
60159
|
+
log(`[effort] unreadable ${path}: ${err instanceof Error ? err.message : String(err)}`);
|
|
60160
|
+
}
|
|
60161
|
+
return null;
|
|
60162
|
+
}
|
|
60163
|
+
}
|
|
60164
|
+
function foreignSidecarFormat(path) {
|
|
60165
|
+
try {
|
|
60166
|
+
const raw = JSON.parse(readFileSync25(path, "utf-8"));
|
|
60167
|
+
if (isRecord(raw) && raw.format !== SIDECAR_FORMAT)
|
|
60168
|
+
return raw.format ?? "none";
|
|
60169
|
+
} catch {}
|
|
60170
|
+
return;
|
|
60171
|
+
}
|
|
60172
|
+
function readEffortRecommendations(path = EFFORT_RECOMMENDATIONS_PATH) {
|
|
60173
|
+
const stat = statOrNull2(path);
|
|
60174
|
+
if (!stat) {
|
|
60175
|
+
_readMemo2.delete(path);
|
|
60176
|
+
return null;
|
|
60177
|
+
}
|
|
60178
|
+
const key = `${stat.mtimeMs}:${stat.size}`;
|
|
60179
|
+
const memo = _readMemo2.get(path);
|
|
60180
|
+
if (memo && memo.key === key)
|
|
60181
|
+
return memo.sidecar;
|
|
60182
|
+
const sidecar = readSidecarFile(path);
|
|
60183
|
+
_readMemo2.set(path, { key, sidecar });
|
|
60184
|
+
return sidecar;
|
|
60185
|
+
}
|
|
60186
|
+
function writeEffortRecommendations(generationId, raw, path = EFFORT_RECOMMENDATIONS_PATH) {
|
|
60187
|
+
const existing = readSidecarFile(path);
|
|
60188
|
+
if (!existing && !_foreignFormatLogged) {
|
|
60189
|
+
const foreign = foreignSidecarFormat(path);
|
|
60190
|
+
if (foreign !== undefined) {
|
|
60191
|
+
_foreignFormatLogged = true;
|
|
60192
|
+
log(`[effort] replacing a sidecar of format ${String(foreign)} with format ${SIDECAR_FORMAT} at ${path}; its generations are dropped`);
|
|
60193
|
+
}
|
|
60194
|
+
}
|
|
60195
|
+
const merged = {
|
|
60196
|
+
...existing?.generations ?? {},
|
|
60197
|
+
[generationId]: { writtenAt: Date.now(), efforts: parseEffortRecommendations(raw) }
|
|
60198
|
+
};
|
|
60199
|
+
const kept = Object.entries(merged).sort(([, a], [, b]) => b.writtenAt - a.writtenAt).slice(0, MAX_GENERATIONS);
|
|
60200
|
+
const sidecar = {
|
|
60201
|
+
contractVersion: SIDECAR_CONTRACT_VERSION,
|
|
60202
|
+
format: SIDECAR_FORMAT,
|
|
60203
|
+
generations: Object.fromEntries(kept)
|
|
60204
|
+
};
|
|
60205
|
+
writeFileAtomic(path, JSON.stringify(sidecar));
|
|
60206
|
+
_readMemo2.delete(path);
|
|
60207
|
+
}
|
|
60208
|
+
function latestEffortRecommendations(path = EFFORT_RECOMMENDATIONS_PATH) {
|
|
60209
|
+
const sidecar = readEffortRecommendations(path);
|
|
60210
|
+
if (!sidecar)
|
|
60211
|
+
return null;
|
|
60212
|
+
const newest = Object.entries(sidecar.generations).sort(([, a], [, b]) => b.writtenAt - a.writtenAt)[0];
|
|
60213
|
+
return newest ? { generationId: newest[0], efforts: newest[1].efforts } : null;
|
|
60214
|
+
}
|
|
60215
|
+
var SIDECAR_CONTRACT_VERSION = 3, SIDECAR_FORMAT = 2, MAX_GENERATIONS = 4, EFFORT_RECOMMENDATIONS_PATH, _foreignFormatLogged = false, _readMemo2;
|
|
60216
|
+
var init_effort_recommendations = __esm(() => {
|
|
60217
|
+
init_fs_atomic();
|
|
60218
|
+
init_logger();
|
|
60219
|
+
init_all_models_cache();
|
|
60220
|
+
EFFORT_RECOMMENDATIONS_PATH = effortRecommendationsPathFor(ALL_MODELS_CACHE_PATH);
|
|
60221
|
+
_readMemo2 = new Map;
|
|
60222
|
+
});
|
|
60223
|
+
|
|
60030
60224
|
// src/model-loader.ts
|
|
60031
|
-
import { existsSync as existsSync25,
|
|
60225
|
+
import { existsSync as existsSync25, readFileSync as readFileSync26 } from "fs";
|
|
60032
60226
|
import { homedir as homedir32 } from "os";
|
|
60033
60227
|
import { join as join35 } from "path";
|
|
60034
60228
|
function isRecommendationTier(value) {
|
|
@@ -60174,17 +60368,17 @@ function recommendationProjection(recommendations, richModels = []) {
|
|
|
60174
60368
|
plans: cache.plans
|
|
60175
60369
|
} : { catalogGenerationId: "", entries: [], plans: [] }, richModels);
|
|
60176
60370
|
}
|
|
60177
|
-
function
|
|
60371
|
+
function isRecord2(value) {
|
|
60178
60372
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
60179
60373
|
}
|
|
60180
60374
|
function isStringArray(value) {
|
|
60181
60375
|
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
60182
60376
|
}
|
|
60183
60377
|
function isRouteObject(value) {
|
|
60184
|
-
return
|
|
60378
|
+
return isRecord2(value) && typeof value.plan === "string" && typeof value.command === "string" && (value.prefix === undefined || typeof value.prefix === "string") && (value.planIds === undefined || isStringArray(value.planIds));
|
|
60185
60379
|
}
|
|
60186
60380
|
function isUsableRow(value) {
|
|
60187
|
-
if (!
|
|
60381
|
+
if (!isRecord2(value))
|
|
60188
60382
|
return false;
|
|
60189
60383
|
if (typeof value.id !== "string" || value.id.length === 0)
|
|
60190
60384
|
return false;
|
|
@@ -60196,7 +60390,7 @@ function isUsableRow(value) {
|
|
|
60196
60390
|
return false;
|
|
60197
60391
|
}
|
|
60198
60392
|
const pricing = value.pricing;
|
|
60199
|
-
if (!
|
|
60393
|
+
if (!isRecord2(pricing) || typeof pricing.input !== "string" || typeof pricing.output !== "string" || typeof pricing.average !== "string") {
|
|
60200
60394
|
return false;
|
|
60201
60395
|
}
|
|
60202
60396
|
if (value.releaseDate !== undefined && typeof value.releaseDate !== "string")
|
|
@@ -60209,7 +60403,7 @@ function isUsableRow(value) {
|
|
|
60209
60403
|
return true;
|
|
60210
60404
|
}
|
|
60211
60405
|
function readProjectedRecommendationsDoc(value) {
|
|
60212
|
-
if (!
|
|
60406
|
+
if (!isRecord2(value))
|
|
60213
60407
|
return null;
|
|
60214
60408
|
if (value.contractVersion !== 3)
|
|
60215
60409
|
return null;
|
|
@@ -60235,15 +60429,21 @@ function readRecommendedModelsCacheFile() {
|
|
|
60235
60429
|
return null;
|
|
60236
60430
|
let parsed;
|
|
60237
60431
|
try {
|
|
60238
|
-
parsed = JSON.parse(
|
|
60239
|
-
} catch {
|
|
60432
|
+
parsed = JSON.parse(readFileSync26(RECOMMENDED_MODELS_CACHE_PATH, "utf-8"));
|
|
60433
|
+
} catch (err) {
|
|
60434
|
+
log(`[recommended] unreadable ${RECOMMENDED_MODELS_CACHE_PATH}: ${err instanceof Error ? err.message : String(err)}`);
|
|
60240
60435
|
return null;
|
|
60241
60436
|
}
|
|
60242
|
-
if (!
|
|
60437
|
+
if (!isRecord2(parsed) || parsed.projectionVersion !== RECOMMENDED_PROJECTION_VERSION) {
|
|
60438
|
+
log(`[recommended] ${RECOMMENDED_MODELS_CACHE_PATH} has projection version ${isRecord2(parsed) ? String(parsed.projectionVersion) : "none"}; this build reads ${RECOMMENDED_PROJECTION_VERSION}`);
|
|
60243
60439
|
return null;
|
|
60244
60440
|
}
|
|
60245
60441
|
return readProjectedRecommendationsDoc(parsed);
|
|
60246
60442
|
}
|
|
60443
|
+
function readLastRecommendedModels() {
|
|
60444
|
+
const doc = readRecommendedModelsCacheFile();
|
|
60445
|
+
return doc && doc.models.length > 0 ? doc : null;
|
|
60446
|
+
}
|
|
60247
60447
|
function sectionDefFor(tier) {
|
|
60248
60448
|
const index = RECOMMENDATION_TIER_INDEX.get(tier);
|
|
60249
60449
|
return index === undefined ? undefined : RECOMMENDATION_SECTIONS[index];
|
|
@@ -60408,7 +60608,7 @@ function computeQuickPicks(primaries) {
|
|
|
60408
60608
|
return { budget, largeContext, mostCapable, visionCoding, agentic };
|
|
60409
60609
|
}
|
|
60410
60610
|
async function getRecommendedModels(opts = {}) {
|
|
60411
|
-
const { forceRefresh = false } = opts;
|
|
60611
|
+
const { forceRefresh = false, effortsPath = EFFORT_RECOMMENDATIONS_PATH } = opts;
|
|
60412
60612
|
const cached = _cachedRecommendedModels;
|
|
60413
60613
|
if (!forceRefresh && cached && cached.generationId === readAllModelsCache()?.catalogGenerationId) {
|
|
60414
60614
|
return cached;
|
|
@@ -60432,15 +60632,20 @@ async function getRecommendedModels(opts = {}) {
|
|
|
60432
60632
|
if (response.recommendations.generationId !== generationId) {
|
|
60433
60633
|
throw new Error("Recommendation and model catalog generations differ");
|
|
60434
60634
|
}
|
|
60635
|
+
try {
|
|
60636
|
+
writeEffortRecommendations(generationId, response.recommendations.efforts, effortsPath);
|
|
60637
|
+
} catch (err) {
|
|
60638
|
+
log(`[effort] sidecar write failed for generation ${generationId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
60639
|
+
}
|
|
60435
60640
|
const top100 = await fetchCatalogData(`${FIREBASE_BASE_URL}?catalog=top100`, RECOMMENDED_FETCH_TIMEOUT_MS, generationId);
|
|
60436
60641
|
const data = recommendationProjection(response.recommendations, top100.models);
|
|
60437
60642
|
if (data.models.length > 0) {
|
|
60438
60643
|
_cachedRecommendedModels = data;
|
|
60439
60644
|
try {
|
|
60440
|
-
|
|
60441
|
-
|
|
60442
|
-
|
|
60443
|
-
}
|
|
60645
|
+
writeFileAtomic(RECOMMENDED_MODELS_CACHE_PATH, JSON.stringify(data));
|
|
60646
|
+
} catch (err) {
|
|
60647
|
+
log(`[recommended] cache write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
60648
|
+
}
|
|
60444
60649
|
return data;
|
|
60445
60650
|
}
|
|
60446
60651
|
} catch (error) {
|
|
@@ -60463,7 +60668,8 @@ function getRecommendedModelsSync() {
|
|
|
60463
60668
|
async function warmRecommendedModels() {
|
|
60464
60669
|
try {
|
|
60465
60670
|
return await getRecommendedModels({ forceRefresh: true });
|
|
60466
|
-
} catch {
|
|
60671
|
+
} catch (err) {
|
|
60672
|
+
log(`[recommended] warm failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
60467
60673
|
return null;
|
|
60468
60674
|
}
|
|
60469
60675
|
}
|
|
@@ -60571,11 +60777,14 @@ function getAvailableModels() {
|
|
|
60571
60777
|
}
|
|
60572
60778
|
var RECOMMENDATION_SECTIONS, RECOMMENDATION_TIER_INDEX, _cachedModelInfo = null, _cachedModelIds = null, _cachedRecommendedModels = null, FIREBASE_BASE_URL = "https://us-central1-claudish-6da10.cloudfunctions.net/queryModels", FIREBASE_RECOMMENDED_URL, RECOMMENDED_PROJECTION_VERSION = 2, RECOMMENDED_MODELS_CACHE_PATH, RECOMMENDED_FETCH_TIMEOUT_MS = 5000, SEARCH_FETCH_TIMEOUT_MS = 1e4, RECOMMENDED_ROUTE_TIER_ORDER;
|
|
60573
60779
|
var init_model_loader = __esm(() => {
|
|
60780
|
+
init_fs_atomic();
|
|
60781
|
+
init_logger();
|
|
60574
60782
|
init_all_models_cache();
|
|
60575
60783
|
init_auto_route();
|
|
60576
60784
|
init_cache_ttl();
|
|
60577
60785
|
init_catalog_client();
|
|
60578
60786
|
init_catalog_route_bindings();
|
|
60787
|
+
init_effort_recommendations();
|
|
60579
60788
|
init_route_candidates();
|
|
60580
60789
|
RECOMMENDATION_SECTIONS = [
|
|
60581
60790
|
{ recommendationTier: "flagship", title: "Flagship", quickPickEligible: true },
|
|
@@ -64162,7 +64371,7 @@ var init_DiscoveryNotice = __esm(() => {
|
|
|
64162
64371
|
});
|
|
64163
64372
|
|
|
64164
64373
|
// src/providers/model-descriptions.ts
|
|
64165
|
-
import { existsSync as existsSync26, mkdirSync as
|
|
64374
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync16, readFileSync as readFileSync27, writeFileSync as writeFileSync15 } from "fs";
|
|
64166
64375
|
import { homedir as homedir33 } from "os";
|
|
64167
64376
|
import { dirname as dirname13, join as join36 } from "path";
|
|
64168
64377
|
function emptyDescriptionIndex() {
|
|
@@ -64186,7 +64395,7 @@ function readCache(path) {
|
|
|
64186
64395
|
if (!existsSync26(path))
|
|
64187
64396
|
return null;
|
|
64188
64397
|
try {
|
|
64189
|
-
const raw = JSON.parse(
|
|
64398
|
+
const raw = JSON.parse(readFileSync27(path, "utf-8"));
|
|
64190
64399
|
if (!raw || typeof raw !== "object" || typeof raw.byId !== "object" || raw.byId === null) {
|
|
64191
64400
|
return null;
|
|
64192
64401
|
}
|
|
@@ -64202,8 +64411,8 @@ function readCache(path) {
|
|
|
64202
64411
|
}
|
|
64203
64412
|
function writeCache(path, cache) {
|
|
64204
64413
|
try {
|
|
64205
|
-
|
|
64206
|
-
|
|
64414
|
+
mkdirSync16(dirname13(path), { recursive: true });
|
|
64415
|
+
writeFileSync15(path, JSON.stringify(cache), "utf-8");
|
|
64207
64416
|
} catch (e) {
|
|
64208
64417
|
log(`[model-descriptions] cache write failed: ${e?.message ?? String(e)}`);
|
|
64209
64418
|
}
|
|
@@ -70443,7 +70652,7 @@ function renderRecommendedText(doc, getNativePrefix) {
|
|
|
70443
70652
|
return lines.join(`
|
|
70444
70653
|
`);
|
|
70445
70654
|
}
|
|
70446
|
-
function markdownRow(group
|
|
70655
|
+
function markdownRow(group) {
|
|
70447
70656
|
const m = group.primary;
|
|
70448
70657
|
const pricing = formatListingPrice(m);
|
|
70449
70658
|
const ctx = m.context || "N/A";
|
|
@@ -70455,24 +70664,24 @@ function markdownRow(group, getNativePrefix) {
|
|
|
70455
70664
|
if (m.supportsVision)
|
|
70456
70665
|
caps.push("vision");
|
|
70457
70666
|
const capsLine = caps.length > 0 ? caps.join(", ") : "none";
|
|
70458
|
-
const prefixes = collectRoutingPrefixes(group, getNativePrefix);
|
|
70459
|
-
const accessLine = prefixes.length > 0 ? prefixes.map((p) => `\`${p}@${m.id}\``).join(" \xB7 ") : `\`${m.id}\``;
|
|
70460
70667
|
return [
|
|
70461
70668
|
`### ${m.id}`,
|
|
70462
70669
|
`- **Pricing**: ${pricing} avg \xB7 ${ctx} context`,
|
|
70463
70670
|
`- **Capabilities**: ${capsLine}`,
|
|
70464
|
-
`- **Access**: ${accessLine}`,
|
|
70465
70671
|
""
|
|
70466
70672
|
].join(`
|
|
70467
70673
|
`);
|
|
70468
70674
|
}
|
|
70469
|
-
function renderRecommendedMarkdown(doc
|
|
70675
|
+
function renderRecommendedMarkdown(doc) {
|
|
70470
70676
|
const sections = groupRecommendedModels(doc.models);
|
|
70471
70677
|
let output = `# Recommended Models
|
|
70472
70678
|
|
|
70473
70679
|
`;
|
|
70474
70680
|
output += `_Last updated: ${doc.lastUpdated || "unknown"}_
|
|
70475
70681
|
|
|
70682
|
+
`;
|
|
70683
|
+
output += `Pass each model by its bare id (the heading); claudish routing picks the provider.
|
|
70684
|
+
|
|
70476
70685
|
`;
|
|
70477
70686
|
for (const section of sections) {
|
|
70478
70687
|
output += `## ${section.title}
|
|
@@ -70483,7 +70692,7 @@ function renderRecommendedMarkdown(doc, getNativePrefix) {
|
|
|
70483
70692
|
|
|
70484
70693
|
`;
|
|
70485
70694
|
for (const group of section.groups)
|
|
70486
|
-
output += markdownRow(group
|
|
70695
|
+
output += markdownRow(group);
|
|
70487
70696
|
}
|
|
70488
70697
|
const picks = computeQuickPicks(quickPickCandidates(sections));
|
|
70489
70698
|
const pickLines = [];
|
|
@@ -70507,6 +70716,23 @@ function renderRecommendedMarkdown(doc, getNativePrefix) {
|
|
|
70507
70716
|
}
|
|
70508
70717
|
return output;
|
|
70509
70718
|
}
|
|
70719
|
+
function renderEffortTableMarkdown(efforts) {
|
|
70720
|
+
const models = Object.keys(efforts).sort();
|
|
70721
|
+
if (models.length === 0)
|
|
70722
|
+
return "";
|
|
70723
|
+
const taskTypes = [...new Set(models.flatMap((m) => Object.keys(efforts[m])))].sort();
|
|
70724
|
+
const lines = [
|
|
70725
|
+
"## Recommended effort by task type",
|
|
70726
|
+
"",
|
|
70727
|
+
"Map your task to a column, take the cell for each model you run, and pass it: " + '`team` `efforts: {"<model>": "<level>"}` (keys exactly as in `models`), ' + "`create_session` / `run_prompt` `effort`. A model with no cell keeps Claude Code's " + "own effort.",
|
|
70728
|
+
"",
|
|
70729
|
+
`| model | ${taskTypes.join(" | ")} |`,
|
|
70730
|
+
`|---|${taskTypes.map(() => "---").join("|")}|`,
|
|
70731
|
+
...models.map((m) => `| ${m} | ${taskTypes.map((t) => efforts[m][t]?.effort ?? "-").join(" | ")} |`)
|
|
70732
|
+
];
|
|
70733
|
+
return lines.join(`
|
|
70734
|
+
`);
|
|
70735
|
+
}
|
|
70510
70736
|
var init_recommended_listing = __esm(() => {
|
|
70511
70737
|
init_model_loader();
|
|
70512
70738
|
init_provider_definitions();
|
|
@@ -70571,7 +70797,7 @@ var init_branding = __esm(() => {
|
|
|
70571
70797
|
});
|
|
70572
70798
|
|
|
70573
70799
|
// src/update-checker.ts
|
|
70574
|
-
import { existsSync as existsSync27, mkdirSync as
|
|
70800
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync17, readFileSync as readFileSync28, unlinkSync as unlinkSync8, writeFileSync as writeFileSync16 } from "fs";
|
|
70575
70801
|
import { homedir as homedir34, platform as platform2, tmpdir } from "os";
|
|
70576
70802
|
import { join as join37 } from "path";
|
|
70577
70803
|
function getCacheFilePath() {
|
|
@@ -70584,7 +70810,7 @@ function getCacheFilePath() {
|
|
|
70584
70810
|
}
|
|
70585
70811
|
try {
|
|
70586
70812
|
if (!existsSync27(cacheDir)) {
|
|
70587
|
-
|
|
70813
|
+
mkdirSync17(cacheDir, { recursive: true });
|
|
70588
70814
|
}
|
|
70589
70815
|
return join37(cacheDir, "update-check.json");
|
|
70590
70816
|
} catch {
|
|
@@ -70597,7 +70823,7 @@ function readCache2() {
|
|
|
70597
70823
|
if (!existsSync27(cachePath)) {
|
|
70598
70824
|
return null;
|
|
70599
70825
|
}
|
|
70600
|
-
const data = JSON.parse(
|
|
70826
|
+
const data = JSON.parse(readFileSync28(cachePath, "utf-8"));
|
|
70601
70827
|
return data;
|
|
70602
70828
|
} catch {
|
|
70603
70829
|
return null;
|
|
@@ -70610,7 +70836,7 @@ function writeCache2(latestVersion) {
|
|
|
70610
70836
|
lastCheck: Date.now(),
|
|
70611
70837
|
latestVersion
|
|
70612
70838
|
};
|
|
70613
|
-
|
|
70839
|
+
writeFileSync16(cachePath, JSON.stringify(data), "utf-8");
|
|
70614
70840
|
} catch {}
|
|
70615
70841
|
}
|
|
70616
70842
|
function isCacheValid(cache) {
|
|
@@ -70621,7 +70847,7 @@ function clearCache() {
|
|
|
70621
70847
|
try {
|
|
70622
70848
|
const cachePath = getCacheFilePath();
|
|
70623
70849
|
if (existsSync27(cachePath)) {
|
|
70624
|
-
|
|
70850
|
+
unlinkSync8(cachePath);
|
|
70625
70851
|
}
|
|
70626
70852
|
} catch {}
|
|
70627
70853
|
}
|
|
@@ -76560,9 +76786,9 @@ var init_seam_hooks = __esm(() => {
|
|
|
76560
76786
|
});
|
|
76561
76787
|
|
|
76562
76788
|
// src/hooks/seam-tap.ts
|
|
76563
|
-
import { randomUUID as
|
|
76789
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
76564
76790
|
function newRequestId() {
|
|
76565
|
-
return
|
|
76791
|
+
return randomUUID6();
|
|
76566
76792
|
}
|
|
76567
76793
|
|
|
76568
76794
|
class EndLine {
|
|
@@ -76890,7 +77116,7 @@ var init_response_seam = __esm(() => {
|
|
|
76890
77116
|
});
|
|
76891
77117
|
|
|
76892
77118
|
// src/services/pricing-cache.ts
|
|
76893
|
-
import { existsSync as existsSync28, readFileSync as
|
|
77119
|
+
import { existsSync as existsSync28, readFileSync as readFileSync29, statSync as statSync10 } from "fs";
|
|
76894
77120
|
import { homedir as homedir35 } from "os";
|
|
76895
77121
|
import { join as join38 } from "path";
|
|
76896
77122
|
function prefixMatch(modelName) {
|
|
@@ -76932,10 +77158,10 @@ function loadDiskCache() {
|
|
|
76932
77158
|
try {
|
|
76933
77159
|
if (!existsSync28(CACHE_FILE))
|
|
76934
77160
|
return false;
|
|
76935
|
-
const stat =
|
|
77161
|
+
const stat = statSync10(CACHE_FILE);
|
|
76936
77162
|
const age = Date.now() - stat.mtimeMs;
|
|
76937
77163
|
const isFresh = age < CACHE_TTL_MS5;
|
|
76938
|
-
const raw =
|
|
77164
|
+
const raw = readFileSync29(CACHE_FILE, "utf-8");
|
|
76939
77165
|
const data = JSON.parse(raw);
|
|
76940
77166
|
for (const [key, pricing] of Object.entries(data)) {
|
|
76941
77167
|
pricingMap.set(key, pricing);
|
|
@@ -76958,7 +77184,7 @@ var init_pricing_cache = __esm(() => {
|
|
|
76958
77184
|
});
|
|
76959
77185
|
|
|
76960
77186
|
// src/proxy-server.ts
|
|
76961
|
-
import { appendFileSync as appendFileSync6, mkdirSync as
|
|
77187
|
+
import { appendFileSync as appendFileSync6, mkdirSync as mkdirSync18 } from "fs";
|
|
76962
77188
|
import { join as join39 } from "path";
|
|
76963
77189
|
function isTerminalRoutingFailure(e) {
|
|
76964
77190
|
return e instanceof RoutingError;
|
|
@@ -76969,7 +77195,7 @@ function maybeCaptureClassifierRequest(c, body) {
|
|
|
76969
77195
|
try {
|
|
76970
77196
|
const dir = join39(process.cwd(), "logs");
|
|
76971
77197
|
if (!classifierCaptureDirReady) {
|
|
76972
|
-
|
|
77198
|
+
mkdirSync18(dir, { recursive: true });
|
|
76973
77199
|
classifierCaptureDirReady = true;
|
|
76974
77200
|
}
|
|
76975
77201
|
const record = {
|
|
@@ -77481,10 +77707,10 @@ var init_proxy_server = __esm(() => {
|
|
|
77481
77707
|
import {
|
|
77482
77708
|
copyFileSync as copyFileSync2,
|
|
77483
77709
|
existsSync as existsSync29,
|
|
77484
|
-
mkdirSync as
|
|
77485
|
-
readFileSync as
|
|
77710
|
+
mkdirSync as mkdirSync19,
|
|
77711
|
+
readFileSync as readFileSync30,
|
|
77486
77712
|
readdirSync as readdirSync3,
|
|
77487
|
-
unlinkSync as
|
|
77713
|
+
unlinkSync as unlinkSync9
|
|
77488
77714
|
} from "fs";
|
|
77489
77715
|
import { homedir as homedir36 } from "os";
|
|
77490
77716
|
import { dirname as dirname14, join as join40 } from "path";
|
|
@@ -77502,7 +77728,7 @@ function clearAllModelCaches() {
|
|
|
77502
77728
|
const files = readdirSync3(cacheDir);
|
|
77503
77729
|
for (const file of files) {
|
|
77504
77730
|
if (cachePatterns.includes(file)) {
|
|
77505
|
-
|
|
77731
|
+
unlinkSync9(join40(cacheDir, file));
|
|
77506
77732
|
cleared++;
|
|
77507
77733
|
}
|
|
77508
77734
|
}
|
|
@@ -79003,7 +79229,7 @@ ${h("MORE INFO")}
|
|
|
79003
79229
|
function printAIAgentGuide() {
|
|
79004
79230
|
try {
|
|
79005
79231
|
const guidePath = join40(__dirname2, "../AI_AGENT_GUIDE.md");
|
|
79006
|
-
const guideContent =
|
|
79232
|
+
const guideContent = readFileSync30(guidePath, "utf-8");
|
|
79007
79233
|
console.log(guideContent);
|
|
79008
79234
|
} catch (error) {
|
|
79009
79235
|
console.error("Error reading AI Agent Guide:");
|
|
@@ -79041,15 +79267,15 @@ async function initializeClaudishSkill() {
|
|
|
79041
79267
|
}
|
|
79042
79268
|
try {
|
|
79043
79269
|
if (!existsSync29(claudeDir)) {
|
|
79044
|
-
|
|
79270
|
+
mkdirSync19(claudeDir, { recursive: true });
|
|
79045
79271
|
console.log("\uD83D\uDCC1 Created .claude/ directory");
|
|
79046
79272
|
}
|
|
79047
79273
|
if (!existsSync29(skillsDir)) {
|
|
79048
|
-
|
|
79274
|
+
mkdirSync19(skillsDir, { recursive: true });
|
|
79049
79275
|
console.log("\uD83D\uDCC1 Created .claude/skills/ directory");
|
|
79050
79276
|
}
|
|
79051
79277
|
if (!existsSync29(claudishSkillDir)) {
|
|
79052
|
-
|
|
79278
|
+
mkdirSync19(claudishSkillDir, { recursive: true });
|
|
79053
79279
|
console.log("\uD83D\uDCC1 Created .claude/skills/claudish-usage/ directory");
|
|
79054
79280
|
}
|
|
79055
79281
|
copyFileSync2(sourceSkillPath, skillFile);
|
|
@@ -79273,11 +79499,11 @@ import {
|
|
|
79273
79499
|
chmodSync as chmodSync2,
|
|
79274
79500
|
closeSync as closeSync8,
|
|
79275
79501
|
existsSync as existsSync31,
|
|
79276
|
-
mkdirSync as
|
|
79502
|
+
mkdirSync as mkdirSync20,
|
|
79277
79503
|
mkdtempSync,
|
|
79278
79504
|
openSync as openSync8,
|
|
79279
79505
|
rmSync as rmSync5,
|
|
79280
|
-
writeFileSync as
|
|
79506
|
+
writeFileSync as writeFileSync17
|
|
79281
79507
|
} from "fs";
|
|
79282
79508
|
import { connect as netConnect } from "net";
|
|
79283
79509
|
import { join as join42 } from "path";
|
|
@@ -79345,7 +79571,7 @@ function planMagmuxWrap(input) {
|
|
|
79345
79571
|
const id = `claudish-${pid}`;
|
|
79346
79572
|
const controlSocket = `/tmp/magmux-${id}.sock`;
|
|
79347
79573
|
const tmpRoot = input.tmpRoot ?? "/tmp";
|
|
79348
|
-
|
|
79574
|
+
mkdirSync20(tmpRoot, { recursive: true });
|
|
79349
79575
|
const scriptDir = mkdtempSync(join42(tmpRoot, "claudish-launch-"));
|
|
79350
79576
|
chmodSync2(scriptDir, 448);
|
|
79351
79577
|
const scriptPath = join42(scriptDir, "claude-launch.sh");
|
|
@@ -79353,7 +79579,7 @@ function planMagmuxWrap(input) {
|
|
|
79353
79579
|
const deltas = envDeltas(parentEnv, input.childEnv);
|
|
79354
79580
|
const fd = openSync8(scriptPath, "wx", 384);
|
|
79355
79581
|
try {
|
|
79356
|
-
|
|
79582
|
+
writeFileSync17(fd, buildLauncherScript(input.claudeBinary, input.claudeArgs, deltas));
|
|
79357
79583
|
} finally {
|
|
79358
79584
|
closeSync8(fd);
|
|
79359
79585
|
}
|
|
@@ -79829,7 +80055,7 @@ var init_process_identity = __esm(() => {
|
|
|
79829
80055
|
// src/pane/pane-launch.ts
|
|
79830
80056
|
import { execFile as execFile3, spawn } from "child_process";
|
|
79831
80057
|
import { randomBytes as randomBytes8 } from "crypto";
|
|
79832
|
-
import { chmodSync as chmodSync3, lstatSync as lstatSync2, mkdirSync as
|
|
80058
|
+
import { chmodSync as chmodSync3, lstatSync as lstatSync2, mkdirSync as mkdirSync21, mkdtempSync as mkdtempSync2, writeFileSync as writeFileSync18 } from "fs";
|
|
79833
80059
|
import { join as join44, resolve as resolve3 } from "path";
|
|
79834
80060
|
function uid() {
|
|
79835
80061
|
return typeof process.getuid === "function" ? process.getuid() : 0;
|
|
@@ -79850,17 +80076,17 @@ function assertPrivateDir(p) {
|
|
|
79850
80076
|
function ensureSockRoot(given = sockRootFor()) {
|
|
79851
80077
|
const root = resolve3(given);
|
|
79852
80078
|
try {
|
|
79853
|
-
|
|
80079
|
+
mkdirSync21(root, { mode: 448 });
|
|
79854
80080
|
} catch (e) {
|
|
79855
80081
|
if (e.code === "ENOENT")
|
|
79856
|
-
|
|
80082
|
+
mkdirSync21(root, { recursive: true, mode: 448 });
|
|
79857
80083
|
else if (e.code !== "EEXIST")
|
|
79858
80084
|
throw e;
|
|
79859
80085
|
}
|
|
79860
80086
|
assertPrivateDir(root);
|
|
79861
80087
|
const panes = join44(root, "panes");
|
|
79862
80088
|
try {
|
|
79863
|
-
|
|
80089
|
+
mkdirSync21(panes, { mode: 448 });
|
|
79864
80090
|
} catch (e) {
|
|
79865
80091
|
if (e.code !== "EEXIST")
|
|
79866
80092
|
throw e;
|
|
@@ -80122,8 +80348,8 @@ function createLaunchDirs(root) {
|
|
|
80122
80348
|
return { ctlDir, turnDir };
|
|
80123
80349
|
}
|
|
80124
80350
|
function writeLauncherFiles(ctlDir, script) {
|
|
80125
|
-
|
|
80126
|
-
|
|
80351
|
+
writeFileSync18(join44(ctlDir, "pane-launch.sh"), script, { mode: 384, flag: "wx" });
|
|
80352
|
+
writeFileSync18(join44(ctlDir, "sh-shim"), SHELL_SHIM, { mode: 448, flag: "wx" });
|
|
80127
80353
|
}
|
|
80128
80354
|
function spawnPaneWatcher(args) {
|
|
80129
80355
|
const proc = spawn("/bin/sh", watcherArgv(args), {
|
|
@@ -80527,12 +80753,12 @@ import {
|
|
|
80527
80753
|
accessSync,
|
|
80528
80754
|
existsSync as existsSync32,
|
|
80529
80755
|
lstatSync as lstatSync3,
|
|
80530
|
-
readFileSync as
|
|
80756
|
+
readFileSync as readFileSync31,
|
|
80531
80757
|
readdirSync as readdirSync4,
|
|
80532
|
-
renameSync as
|
|
80758
|
+
renameSync as renameSync6,
|
|
80533
80759
|
rmSync as rmSync6,
|
|
80534
|
-
unlinkSync as
|
|
80535
|
-
writeFileSync as
|
|
80760
|
+
unlinkSync as unlinkSync10,
|
|
80761
|
+
writeFileSync as writeFileSync19
|
|
80536
80762
|
} from "fs";
|
|
80537
80763
|
import { join as join45 } from "path";
|
|
80538
80764
|
function ownerStartOfSelf() {
|
|
@@ -80560,15 +80786,15 @@ function recordsDir(root) {
|
|
|
80560
80786
|
function writeRecord(root, rec) {
|
|
80561
80787
|
const p = recordPathOf(root, rec.paneId);
|
|
80562
80788
|
const tmp = `${p}.tmp-${process.pid}`;
|
|
80563
|
-
|
|
80789
|
+
writeFileSync19(tmp, `${JSON.stringify(rec)}
|
|
80564
80790
|
`, { mode: 384 });
|
|
80565
|
-
|
|
80791
|
+
renameSync6(tmp, p);
|
|
80566
80792
|
}
|
|
80567
80793
|
function readRecord(root, paneId) {
|
|
80568
80794
|
if (!isValidPaneId(paneId))
|
|
80569
80795
|
return null;
|
|
80570
80796
|
try {
|
|
80571
|
-
return validRecord(JSON.parse(
|
|
80797
|
+
return validRecord(JSON.parse(readFileSync31(recordPathOf(root, paneId), "utf8")), paneId);
|
|
80572
80798
|
} catch {
|
|
80573
80799
|
return null;
|
|
80574
80800
|
}
|
|
@@ -80580,7 +80806,7 @@ function updateRecord(root, paneId, patch) {
|
|
|
80580
80806
|
}
|
|
80581
80807
|
function deleteRecord(root, paneId) {
|
|
80582
80808
|
try {
|
|
80583
|
-
|
|
80809
|
+
unlinkSync10(recordPathOf(root, paneId));
|
|
80584
80810
|
} catch {}
|
|
80585
80811
|
}
|
|
80586
80812
|
function validRecord(v, stem) {
|
|
@@ -80625,7 +80851,7 @@ function readRecords(root) {
|
|
|
80625
80851
|
}
|
|
80626
80852
|
function readGroupFile(ctlDir) {
|
|
80627
80853
|
try {
|
|
80628
|
-
return parseGroupFile(
|
|
80854
|
+
return parseGroupFile(readFileSync31(join45(ctlDir, "group"), "utf8"));
|
|
80629
80855
|
} catch {
|
|
80630
80856
|
return null;
|
|
80631
80857
|
}
|
|
@@ -80634,8 +80860,8 @@ function writeGroupFile(ctlDir, snap) {
|
|
|
80634
80860
|
const p = join45(ctlDir, "group");
|
|
80635
80861
|
const tmp = `${p}.tmp`;
|
|
80636
80862
|
try {
|
|
80637
|
-
|
|
80638
|
-
|
|
80863
|
+
writeFileSync19(tmp, formatGroupFile(snap), { mode: 384 });
|
|
80864
|
+
renameSync6(tmp, p);
|
|
80639
80865
|
} catch {}
|
|
80640
80866
|
}
|
|
80641
80867
|
function removePaneFiles(root, f) {
|
|
@@ -81844,7 +82070,7 @@ var init_screen_classifier = __esm(() => {
|
|
|
81844
82070
|
});
|
|
81845
82071
|
|
|
81846
82072
|
// src/pane/session-registry.ts
|
|
81847
|
-
import { readFileSync as
|
|
82073
|
+
import { readFileSync as readFileSync32, readdirSync as readdirSync5 } from "fs";
|
|
81848
82074
|
import { join as join48 } from "path";
|
|
81849
82075
|
function parseRegistryRecord(raw) {
|
|
81850
82076
|
let parsed;
|
|
@@ -81926,7 +82152,7 @@ class SessionRegistry {
|
|
|
81926
82152
|
readPid(pid) {
|
|
81927
82153
|
let raw;
|
|
81928
82154
|
try {
|
|
81929
|
-
raw =
|
|
82155
|
+
raw = readFileSync32(join48(this.dir, `${pid}.json`), "utf8");
|
|
81930
82156
|
} catch {
|
|
81931
82157
|
return null;
|
|
81932
82158
|
}
|
|
@@ -82229,7 +82455,7 @@ import {
|
|
|
82229
82455
|
readSync as readSync4,
|
|
82230
82456
|
readdirSync as readdirSync6,
|
|
82231
82457
|
realpathSync as realpathSync3,
|
|
82232
|
-
statSync as
|
|
82458
|
+
statSync as statSync11
|
|
82233
82459
|
} from "fs";
|
|
82234
82460
|
import { join as join49 } from "path";
|
|
82235
82461
|
function initialFollowerState(resolvePath = safeRealpath) {
|
|
@@ -82862,7 +83088,7 @@ function lastHumanPromptOffset(path) {
|
|
|
82862
83088
|
}
|
|
82863
83089
|
function fileSize(p) {
|
|
82864
83090
|
try {
|
|
82865
|
-
return
|
|
83091
|
+
return statSync11(p).size;
|
|
82866
83092
|
} catch {
|
|
82867
83093
|
return 0;
|
|
82868
83094
|
}
|
|
@@ -82886,7 +83112,7 @@ var init_transcript_follower = __esm(() => {
|
|
|
82886
83112
|
});
|
|
82887
83113
|
|
|
82888
83114
|
// src/pane/pane-session.ts
|
|
82889
|
-
import { readFileSync as
|
|
83115
|
+
import { readFileSync as readFileSync33, realpathSync as realpathSync4, rmSync as rmSync7, statSync as statSync12, writeFileSync as writeFileSync20 } from "fs";
|
|
82890
83116
|
import { join as join50 } from "path";
|
|
82891
83117
|
function iso(ms) {
|
|
82892
83118
|
return new Date(ms).toISOString();
|
|
@@ -83082,7 +83308,7 @@ class PaneSessionImpl {
|
|
|
83082
83308
|
return this.spawnFailed(new Error("magmux did not start"));
|
|
83083
83309
|
this.magmux = proc;
|
|
83084
83310
|
try {
|
|
83085
|
-
|
|
83311
|
+
writeFileSync20(join50(this.ctlDir, "magmux.pid"), `${proc.pid}
|
|
83086
83312
|
`, { mode: 384 });
|
|
83087
83313
|
} catch {}
|
|
83088
83314
|
updateRecord(this.root, this.paneId, { magmuxPid: proc.pid });
|
|
@@ -84800,7 +85026,7 @@ ${screenTailOf(this.screen)}`
|
|
|
84800
85026
|
if (!p)
|
|
84801
85027
|
return 0;
|
|
84802
85028
|
try {
|
|
84803
|
-
return
|
|
85029
|
+
return statSync12(p).size;
|
|
84804
85030
|
} catch {
|
|
84805
85031
|
return 0;
|
|
84806
85032
|
}
|
|
@@ -84809,7 +85035,7 @@ ${screenTailOf(this.screen)}`
|
|
|
84809
85035
|
const p = this.errorLogPath();
|
|
84810
85036
|
if (p && this.errorLogSize() > st.errorLogSize) {
|
|
84811
85037
|
try {
|
|
84812
|
-
const text =
|
|
85038
|
+
const text = readFileSync33(p, "utf8").slice(st.errorLogSize).trim();
|
|
84813
85039
|
return { status: null, category: "upstream_error_log", text };
|
|
84814
85040
|
} catch {}
|
|
84815
85041
|
}
|
|
@@ -85606,7 +85832,7 @@ __export(exports_session_discovery, {
|
|
|
85606
85832
|
transcriptPathFor: () => transcriptPathFor
|
|
85607
85833
|
});
|
|
85608
85834
|
import { execFile as execFile4, execFileSync as execFileSync3 } from "child_process";
|
|
85609
|
-
import { closeSync as closeSync10, openSync as openSync10, readSync as readSync5, readdirSync as readdirSync7, realpathSync as realpathSync5, statSync as
|
|
85835
|
+
import { closeSync as closeSync10, openSync as openSync10, readSync as readSync5, readdirSync as readdirSync7, realpathSync as realpathSync5, statSync as statSync13 } from "fs";
|
|
85610
85836
|
import { basename as basename4, join as join51 } from "path";
|
|
85611
85837
|
function projectsDir(env = process.env) {
|
|
85612
85838
|
return join51(claudeConfigDir(env), "projects");
|
|
@@ -85677,7 +85903,7 @@ function sessionsIn(dirName) {
|
|
|
85677
85903
|
for (const n of names) {
|
|
85678
85904
|
const file = join51(dir, n);
|
|
85679
85905
|
try {
|
|
85680
|
-
const st =
|
|
85906
|
+
const st = statSync13(file);
|
|
85681
85907
|
if (st.size === 0)
|
|
85682
85908
|
continue;
|
|
85683
85909
|
const row = {
|
|
@@ -85838,7 +86064,7 @@ function discoverWorktreeGroups(repo) {
|
|
|
85838
86064
|
g.activeNow = g.sessions.some((s) => isActive(s));
|
|
85839
86065
|
if (g.path) {
|
|
85840
86066
|
try {
|
|
85841
|
-
g.createdMs =
|
|
86067
|
+
g.createdMs = statSync13(g.path).birthtimeMs;
|
|
85842
86068
|
} catch {}
|
|
85843
86069
|
}
|
|
85844
86070
|
if (!g.createdMs && g.sessions.length > 0) {
|
|
@@ -85926,7 +86152,7 @@ function hydrateSession(row) {
|
|
|
85926
86152
|
row.hydrated = true;
|
|
85927
86153
|
if (isActive(row)) {
|
|
85928
86154
|
try {
|
|
85929
|
-
row.sizeBytes =
|
|
86155
|
+
row.sizeBytes = statSync13(row.file).size;
|
|
85930
86156
|
} catch {}
|
|
85931
86157
|
}
|
|
85932
86158
|
const head = parseRecords(readChunk(row.file, 0, Math.min(HEAD_BYTES, row.sizeBytes)), false);
|
|
@@ -86051,17 +86277,17 @@ var init_session_discovery = __esm(() => {
|
|
|
86051
86277
|
});
|
|
86052
86278
|
|
|
86053
86279
|
// src/team-orchestrator.ts
|
|
86054
|
-
import { randomBytes as randomBytes9, randomUUID as
|
|
86280
|
+
import { randomBytes as randomBytes9, randomUUID as randomUUID7 } from "crypto";
|
|
86055
86281
|
import {
|
|
86056
86282
|
existsSync as existsSync34,
|
|
86057
86283
|
lstatSync as lstatSync4,
|
|
86058
|
-
mkdirSync as
|
|
86059
|
-
readFileSync as
|
|
86284
|
+
mkdirSync as mkdirSync22,
|
|
86285
|
+
readFileSync as readFileSync34,
|
|
86060
86286
|
readdirSync as readdirSync8,
|
|
86061
86287
|
realpathSync as realpathSync6,
|
|
86062
86288
|
rmSync as rmSync8,
|
|
86063
|
-
statSync as
|
|
86064
|
-
writeFileSync as
|
|
86289
|
+
statSync as statSync14,
|
|
86290
|
+
writeFileSync as writeFileSync21
|
|
86065
86291
|
} from "fs";
|
|
86066
86292
|
import { basename as basename5, dirname as dirname18, join as join52, resolve as resolve5, sep } from "path";
|
|
86067
86293
|
function slotTerminal(e) {
|
|
@@ -86237,14 +86463,14 @@ function teamRunRowFromDisk(path, status) {
|
|
|
86237
86463
|
}
|
|
86238
86464
|
function statusMtimeMs(path) {
|
|
86239
86465
|
try {
|
|
86240
|
-
return
|
|
86466
|
+
return statSync14(join52(path, "status.json")).mtimeMs;
|
|
86241
86467
|
} catch {
|
|
86242
86468
|
return null;
|
|
86243
86469
|
}
|
|
86244
86470
|
}
|
|
86245
86471
|
function readManifestOrNull(path) {
|
|
86246
86472
|
try {
|
|
86247
|
-
return JSON.parse(
|
|
86473
|
+
return JSON.parse(readFileSync34(join52(path, "manifest.json"), "utf-8"));
|
|
86248
86474
|
} catch {
|
|
86249
86475
|
return null;
|
|
86250
86476
|
}
|
|
@@ -86446,7 +86672,7 @@ function persistErrorLog(errorLogPath, header, sections) {
|
|
|
86446
86672
|
parts.push(`--- ${title} ---`, body.trim() ? redactSecrets(body) : "(empty)", "");
|
|
86447
86673
|
}
|
|
86448
86674
|
try {
|
|
86449
|
-
|
|
86675
|
+
writeFileSync21(errorLogPath, parts.join(`
|
|
86450
86676
|
`), "utf-8");
|
|
86451
86677
|
} catch {}
|
|
86452
86678
|
}
|
|
@@ -86488,7 +86714,7 @@ function readTeamInputFile(inputPath) {
|
|
|
86488
86714
|
if (!existsSync34(resolved)) {
|
|
86489
86715
|
throw new Error(`Input file not found: ${resolved}`);
|
|
86490
86716
|
}
|
|
86491
|
-
const text =
|
|
86717
|
+
const text = readFileSync34(resolved, "utf-8");
|
|
86492
86718
|
if (text.trim().length === 0) {
|
|
86493
86719
|
throw new Error(`Input file is empty: ${resolved}`);
|
|
86494
86720
|
}
|
|
@@ -86501,10 +86727,10 @@ function setupSession(sessionPath, models, input) {
|
|
|
86501
86727
|
if (existsSync34(join52(sessionPath, "manifest.json"))) {
|
|
86502
86728
|
throw new Error(`Session already exists at ${sessionPath}. Use a new directory path or delete the existing session first.`);
|
|
86503
86729
|
}
|
|
86504
|
-
|
|
86505
|
-
|
|
86730
|
+
mkdirSync22(join52(sessionPath, "work"), { recursive: true });
|
|
86731
|
+
mkdirSync22(join52(sessionPath, "errors"), { recursive: true });
|
|
86506
86732
|
if (input !== undefined) {
|
|
86507
|
-
|
|
86733
|
+
writeFileSync21(join52(sessionPath, "input.md"), input, "utf-8");
|
|
86508
86734
|
} else if (!existsSync34(join52(sessionPath, "input.md"))) {
|
|
86509
86735
|
throw new Error(`No input.md found at ${sessionPath} and no input provided`);
|
|
86510
86736
|
}
|
|
@@ -86522,9 +86748,9 @@ function setupSession(sessionPath, models, input) {
|
|
|
86522
86748
|
model: models[i],
|
|
86523
86749
|
assignedAt: now
|
|
86524
86750
|
};
|
|
86525
|
-
|
|
86751
|
+
mkdirSync22(join52(sessionPath, "work", anonId), { recursive: true });
|
|
86526
86752
|
}
|
|
86527
|
-
|
|
86753
|
+
writeFileSync21(join52(sessionPath, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
|
|
86528
86754
|
const status = {
|
|
86529
86755
|
startedAt: now,
|
|
86530
86756
|
models: Object.fromEntries(Object.keys(manifest.models).map((id) => [
|
|
@@ -86539,7 +86765,7 @@ function setupSession(sessionPath, models, input) {
|
|
|
86539
86765
|
}
|
|
86540
86766
|
]))
|
|
86541
86767
|
};
|
|
86542
|
-
|
|
86768
|
+
writeFileAtomic(join52(sessionPath, "status.json"), JSON.stringify(status, null, 2));
|
|
86543
86769
|
return manifest;
|
|
86544
86770
|
}
|
|
86545
86771
|
function assertValidRequirePattern(pattern) {
|
|
@@ -86599,9 +86825,9 @@ async function startModelsIn(flight, sessionPath, opts) {
|
|
|
86599
86825
|
if (!flagCheck.ok)
|
|
86600
86826
|
throw new Error(`invalid_args: ${flagCheck.message}`);
|
|
86601
86827
|
const path = resolve5(sessionPath);
|
|
86602
|
-
const manifest = JSON.parse(
|
|
86828
|
+
const manifest = JSON.parse(readFileSync34(join52(path, "manifest.json"), "utf-8"));
|
|
86603
86829
|
const statusPath = join52(path, "status.json");
|
|
86604
|
-
const inputContent =
|
|
86830
|
+
const inputContent = readFileSync34(join52(path, "input.md"), "utf-8");
|
|
86605
86831
|
const readAvailable = !flagsRemoveRead(claudeFlags);
|
|
86606
86832
|
const refusal = deliveryRefusal(inputContent, readAvailable);
|
|
86607
86833
|
if (refusal)
|
|
@@ -86612,7 +86838,7 @@ async function startModelsIn(flight, sessionPath, opts) {
|
|
|
86612
86838
|
const hookEngine = await (opts.hookEngine ?? (() => loadHooksOnce()))().catch(() => null);
|
|
86613
86839
|
const spawnPlan = await (opts.spawnPlanner ?? prehydrateCredentialsForSpawn)(Object.values(manifest.models).map((m) => m.model));
|
|
86614
86840
|
await assertMagmuxAvailable();
|
|
86615
|
-
const statusCache = JSON.parse(
|
|
86841
|
+
const statusCache = JSON.parse(readFileSync34(statusPath, "utf-8"));
|
|
86616
86842
|
const startMs = Date.now();
|
|
86617
86843
|
const runId = mintRunId(path, startMs);
|
|
86618
86844
|
statusCache.runId = runId;
|
|
@@ -86622,7 +86848,7 @@ async function startModelsIn(flight, sessionPath, opts) {
|
|
|
86622
86848
|
statusCache.models[id] = { ...statusCache.models[id], ...update };
|
|
86623
86849
|
}
|
|
86624
86850
|
function flushStatus() {
|
|
86625
|
-
|
|
86851
|
+
writeFileAtomic(statusPath, JSON.stringify(statusCache, null, 2));
|
|
86626
86852
|
}
|
|
86627
86853
|
function updateModelStatus(id, update) {
|
|
86628
86854
|
if (aborting)
|
|
@@ -86637,16 +86863,20 @@ async function startModelsIn(flight, sessionPath, opts) {
|
|
|
86637
86863
|
}
|
|
86638
86864
|
const minOutputBytes = opts.minOutputBytes ?? DEFAULT_MIN_OUTPUT_BYTES;
|
|
86639
86865
|
const requirePattern = opts.requirePattern;
|
|
86640
|
-
|
|
86866
|
+
mkdirSync22(statsDir(path), { recursive: true });
|
|
86641
86867
|
const entries = new Map;
|
|
86642
86868
|
let run = null;
|
|
86643
86869
|
const errorLogPathOf = (id) => join52(path, "errors", `${id}.log`);
|
|
86644
86870
|
const upstreamLogOf = (id) => upstreamLogPath(path, id);
|
|
86645
|
-
const
|
|
86871
|
+
const flagsOf = (e) => {
|
|
86872
|
+
const effort = opts.efforts?.[e.model];
|
|
86873
|
+
return effort ? [...claudeFlags, "--effort-override", effort] : claudeFlags;
|
|
86874
|
+
};
|
|
86875
|
+
const commandOf = (e) => ["claudish", "-i", "--model", e.spawnModel ?? e.model, "-y", "--quiet", ...flagsOf(e)].join(" ");
|
|
86646
86876
|
function writeResponse(e, text) {
|
|
86647
86877
|
e.answer = text;
|
|
86648
86878
|
try {
|
|
86649
|
-
|
|
86879
|
+
writeFileSync21(join52(path, `response-${e.id}.md`), text, "utf-8");
|
|
86650
86880
|
} catch (err) {
|
|
86651
86881
|
persistErrorLog(errorLogPathOf(e.id), `response file not written: ${String(err)}`, []);
|
|
86652
86882
|
}
|
|
@@ -86656,7 +86886,7 @@ async function startModelsIn(flight, sessionPath, opts) {
|
|
|
86656
86886
|
if (e.answer !== null || !e.session)
|
|
86657
86887
|
return;
|
|
86658
86888
|
try {
|
|
86659
|
-
|
|
86889
|
+
writeFileSync21(join52(path, `response-${e.id}.md`), e.session.chainText(), "utf-8");
|
|
86660
86890
|
} catch (err) {
|
|
86661
86891
|
persistErrorLog(errorLogPathOf(e.id), `response file not written: ${String(err)}`, []);
|
|
86662
86892
|
}
|
|
@@ -86819,7 +87049,7 @@ async function startModelsIn(flight, sessionPath, opts) {
|
|
|
86819
87049
|
session = await startPaneSession({
|
|
86820
87050
|
kind: "t",
|
|
86821
87051
|
label: e.id,
|
|
86822
|
-
callerFlags:
|
|
87052
|
+
callerFlags: flagsOf(e),
|
|
86823
87053
|
spawnModel: e.spawnModel ?? e.model,
|
|
86824
87054
|
cwd,
|
|
86825
87055
|
sessionUuid: uuid,
|
|
@@ -86888,7 +87118,7 @@ async function startModelsIn(flight, sessionPath, opts) {
|
|
|
86888
87118
|
stopReason: null
|
|
86889
87119
|
};
|
|
86890
87120
|
entries.set(id, e);
|
|
86891
|
-
const uuid =
|
|
87121
|
+
const uuid = randomUUID7();
|
|
86892
87122
|
const transcriptPath = transcriptPathFor(cwd, uuid, projects);
|
|
86893
87123
|
updateModelStatus(id, {
|
|
86894
87124
|
state: "STARTING",
|
|
@@ -87013,12 +87243,14 @@ async function startModelsIn(flight, sessionPath, opts) {
|
|
|
87013
87243
|
emitProgress("settled");
|
|
87014
87244
|
try {
|
|
87015
87245
|
opts.onSettled?.(statusCache);
|
|
87016
|
-
} catch {
|
|
87246
|
+
} catch (err) {
|
|
87247
|
+
log(`[team] onSettled failed for ${path}: ${err instanceof Error ? err.message : String(err)}`);
|
|
87248
|
+
}
|
|
87017
87249
|
resolveSettled();
|
|
87018
87250
|
}
|
|
87019
87251
|
return statusCache;
|
|
87020
87252
|
})();
|
|
87021
|
-
done.catch(() => {});
|
|
87253
|
+
done.catch((err) => log(`[team] run failed at ${path}: ${err instanceof Error ? err.message : String(err)}`));
|
|
87022
87254
|
return {
|
|
87023
87255
|
runId,
|
|
87024
87256
|
teamSessionId: basename5(path),
|
|
@@ -87042,14 +87274,14 @@ async function judgeResponses(sessionPath, opts = {}) {
|
|
|
87042
87274
|
const responses = {};
|
|
87043
87275
|
for (const file of responseFiles) {
|
|
87044
87276
|
const id = file.replace(/^response-/, "").replace(/\.md$/, "");
|
|
87045
|
-
responses[id] =
|
|
87277
|
+
responses[id] = readFileSync34(join52(sessionPath, file), "utf-8");
|
|
87046
87278
|
}
|
|
87047
|
-
const input =
|
|
87279
|
+
const input = readFileSync34(join52(sessionPath, "input.md"), "utf-8");
|
|
87048
87280
|
const judgePrompt = buildJudgePrompt(input, responses);
|
|
87049
|
-
|
|
87281
|
+
writeFileSync21(join52(sessionPath, "judge-prompt.md"), judgePrompt, "utf-8");
|
|
87050
87282
|
const judgeModels = opts.judges ?? getDefaultJudgeModels(sessionPath);
|
|
87051
87283
|
const judgePath = join52(sessionPath, "judging");
|
|
87052
|
-
|
|
87284
|
+
mkdirSync22(judgePath, { recursive: true });
|
|
87053
87285
|
setupSession(judgePath, judgeModels, judgePrompt);
|
|
87054
87286
|
await runModels(judgePath, {
|
|
87055
87287
|
claudeFlags: opts.claudeFlags,
|
|
@@ -87059,11 +87291,11 @@ async function judgeResponses(sessionPath, opts = {}) {
|
|
|
87059
87291
|
});
|
|
87060
87292
|
const votes = parseJudgeVotes(judgePath, Object.keys(responses));
|
|
87061
87293
|
const verdict = aggregateVerdict(votes, Object.keys(responses));
|
|
87062
|
-
|
|
87294
|
+
writeFileSync21(join52(sessionPath, "verdict.md"), formatVerdict(verdict, sessionPath), "utf-8");
|
|
87063
87295
|
return verdict;
|
|
87064
87296
|
}
|
|
87065
87297
|
function getStatus(sessionPath) {
|
|
87066
|
-
return JSON.parse(
|
|
87298
|
+
return JSON.parse(readFileSync34(join52(sessionPath, "status.json"), "utf-8"));
|
|
87067
87299
|
}
|
|
87068
87300
|
function readTeamStatus(sessionPath) {
|
|
87069
87301
|
try {
|
|
@@ -87071,7 +87303,11 @@ function readTeamStatus(sessionPath) {
|
|
|
87071
87303
|
if (parsed && typeof parsed === "object" && parsed.models && typeof parsed.models === "object") {
|
|
87072
87304
|
return parsed;
|
|
87073
87305
|
}
|
|
87074
|
-
} catch {
|
|
87306
|
+
} catch (err) {
|
|
87307
|
+
if (err?.code !== "ENOENT") {
|
|
87308
|
+
log(`[team] unreadable status.json at ${sessionPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
87309
|
+
}
|
|
87310
|
+
}
|
|
87075
87311
|
return { startedAt: new Date().toISOString(), models: {} };
|
|
87076
87312
|
}
|
|
87077
87313
|
function summarise(status) {
|
|
@@ -87099,7 +87335,7 @@ function fisherYatesShuffle(arr) {
|
|
|
87099
87335
|
return arr;
|
|
87100
87336
|
}
|
|
87101
87337
|
function getDefaultJudgeModels(sessionPath) {
|
|
87102
|
-
const manifest = JSON.parse(
|
|
87338
|
+
const manifest = JSON.parse(readFileSync34(join52(sessionPath, "manifest.json"), "utf-8"));
|
|
87103
87339
|
return Object.values(manifest.models).map((e) => e.model);
|
|
87104
87340
|
}
|
|
87105
87341
|
function buildJudgePrompt(input, responses) {
|
|
@@ -87162,8 +87398,9 @@ function parseJudgeVotes(judgePath, responseIds) {
|
|
|
87162
87398
|
const judgeId = file.replace(/^response-/, "").replace(/\.md$/, "");
|
|
87163
87399
|
let content;
|
|
87164
87400
|
try {
|
|
87165
|
-
content =
|
|
87166
|
-
} catch {
|
|
87401
|
+
content = readFileSync34(join52(judgePath, file), "utf-8");
|
|
87402
|
+
} catch (err) {
|
|
87403
|
+
log(`[team] judge answer ${file} unreadable: ${err instanceof Error ? err.message : String(err)}`);
|
|
87167
87404
|
continue;
|
|
87168
87405
|
}
|
|
87169
87406
|
const votePattern = /```vote\s*\n([\s\S]*?)\n\s*```/g;
|
|
@@ -87214,7 +87451,7 @@ function aggregateVerdict(votes, responseIds) {
|
|
|
87214
87451
|
function formatVerdict(verdict, sessionPath) {
|
|
87215
87452
|
let manifest = null;
|
|
87216
87453
|
try {
|
|
87217
|
-
manifest = JSON.parse(
|
|
87454
|
+
manifest = JSON.parse(readFileSync34(join52(sessionPath, "manifest.json"), "utf-8"));
|
|
87218
87455
|
} catch {}
|
|
87219
87456
|
let output = `# Team Verdict
|
|
87220
87457
|
|
|
@@ -87249,12 +87486,14 @@ var startsInFlight, teamRuns, newestRunByPath, SETTLED_RUN_RETENTION_MS, MAX_SET
|
|
|
87249
87486
|
var init_team_orchestrator = __esm(() => {
|
|
87250
87487
|
init_prehydrate();
|
|
87251
87488
|
init_config();
|
|
87489
|
+
init_fs_atomic();
|
|
87252
87490
|
init_upstream_error_capture();
|
|
87253
87491
|
init_hooks();
|
|
87254
87492
|
init_inbox();
|
|
87255
87493
|
init_sinks();
|
|
87256
87494
|
init_request_stage();
|
|
87257
87495
|
init_binding();
|
|
87496
|
+
init_logger();
|
|
87258
87497
|
init_pane();
|
|
87259
87498
|
init_redact();
|
|
87260
87499
|
init_session_discovery();
|
|
@@ -87267,7 +87506,7 @@ var init_team_orchestrator = __esm(() => {
|
|
|
87267
87506
|
});
|
|
87268
87507
|
|
|
87269
87508
|
// src/mcp-session/inherited-settings.ts
|
|
87270
|
-
import { existsSync as existsSync35, readFileSync as
|
|
87509
|
+
import { existsSync as existsSync35, readFileSync as readFileSync35, statSync as statSync15 } from "fs";
|
|
87271
87510
|
import { join as join53, resolve as resolve6 } from "path";
|
|
87272
87511
|
function isPlainObject7(value) {
|
|
87273
87512
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -87313,7 +87552,7 @@ function readSettingsValue(value) {
|
|
|
87313
87552
|
return parseLayer(value, value);
|
|
87314
87553
|
let text;
|
|
87315
87554
|
try {
|
|
87316
|
-
text =
|
|
87555
|
+
text = readFileSync35(value, "utf-8");
|
|
87317
87556
|
} catch (err) {
|
|
87318
87557
|
throw new Error(`invalid_args: settings ${value} cannot be read (${err.message})`);
|
|
87319
87558
|
}
|
|
@@ -87325,7 +87564,7 @@ function buildInheritedSettingsLayer(setupFrom, callerFlags) {
|
|
|
87325
87564
|
const file = join53(setupFrom, ".claude", name);
|
|
87326
87565
|
if (!existsSync35(file))
|
|
87327
87566
|
continue;
|
|
87328
|
-
layers.push(parseLayer(
|
|
87567
|
+
layers.push(parseLayer(readFileSync35(file, "utf-8"), file));
|
|
87329
87568
|
}
|
|
87330
87569
|
const restFlags = [];
|
|
87331
87570
|
for (let i = 0;i < callerFlags.length; i++) {
|
|
@@ -87355,7 +87594,7 @@ function resolveSetupFrom(arg, workDir, serverCwd) {
|
|
|
87355
87594
|
let setupFrom = serverCwd;
|
|
87356
87595
|
if (typeof arg === "string") {
|
|
87357
87596
|
setupFrom = resolve6(arg);
|
|
87358
|
-
if (!
|
|
87597
|
+
if (!statSync15(setupFrom, { throwIfNoEntry: false })?.isDirectory()) {
|
|
87359
87598
|
throw new Error(`invalid_args: setup_from ${setupFrom} is not an existing directory`);
|
|
87360
87599
|
}
|
|
87361
87600
|
} else if (arg !== undefined) {
|
|
@@ -87366,20 +87605,20 @@ function resolveSetupFrom(arg, workDir, serverCwd) {
|
|
|
87366
87605
|
var init_inherited_settings = () => {};
|
|
87367
87606
|
|
|
87368
87607
|
// src/mcp-session/session-manager.ts
|
|
87369
|
-
import { randomUUID as
|
|
87608
|
+
import { randomUUID as randomUUID8 } from "crypto";
|
|
87370
87609
|
import {
|
|
87371
87610
|
appendFileSync as appendFileSync7,
|
|
87372
87611
|
closeSync as closeSync11,
|
|
87373
87612
|
createWriteStream,
|
|
87374
87613
|
existsSync as existsSync36,
|
|
87375
|
-
mkdirSync as
|
|
87614
|
+
mkdirSync as mkdirSync23,
|
|
87376
87615
|
openSync as openSync11,
|
|
87377
|
-
readFileSync as
|
|
87616
|
+
readFileSync as readFileSync36,
|
|
87378
87617
|
readSync as readSync6,
|
|
87379
|
-
renameSync as
|
|
87618
|
+
renameSync as renameSync7,
|
|
87380
87619
|
rmSync as rmSync9,
|
|
87381
|
-
statSync as
|
|
87382
|
-
writeFileSync as
|
|
87620
|
+
statSync as statSync16,
|
|
87621
|
+
writeFileSync as writeFileSync22
|
|
87383
87622
|
} from "fs";
|
|
87384
87623
|
import { join as join54, resolve as resolve7, sep as sep2 } from "path";
|
|
87385
87624
|
function normaliseTimeoutSeconds(raw) {
|
|
@@ -87471,8 +87710,8 @@ function toMetaRecord(info, cwd) {
|
|
|
87471
87710
|
}
|
|
87472
87711
|
function writeJsonAtomic(path, value) {
|
|
87473
87712
|
const tmp = `${path}.tmp`;
|
|
87474
|
-
|
|
87475
|
-
|
|
87713
|
+
writeFileSync22(tmp, JSON.stringify(value, null, 2), "utf-8");
|
|
87714
|
+
renameSync7(tmp, path);
|
|
87476
87715
|
}
|
|
87477
87716
|
function anomalyKey(a) {
|
|
87478
87717
|
const at = a.lastIndexOf(" \xD7");
|
|
@@ -87481,7 +87720,7 @@ function anomalyKey(a) {
|
|
|
87481
87720
|
function readTailText(path, maxBytes) {
|
|
87482
87721
|
let fd = null;
|
|
87483
87722
|
try {
|
|
87484
|
-
const size =
|
|
87723
|
+
const size = statSync16(path).size;
|
|
87485
87724
|
if (size === 0)
|
|
87486
87725
|
return { text: "", truncated: false };
|
|
87487
87726
|
const start = Math.max(0, size - maxBytes);
|
|
@@ -87512,7 +87751,7 @@ function readTailLines2(path, maxBytes) {
|
|
|
87512
87751
|
}
|
|
87513
87752
|
function fileSize2(path) {
|
|
87514
87753
|
try {
|
|
87515
|
-
return
|
|
87754
|
+
return statSync16(path).size;
|
|
87516
87755
|
} catch {
|
|
87517
87756
|
return 0;
|
|
87518
87757
|
}
|
|
@@ -87521,7 +87760,7 @@ function readJsonObject(path, maxBytes) {
|
|
|
87521
87760
|
try {
|
|
87522
87761
|
if (fileSize2(path) > maxBytes)
|
|
87523
87762
|
return null;
|
|
87524
|
-
const parsed = JSON.parse(
|
|
87763
|
+
const parsed = JSON.parse(readFileSync36(path, "utf-8"));
|
|
87525
87764
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
87526
87765
|
return null;
|
|
87527
87766
|
return parsed;
|
|
@@ -87625,14 +87864,14 @@ class SessionManager {
|
|
|
87625
87864
|
return this._launcherPid;
|
|
87626
87865
|
}
|
|
87627
87866
|
recordTeamRun(opts) {
|
|
87628
|
-
|
|
87867
|
+
mkdirSync23(this.sessionsDir, { recursive: true });
|
|
87629
87868
|
let id = "";
|
|
87630
87869
|
let dir = "";
|
|
87631
87870
|
for (let attempt = 0;; attempt++) {
|
|
87632
|
-
id = `team-${
|
|
87871
|
+
id = `team-${randomUUID8().replace(/-/g, "").slice(0, 8)}`;
|
|
87633
87872
|
dir = join54(this.sessionsDir, id);
|
|
87634
87873
|
try {
|
|
87635
|
-
|
|
87874
|
+
mkdirSync23(dir);
|
|
87636
87875
|
break;
|
|
87637
87876
|
} catch (err) {
|
|
87638
87877
|
if (err?.code !== "EEXIST" || attempt >= 4)
|
|
@@ -87756,14 +87995,14 @@ class SessionManager {
|
|
|
87756
87995
|
}
|
|
87757
87996
|
}
|
|
87758
87997
|
recordSession(opts, inheritedLayer) {
|
|
87759
|
-
const sessionId = opts.sessionId ??
|
|
87760
|
-
const claudeSessionId =
|
|
87998
|
+
const sessionId = opts.sessionId ?? randomUUID8().slice(0, 8);
|
|
87999
|
+
const claudeSessionId = randomUUID8();
|
|
87761
88000
|
const timeout = normaliseTimeoutSeconds(opts.timeoutSeconds);
|
|
87762
88001
|
const startedAt = new Date().toISOString();
|
|
87763
88002
|
const sessionDir = opts.sessionDir ?? join54(this.sessionsDir, sessionId);
|
|
87764
|
-
|
|
88003
|
+
mkdirSync23(sessionDir, { recursive: true });
|
|
87765
88004
|
if (opts.prompt)
|
|
87766
|
-
|
|
88005
|
+
writeFileSync22(join54(sessionDir, "prompt.md"), opts.prompt, "utf-8");
|
|
87767
88006
|
this.writeSpawnRecord(sessionDir, {
|
|
87768
88007
|
kind: "session",
|
|
87769
88008
|
sessionId,
|
|
@@ -87775,7 +88014,7 @@ class SessionManager {
|
|
|
87775
88014
|
...opts.setupFrom ? { setupFrom: opts.setupFrom } : {}
|
|
87776
88015
|
});
|
|
87777
88016
|
if (inheritedLayer) {
|
|
87778
|
-
|
|
88017
|
+
writeFileSync22(join54(sessionDir, INHERITED_SETTINGS), `${JSON.stringify(inheritedLayer, null, 2)}
|
|
87779
88018
|
`, { encoding: "utf-8", mode: 384 });
|
|
87780
88019
|
}
|
|
87781
88020
|
const cwd = opts.cwd ?? process.cwd();
|
|
@@ -88017,7 +88256,7 @@ class SessionManager {
|
|
|
88017
88256
|
try {
|
|
88018
88257
|
const text = screenLines.join(`
|
|
88019
88258
|
`).replace(/\s+$/, "");
|
|
88020
|
-
|
|
88259
|
+
writeFileSync22(join54(entry.sessionDir, "screen.txt"), `${redactSecrets(text)}
|
|
88021
88260
|
`, "utf-8");
|
|
88022
88261
|
} catch {}
|
|
88023
88262
|
}
|
|
@@ -88304,7 +88543,7 @@ class SessionManager {
|
|
|
88304
88543
|
return null;
|
|
88305
88544
|
let dirMtimeMs;
|
|
88306
88545
|
try {
|
|
88307
|
-
const stat =
|
|
88546
|
+
const stat = statSync16(sessionDir);
|
|
88308
88547
|
if (!stat.isDirectory())
|
|
88309
88548
|
return null;
|
|
88310
88549
|
dirMtimeMs = stat.mtimeMs;
|
|
@@ -88756,7 +88995,7 @@ var init_progress_heartbeat = __esm(() => {
|
|
|
88756
88995
|
|
|
88757
88996
|
// src/mcp/run-prompt-claude-code.ts
|
|
88758
88997
|
import { spawn as spawn2 } from "child_process";
|
|
88759
|
-
import { mkdirSync as
|
|
88998
|
+
import { mkdirSync as mkdirSync24, mkdtempSync as mkdtempSync3, rmSync as rmSync10, writeFileSync as writeFileSync23 } from "fs";
|
|
88760
88999
|
import { tmpdir as tmpdir2 } from "os";
|
|
88761
89000
|
import { join as join55 } from "path";
|
|
88762
89001
|
function claudeCodePrintArgv(model, systemPromptFile) {
|
|
@@ -88879,11 +89118,11 @@ async function runPromptViaClaudeCode(model, prompt, systemPrompt, opts = {}) {
|
|
|
88879
89118
|
const root = mkdtempSync3(join55(tmpdir2(), "claudish-run-prompt-"));
|
|
88880
89119
|
try {
|
|
88881
89120
|
const cwd = join55(root, "cwd");
|
|
88882
|
-
|
|
89121
|
+
mkdirSync24(cwd, { mode: 448 });
|
|
88883
89122
|
let systemPromptFile;
|
|
88884
89123
|
if (typeof systemPrompt === "string" && systemPrompt.length > 0) {
|
|
88885
89124
|
systemPromptFile = join55(root, "system-prompt.txt");
|
|
88886
|
-
|
|
89125
|
+
writeFileSync23(systemPromptFile, systemPrompt, { mode: 384 });
|
|
88887
89126
|
}
|
|
88888
89127
|
const argv = claudeCodePrintArgv(model, systemPromptFile);
|
|
88889
89128
|
const outcome = await runChild(launch, argv, cwd, claudeCodePrintEnv(parentEnv), prompt, signal);
|
|
@@ -89182,14 +89421,14 @@ var init_preflight_chain = __esm(() => {
|
|
|
89182
89421
|
});
|
|
89183
89422
|
|
|
89184
89423
|
// src/mcp-server.ts
|
|
89185
|
-
import { existsSync as existsSync37,
|
|
89424
|
+
import { existsSync as existsSync37, readFileSync as readFileSync37, readdirSync as readdirSync9 } from "fs";
|
|
89186
89425
|
import { homedir as homedir37 } from "os";
|
|
89187
89426
|
import { dirname as dirname19, join as join56, resolve as resolve8 } from "path";
|
|
89188
89427
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
89189
89428
|
async function loadAllModels(forceRefresh = false) {
|
|
89190
89429
|
if (!forceRefresh && existsSync37(OPENROUTER_MODELS_CACHE_PATH)) {
|
|
89191
89430
|
try {
|
|
89192
|
-
const cacheData = JSON.parse(
|
|
89431
|
+
const cacheData = JSON.parse(readFileSync37(OPENROUTER_MODELS_CACHE_PATH, "utf-8"));
|
|
89193
89432
|
const lastUpdated = new Date(cacheData.lastUpdated);
|
|
89194
89433
|
const ageInDays = (Date.now() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
|
|
89195
89434
|
if (ageInDays <= CACHE_MAX_AGE_DAYS) {
|
|
@@ -89203,13 +89442,21 @@ async function loadAllModels(forceRefresh = false) {
|
|
|
89203
89442
|
throw new Error(`API returned ${response.status}`);
|
|
89204
89443
|
const data = await response.json();
|
|
89205
89444
|
const models = data.data || [];
|
|
89206
|
-
|
|
89207
|
-
|
|
89445
|
+
try {
|
|
89446
|
+
writeFileAtomic(OPENROUTER_MODELS_CACHE_PATH, JSON.stringify({ lastUpdated: new Date().toISOString(), models }));
|
|
89447
|
+
} catch (err) {
|
|
89448
|
+
log(`[mcp] OpenRouter models cache write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
89449
|
+
}
|
|
89208
89450
|
return models;
|
|
89209
|
-
} catch {
|
|
89210
|
-
|
|
89211
|
-
|
|
89212
|
-
|
|
89451
|
+
} catch (err) {
|
|
89452
|
+
log(`[mcp] OpenRouter models fetch failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
89453
|
+
try {
|
|
89454
|
+
if (existsSync37(OPENROUTER_MODELS_CACHE_PATH)) {
|
|
89455
|
+
const cacheData = JSON.parse(readFileSync37(OPENROUTER_MODELS_CACHE_PATH, "utf-8"));
|
|
89456
|
+
return cacheData.models || [];
|
|
89457
|
+
}
|
|
89458
|
+
} catch (cacheErr) {
|
|
89459
|
+
log(`[mcp] OpenRouter models cache unreadable: ${cacheErr instanceof Error ? cacheErr.message : String(cacheErr)}`);
|
|
89213
89460
|
}
|
|
89214
89461
|
return [];
|
|
89215
89462
|
}
|
|
@@ -89260,7 +89507,7 @@ function parseAnthropicSse(raw) {
|
|
|
89260
89507
|
}
|
|
89261
89508
|
return { text, usage: hasUsage ? { input: inputTokens, output: outputTokens } : undefined };
|
|
89262
89509
|
}
|
|
89263
|
-
async function runPromptViaProxy(model, prompt, systemPrompt) {
|
|
89510
|
+
async function runPromptViaProxy(model, prompt, systemPrompt, effort) {
|
|
89264
89511
|
const proxy = await getProxy();
|
|
89265
89512
|
const body = {
|
|
89266
89513
|
model,
|
|
@@ -89270,6 +89517,9 @@ async function runPromptViaProxy(model, prompt, systemPrompt) {
|
|
|
89270
89517
|
if (systemPrompt) {
|
|
89271
89518
|
body.system = systemPrompt;
|
|
89272
89519
|
}
|
|
89520
|
+
if (effort) {
|
|
89521
|
+
body.output_config = { effort };
|
|
89522
|
+
}
|
|
89273
89523
|
const response = await fetch(`${proxy.url}/v1/messages`, {
|
|
89274
89524
|
method: "POST",
|
|
89275
89525
|
headers: { "Content-Type": "application/json" },
|
|
@@ -89286,11 +89536,11 @@ async function runPromptViaProxy(model, prompt, systemPrompt) {
|
|
|
89286
89536
|
}
|
|
89287
89537
|
return { content: parsed.text, usage: parsed.usage };
|
|
89288
89538
|
}
|
|
89289
|
-
async function runPrompt(model, prompt, systemPrompt, signal) {
|
|
89539
|
+
async function runPrompt(model, prompt, systemPrompt, signal, effort) {
|
|
89290
89540
|
if (nativeRouteFor(model) !== null) {
|
|
89291
89541
|
return runPromptViaClaudeCode(model, prompt, systemPrompt, { signal });
|
|
89292
89542
|
}
|
|
89293
|
-
return runPromptViaProxy(model, prompt, systemPrompt);
|
|
89543
|
+
return runPromptViaProxy(model, prompt, systemPrompt, effort);
|
|
89294
89544
|
}
|
|
89295
89545
|
function formatRunPromptResult(result) {
|
|
89296
89546
|
const footer = [];
|
|
@@ -89336,6 +89586,110 @@ function fmtSize(n) {
|
|
|
89336
89586
|
return `${(n / 1024).toFixed(1)}KB`;
|
|
89337
89587
|
return `${(n / (1024 * 1024)).toFixed(1)}MB`;
|
|
89338
89588
|
}
|
|
89589
|
+
function effortArg(value) {
|
|
89590
|
+
if (value === undefined || value === null || value === "" || value === KEEP_EFFORT) {
|
|
89591
|
+
return;
|
|
89592
|
+
}
|
|
89593
|
+
if (isEffortLevel(value))
|
|
89594
|
+
return value;
|
|
89595
|
+
throw new Error(`Invalid 'effort': ${JSON.stringify(value)}. Expected one of ${EFFORT_LEVELS.join(", ")} ` + `or "${KEEP_EFFORT}" (list_models shows the recommended level per model and task type).`);
|
|
89596
|
+
}
|
|
89597
|
+
function effortClarification(specs, efforts = latestEffortRecommendations()?.efforts) {
|
|
89598
|
+
if (!efforts)
|
|
89599
|
+
return;
|
|
89600
|
+
const out = {};
|
|
89601
|
+
for (const spec of specs) {
|
|
89602
|
+
if (nativeRouteFor(spec) !== null)
|
|
89603
|
+
continue;
|
|
89604
|
+
const row = efforts[parseModelSpec(spec).model];
|
|
89605
|
+
if (!row)
|
|
89606
|
+
continue;
|
|
89607
|
+
out[spec] = Object.fromEntries(Object.entries(row).map(([task, rec]) => [task, rec.effort]));
|
|
89608
|
+
}
|
|
89609
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
89610
|
+
}
|
|
89611
|
+
function needsEffortResult(recommended, how) {
|
|
89612
|
+
return {
|
|
89613
|
+
content: [
|
|
89614
|
+
{
|
|
89615
|
+
type: "text",
|
|
89616
|
+
text: `needs_effort: nothing was started. Map your task to one task type and call again ${how}.
|
|
89617
|
+
` + `Recommended levels: ${JSON.stringify(recommended, null, 2)}`
|
|
89618
|
+
}
|
|
89619
|
+
],
|
|
89620
|
+
isError: true
|
|
89621
|
+
};
|
|
89622
|
+
}
|
|
89623
|
+
function modelEffortsArg(value, models) {
|
|
89624
|
+
if (value === undefined || value === null)
|
|
89625
|
+
return;
|
|
89626
|
+
if (typeof value !== "object" || Array.isArray(value)) {
|
|
89627
|
+
throw new Error(`Invalid 'efforts': expected an object like {"<model>": "<level>"}.`);
|
|
89628
|
+
}
|
|
89629
|
+
const out = {};
|
|
89630
|
+
for (const [model, level] of Object.entries(value)) {
|
|
89631
|
+
if (!models.includes(model)) {
|
|
89632
|
+
throw new Error(`Invalid 'efforts': ${JSON.stringify(model)} is not one of 'models' ` + `(${models.join(", ")}). Keys must match a 'models' entry exactly.`);
|
|
89633
|
+
}
|
|
89634
|
+
if (!isEffortLevel(level)) {
|
|
89635
|
+
throw new Error(`Invalid 'efforts' for ${model}: ${JSON.stringify(level)}. ` + `Expected one of ${EFFORT_LEVELS.join(", ")}.`);
|
|
89636
|
+
}
|
|
89637
|
+
out[model] = level;
|
|
89638
|
+
}
|
|
89639
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
89640
|
+
}
|
|
89641
|
+
function isCanonicalCatalogModel(id) {
|
|
89642
|
+
return readAllModelsCache()?.entries.some((e) => e.modelId === id) ?? false;
|
|
89643
|
+
}
|
|
89644
|
+
function stripUnrequestedProvider(spec, required, isCatalogModel = isCanonicalCatalogModel) {
|
|
89645
|
+
if (required || parseModelChain(spec).length !== 1)
|
|
89646
|
+
return spec;
|
|
89647
|
+
const parsed = parseModelSpec(spec);
|
|
89648
|
+
if (!parsed.isExplicitProvider || parsed.isLegacySyntax)
|
|
89649
|
+
return spec;
|
|
89650
|
+
const builtin = BUILTIN_PROVIDERS.find((p) => p.name === parsed.provider);
|
|
89651
|
+
if (!builtin || builtin.isLocal || isLocalProviderName(parsed.provider))
|
|
89652
|
+
return spec;
|
|
89653
|
+
if (!isCatalogModel(parsed.model))
|
|
89654
|
+
return spec;
|
|
89655
|
+
return spec.slice(spec.indexOf("@") + 1);
|
|
89656
|
+
}
|
|
89657
|
+
function userRequiredProvidersArg(value, specs) {
|
|
89658
|
+
if (value === undefined || value === null)
|
|
89659
|
+
return new Set;
|
|
89660
|
+
if (!Array.isArray(value) || value.some((v) => typeof v !== "string")) {
|
|
89661
|
+
throw new Error(`Invalid 'user_required_provider': expected an array of model specs.`);
|
|
89662
|
+
}
|
|
89663
|
+
for (const spec of value) {
|
|
89664
|
+
if (!specs.includes(spec)) {
|
|
89665
|
+
throw new Error(`Invalid 'user_required_provider': ${JSON.stringify(spec)} is not one of the ` + `models (${specs.join(", ")}). Entries must match a 'models' or 'judges' entry exactly.`);
|
|
89666
|
+
}
|
|
89667
|
+
}
|
|
89668
|
+
return new Set(value);
|
|
89669
|
+
}
|
|
89670
|
+
function strippedProviders(specs, required, isCatalogModel) {
|
|
89671
|
+
const proposed = specs.map((from) => stripUnrequestedProvider(from, required.has(from), isCatalogModel));
|
|
89672
|
+
const stripped = [];
|
|
89673
|
+
const out = specs.map((from, i) => {
|
|
89674
|
+
const to = proposed[i];
|
|
89675
|
+
if (to === from)
|
|
89676
|
+
return from;
|
|
89677
|
+
const collides = proposed.some((other, j) => j !== i && other === to && specs[j] !== from);
|
|
89678
|
+
if (collides)
|
|
89679
|
+
return from;
|
|
89680
|
+
stripped.push({ from, to });
|
|
89681
|
+
return to;
|
|
89682
|
+
});
|
|
89683
|
+
if (stripped.length > 0) {
|
|
89684
|
+
log(`[mcp] provider removed: ${stripped.map((x) => `${x.from} -> ${x.to}`).join(", ")}`);
|
|
89685
|
+
}
|
|
89686
|
+
return { specs: out, stripped };
|
|
89687
|
+
}
|
|
89688
|
+
function strippedNote(stripped) {
|
|
89689
|
+
if (stripped.length === 0)
|
|
89690
|
+
return;
|
|
89691
|
+
return `Provider removed so claudish routing decides: ${stripped.map((x) => `${x.from} -> ${x.to}`).join(", ")}. ` + "Pass 'user_required_provider' only when the user named the provider.";
|
|
89692
|
+
}
|
|
89339
89693
|
function buildChildClaudeFlags(agent, claudeFlags) {
|
|
89340
89694
|
const extra = typeof claudeFlags === "string" ? claudeFlags.split(/\s+/).filter(Boolean) : [];
|
|
89341
89695
|
const named = typeof agent === "string" ? agent.trim() : "";
|
|
@@ -89486,7 +89840,10 @@ function teamStatusAnswer(path, runId) {
|
|
|
89486
89840
|
let status;
|
|
89487
89841
|
try {
|
|
89488
89842
|
status = getStatus(path);
|
|
89489
|
-
} catch {
|
|
89843
|
+
} catch (err) {
|
|
89844
|
+
if (err?.code !== "ENOENT") {
|
|
89845
|
+
log(`[team] unreadable status.json at ${path}: ${err instanceof Error ? err.message : String(err)}`);
|
|
89846
|
+
}
|
|
89490
89847
|
if (row)
|
|
89491
89848
|
return { ...contractMeta(), run: row };
|
|
89492
89849
|
throw new ContractErrorException("unknown_run", `no team run at ${path}: no status.json there and no run held by this server`);
|
|
@@ -89551,10 +89908,19 @@ ${block.join(`
|
|
|
89551
89908
|
properties: {
|
|
89552
89909
|
model: {
|
|
89553
89910
|
type: "string",
|
|
89554
|
-
description: "Model name
|
|
89911
|
+
description: "Model name. Pass the bare name (e.g. 'gemini-4-argon'): claudish routing picks " + "the provider from the user's setup. A 'provider@' on a catalog model is removed " + "unless 'user_required_provider' is true. A bare Claude name (claude-*, opus, " + "sonnet, haiku) runs on Claude Code's own login."
|
|
89912
|
+
},
|
|
89913
|
+
user_required_provider: {
|
|
89914
|
+
type: "boolean",
|
|
89915
|
+
description: "True only when the USER named the provider ('use OpenRouter for it'): the " + "'provider@model' spec is then sent as given."
|
|
89555
89916
|
},
|
|
89556
89917
|
prompt: { type: "string", description: "The prompt to send to the model" },
|
|
89557
|
-
system_prompt: { type: "string", description: "Optional system prompt" }
|
|
89918
|
+
system_prompt: { type: "string", description: "Optional system prompt" },
|
|
89919
|
+
effort: {
|
|
89920
|
+
type: "string",
|
|
89921
|
+
enum: [...EFFORT_LEVELS, KEEP_EFFORT],
|
|
89922
|
+
description: "Reasoning effort for this request. Take it from list_models' " + "'Recommended effort by task type' table: your task's column, this model's row. " + "Omitted for a model that has a row, the call starts nothing and answers " + `'needs_effort' with that row; "${KEEP_EFFORT}" keeps Claude Code's own level. ` + "Mapped onto the levels the model's connection publishes. Ignored for a bare " + "Claude name."
|
|
89923
|
+
}
|
|
89558
89924
|
},
|
|
89559
89925
|
required: ["model", "prompt"]
|
|
89560
89926
|
},
|
|
@@ -89562,8 +89928,16 @@ ${block.join(`
|
|
|
89562
89928
|
heartbeat: true,
|
|
89563
89929
|
handler: async (args, ctx) => {
|
|
89564
89930
|
try {
|
|
89565
|
-
const
|
|
89566
|
-
|
|
89931
|
+
const { specs, stripped } = strippedProviders([args.model], new Set(args.user_required_provider === true ? [args.model] : []));
|
|
89932
|
+
const recommended = args.effort === undefined ? effortClarification([args.model]) : undefined;
|
|
89933
|
+
if (recommended) {
|
|
89934
|
+
return needsEffortResult(recommended, `with effort: "<level>" (effort: "${KEEP_EFFORT}" keeps Claude Code's own)`);
|
|
89935
|
+
}
|
|
89936
|
+
const result = await runPrompt(specs[0], args.prompt, args.system_prompt, ctx.signal, effortArg(args.effort));
|
|
89937
|
+
const text = [strippedNote(stripped), formatRunPromptResult(result)].filter(Boolean).join(`
|
|
89938
|
+
|
|
89939
|
+
`);
|
|
89940
|
+
return { content: [{ type: "text", text }] };
|
|
89567
89941
|
} catch (error) {
|
|
89568
89942
|
const errMsg = error instanceof Error ? error.message : String(error);
|
|
89569
89943
|
return {
|
|
@@ -89583,41 +89957,35 @@ ${block.join(`
|
|
|
89583
89957
|
});
|
|
89584
89958
|
tools.push({
|
|
89585
89959
|
name: "list_models",
|
|
89586
|
-
description: "List recommended models for coding tasks",
|
|
89960
|
+
description: "List recommended models for coding tasks, and the catalog's recommended reasoning " + "effort per model and task type (pass it as team 'efforts' or create_session / " + "run_prompt 'effort')",
|
|
89587
89961
|
inputSchema: { type: "object" },
|
|
89588
89962
|
group: "low-level",
|
|
89589
89963
|
handler: async () => {
|
|
89590
|
-
let doc;
|
|
89964
|
+
let doc = null;
|
|
89965
|
+
let note = "";
|
|
89591
89966
|
try {
|
|
89592
89967
|
doc = await getRecommendedModels();
|
|
89593
|
-
|
|
89594
|
-
|
|
89595
|
-
|
|
89596
|
-
|
|
89597
|
-
|
|
89598
|
-
|
|
89599
|
-
}
|
|
89600
|
-
]
|
|
89601
|
-
};
|
|
89968
|
+
if (!doc.models || doc.models.length === 0) {
|
|
89969
|
+
log("[mcp] list_models: the recommended list is empty");
|
|
89970
|
+
doc = null;
|
|
89971
|
+
}
|
|
89972
|
+
} catch (err) {
|
|
89973
|
+
log(`[mcp] list_models: ${err instanceof Error ? err.message : String(err)}`);
|
|
89602
89974
|
}
|
|
89603
|
-
if (!doc
|
|
89604
|
-
|
|
89605
|
-
|
|
89606
|
-
|
|
89607
|
-
|
|
89608
|
-
|
|
89609
|
-
}
|
|
89610
|
-
]
|
|
89611
|
-
};
|
|
89975
|
+
if (!doc) {
|
|
89976
|
+
doc = readLastRecommendedModels();
|
|
89977
|
+
if (doc) {
|
|
89978
|
+
note = "_The live catalog could not be read; this list is from generation " + `${doc.generationId ?? "unknown"}, the last one this machine stored._`;
|
|
89979
|
+
log(`[mcp] list_models: answered from stored generation ${doc.generationId ?? "unknown"}`);
|
|
89980
|
+
}
|
|
89612
89981
|
}
|
|
89613
|
-
|
|
89614
|
-
|
|
89615
|
-
|
|
89616
|
-
|
|
89617
|
-
|
|
89618
|
-
|
|
89619
|
-
|
|
89620
|
-
};
|
|
89982
|
+
const efforts = latestEffortRecommendations();
|
|
89983
|
+
const effortTable = efforts ? renderEffortTableMarkdown(efforts.efforts) : "";
|
|
89984
|
+
const listing = doc ? renderRecommendedMarkdown(doc) : "No recommended models found. Try search_models instead.";
|
|
89985
|
+
const text = [note, listing, effortTable].filter(Boolean).join(`
|
|
89986
|
+
|
|
89987
|
+
`);
|
|
89988
|
+
return { content: [{ type: "text", text }] };
|
|
89621
89989
|
}
|
|
89622
89990
|
});
|
|
89623
89991
|
tools.push({
|
|
@@ -89878,11 +90246,21 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
89878
90246
|
items: { type: "string" },
|
|
89879
90247
|
description: "Model IDs to run (required for 'run' and 'run-and-judge' modes). " + "Native Claude names ARE runnable slots and belong in this array alongside " + "external models: 'internal'/'default' select the default tier, and " + "'opus'/'sonnet'/'haiku'/'claude-*' select a specific one. They run on the " + "user's Claude subscription through the native passthrough (no API key, no " + "translation), and \u2014 unlike a Task agent \u2014 they are covered by require_pattern, " + "so a native reviewer that never produced the required shape is reported " + "EMPTY 'shape_mismatch' instead of silently succeeding."
|
|
89880
90248
|
},
|
|
90249
|
+
efforts: {
|
|
90250
|
+
type: "object",
|
|
90251
|
+
additionalProperties: { type: "string", enum: [...EFFORT_LEVELS] },
|
|
90252
|
+
description: "Reasoning effort per model for 'run' and 'run-and-judge', e.g. " + `{"gpt-6-luna": "high", "kimi-k3": "max"}. Keys must match a 'models' ` + "entry exactly. Take each level from list_models' 'Recommended effort by task " + "type' table: your task's column, the model's row. The slot pins that level on " + "every request (claudish --effort-override); a model without an entry keeps " + "Claude Code's own effort. Omitted while a model has a row, nothing starts and " + "the answer is 'needs_effort' with the rows; {} keeps Claude Code's own for all."
|
|
90253
|
+
},
|
|
89881
90254
|
judges: {
|
|
89882
90255
|
type: "array",
|
|
89883
90256
|
items: { type: "string" },
|
|
89884
90257
|
description: "Model IDs to use as judges (default: same as runners)"
|
|
89885
90258
|
},
|
|
90259
|
+
user_required_provider: {
|
|
90260
|
+
type: "array",
|
|
90261
|
+
items: { type: "string" },
|
|
90262
|
+
description: "The 'models' or 'judges' entries whose provider the USER named ('run Kimi on " + "OpenRouter'), exactly as written there. Every other 'provider@' on a catalog " + "model is removed so claudish routing picks the provider from the user's setup; " + "pass bare names unless the user asked for a provider."
|
|
90263
|
+
},
|
|
89886
90264
|
input_file: {
|
|
89887
90265
|
type: "string",
|
|
89888
90266
|
description: "PREFERRED. Path to a file holding the task prompt, relative to the working " + "directory. Use this rather than `input` for anything longer than a sentence: " + "a prompt passed inline is echoed verbatim in the caller's terminal, where a " + "200-line review brief buries every other argument and makes the call " + "unreadable. Write the brief to the session directory first (input.md is the " + "conventional name) and point here."
|
|
@@ -89923,8 +90301,20 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
89923
90301
|
const path = args.path;
|
|
89924
90302
|
if (typeof path !== "string" || !path)
|
|
89925
90303
|
throw new Error(`'path' is required for '${mode}'`);
|
|
89926
|
-
const
|
|
89927
|
-
const
|
|
90304
|
+
const givenModels = args.models;
|
|
90305
|
+
const givenJudges = args.judges;
|
|
90306
|
+
const requiredProviders = userRequiredProvidersArg(args.user_required_provider, [
|
|
90307
|
+
...givenModels ?? [],
|
|
90308
|
+
...givenJudges ?? []
|
|
90309
|
+
]);
|
|
90310
|
+
const modelStrip = givenModels ? strippedProviders(givenModels, requiredProviders) : undefined;
|
|
90311
|
+
const judgeStrip = givenJudges ? strippedProviders(givenJudges, requiredProviders) : undefined;
|
|
90312
|
+
const models = modelStrip?.specs;
|
|
90313
|
+
const judges = judgeStrip?.specs;
|
|
90314
|
+
const providerNote = strippedNote([
|
|
90315
|
+
...modelStrip?.stripped ?? [],
|
|
90316
|
+
...judgeStrip?.stripped ?? []
|
|
90317
|
+
]);
|
|
89928
90318
|
const inlineInput = args.input;
|
|
89929
90319
|
const inputFile = args.input_file;
|
|
89930
90320
|
if (inlineInput !== undefined && inputFile !== undefined) {
|
|
@@ -89935,10 +90325,16 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
89935
90325
|
const minOutputBytes = args.min_output_bytes;
|
|
89936
90326
|
const childFlags = buildChildClaudeFlags(args.agent, args.claude_flags) ?? [];
|
|
89937
90327
|
const resolved = validateSessionPath(path);
|
|
90328
|
+
const givenEfforts = givenModels ? modelEffortsArg(args.efforts, givenModels) : undefined;
|
|
90329
|
+
const efforts = givenEfforts ? Object.fromEntries(Object.entries(givenEfforts).map(([m, level]) => [
|
|
90330
|
+
models?.[givenModels?.indexOf(m) ?? -1] ?? m,
|
|
90331
|
+
level
|
|
90332
|
+
])) : undefined;
|
|
89938
90333
|
const runOpts = {
|
|
89939
90334
|
requirePattern,
|
|
89940
90335
|
minOutputBytes,
|
|
89941
90336
|
claudeFlags: childFlags,
|
|
90337
|
+
efforts,
|
|
89942
90338
|
onProgress: (u) => {
|
|
89943
90339
|
ctx.reportProgress(`team: ${u.phase}`);
|
|
89944
90340
|
}
|
|
@@ -89947,8 +90343,14 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
89947
90343
|
if (input !== undefined)
|
|
89948
90344
|
return input;
|
|
89949
90345
|
const existing = join56(resolved, "input.md");
|
|
89950
|
-
return existsSync37(existing) ?
|
|
90346
|
+
return existsSync37(existing) ? readFileSync37(existing, "utf-8") : undefined;
|
|
89951
90347
|
};
|
|
90348
|
+
if ((mode === "run" || mode === "run-and-judge") && givenModels && args.efforts === undefined) {
|
|
90349
|
+
const recommended = effortClarification(givenModels);
|
|
90350
|
+
if (recommended) {
|
|
90351
|
+
return needsEffortResult(recommended, `with efforts: {"<model>": "<level>"} (efforts: {} keeps Claude Code's own for every model)`);
|
|
90352
|
+
}
|
|
90353
|
+
}
|
|
89952
90354
|
switch (mode) {
|
|
89953
90355
|
case "run": {
|
|
89954
90356
|
if (!models?.length)
|
|
@@ -90008,6 +90410,7 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
90008
90410
|
cancel: `team(mode:"cancel", path:"${p}", slot:"<id>")`,
|
|
90009
90411
|
judge: `team(mode:"judge", path:"${p}") once every slot has finished`
|
|
90010
90412
|
},
|
|
90413
|
+
...providerNote ? { provider_note: providerNote } : {},
|
|
90011
90414
|
note: "Every slot has taken its prompt or failed to. Nothing terminates a " + "working slot on a timer: `status` reports each slot's state, " + "activity and seconds of silence; a slot inside a long build is " + "quiet and working. You decide whether to cancel."
|
|
90012
90415
|
}, null, 2)
|
|
90013
90416
|
}
|
|
@@ -90016,7 +90419,8 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
90016
90419
|
}
|
|
90017
90420
|
case "judge": {
|
|
90018
90421
|
const verdict = await judgeResponses(resolved, { judges, claudeFlags: childFlags });
|
|
90019
|
-
|
|
90422
|
+
const out = providerNote ? { ...verdict, provider_note: providerNote } : verdict;
|
|
90423
|
+
return { content: [{ type: "text", text: JSON.stringify(out, null, 2) }] };
|
|
90020
90424
|
}
|
|
90021
90425
|
case "run-and-judge": {
|
|
90022
90426
|
if (!models?.length)
|
|
@@ -90037,7 +90441,12 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
90037
90441
|
content: [
|
|
90038
90442
|
{
|
|
90039
90443
|
type: "text",
|
|
90040
|
-
text: JSON.stringify({
|
|
90444
|
+
text: JSON.stringify({
|
|
90445
|
+
...verdict,
|
|
90446
|
+
run_id: handle.runId,
|
|
90447
|
+
run,
|
|
90448
|
+
...providerNote ? { provider_note: providerNote } : {}
|
|
90449
|
+
}, null, 2)
|
|
90041
90450
|
}
|
|
90042
90451
|
]
|
|
90043
90452
|
};
|
|
@@ -90097,7 +90506,7 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
90097
90506
|
let stderrFull = stderr_snippet || "";
|
|
90098
90507
|
if (error_log_path) {
|
|
90099
90508
|
try {
|
|
90100
|
-
stderrFull =
|
|
90509
|
+
stderrFull = readFileSync37(error_log_path, "utf-8");
|
|
90101
90510
|
} catch {}
|
|
90102
90511
|
}
|
|
90103
90512
|
const sessionData = {};
|
|
@@ -90105,7 +90514,7 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
90105
90514
|
const sp = session_path;
|
|
90106
90515
|
for (const file of ["status.json", "manifest.json", "input.md"]) {
|
|
90107
90516
|
try {
|
|
90108
|
-
sessionData[file] =
|
|
90517
|
+
sessionData[file] = readFileSync37(join56(sp, file), "utf-8");
|
|
90109
90518
|
} catch {}
|
|
90110
90519
|
}
|
|
90111
90520
|
try {
|
|
@@ -90114,7 +90523,7 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
90114
90523
|
for (const f of readdirSync9(errorDir)) {
|
|
90115
90524
|
if (f.endsWith(".log")) {
|
|
90116
90525
|
try {
|
|
90117
|
-
sessionData[`errors/${f}`] =
|
|
90526
|
+
sessionData[`errors/${f}`] = readFileSync37(join56(errorDir, f), "utf-8");
|
|
90118
90527
|
} catch {}
|
|
90119
90528
|
}
|
|
90120
90529
|
}
|
|
@@ -90124,7 +90533,7 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
90124
90533
|
for (const f of readdirSync9(sp)) {
|
|
90125
90534
|
if (f.startsWith("response-") && f.endsWith(".md")) {
|
|
90126
90535
|
try {
|
|
90127
|
-
const content =
|
|
90536
|
+
const content = readFileSync37(join56(sp, f), "utf-8");
|
|
90128
90537
|
sessionData[f] = content.slice(0, 200) + (content.length > 200 ? "... (truncated)" : "");
|
|
90129
90538
|
} catch {}
|
|
90130
90539
|
}
|
|
@@ -90135,7 +90544,7 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
90135
90544
|
try {
|
|
90136
90545
|
const pkgPath = join56(__dirname3, "../package.json");
|
|
90137
90546
|
if (existsSync37(pkgPath)) {
|
|
90138
|
-
version = JSON.parse(
|
|
90547
|
+
version = JSON.parse(readFileSync37(pkgPath, "utf-8")).version;
|
|
90139
90548
|
}
|
|
90140
90549
|
} catch {}
|
|
90141
90550
|
const report = {
|
|
@@ -90219,7 +90628,11 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
90219
90628
|
properties: {
|
|
90220
90629
|
model: {
|
|
90221
90630
|
type: "string",
|
|
90222
|
-
description: "Model
|
|
90631
|
+
description: "Model name. Pass the bare name (e.g. 'gpt-6.1-sol'): claudish routing picks the " + "provider from the user's setup. A 'provider@' on a catalog model is removed " + "unless 'user_required_provider' is true."
|
|
90632
|
+
},
|
|
90633
|
+
user_required_provider: {
|
|
90634
|
+
type: "boolean",
|
|
90635
|
+
description: "True only when the USER named the provider: the 'provider@model' spec is then " + "used as given."
|
|
90223
90636
|
},
|
|
90224
90637
|
prompt: {
|
|
90225
90638
|
type: "string",
|
|
@@ -90239,6 +90652,11 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
90239
90652
|
type: "string",
|
|
90240
90653
|
description: "Any other Claude Code / claudish flags and their values, space-separated \u2014 no " + "positional text. Unrecognised flags pass through to the child Claude Code. " + "Flags the pane owns or that only work in print mode are refused. NOTE: split on " + "whitespace, so a flag VALUE containing spaces cannot be expressed here."
|
|
90241
90654
|
},
|
|
90655
|
+
effort: {
|
|
90656
|
+
type: "string",
|
|
90657
|
+
enum: [...EFFORT_LEVELS, KEEP_EFFORT],
|
|
90658
|
+
description: "Reasoning effort for the whole session. Take it from list_models' " + "'Recommended effort by task type' table: your task's column, this model's row. " + "Pinned on every request (claudish --effort-override), over one in claude_flags. " + "Omitted for a model that has a row, nothing starts and the answer is " + `'needs_effort' with that row; "${KEEP_EFFORT}" keeps Claude Code's own level.`
|
|
90659
|
+
},
|
|
90242
90660
|
work_dir: {
|
|
90243
90661
|
type: "string",
|
|
90244
90662
|
description: "Working directory for the session (default: current directory)"
|
|
@@ -90254,11 +90672,19 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
90254
90672
|
handler: async (args) => {
|
|
90255
90673
|
try {
|
|
90256
90674
|
const claudishFlags = buildChildClaudeFlags(args.agent, args.claude_flags) ?? [];
|
|
90675
|
+
const effort = effortArg(args.effort);
|
|
90676
|
+
if (effort)
|
|
90677
|
+
claudishFlags.push("--effort-override", effort);
|
|
90257
90678
|
const flagCheck = checkChildFlags(claudishFlags);
|
|
90258
90679
|
if (!flagCheck.ok)
|
|
90259
90680
|
throw new Error(`invalid_args: ${flagCheck.message}`);
|
|
90260
90681
|
await assertMagmuxAvailable();
|
|
90261
|
-
const
|
|
90682
|
+
const { specs, stripped } = strippedProviders([args.model], new Set(args.user_required_provider === true ? [args.model] : []));
|
|
90683
|
+
const requestedModel = specs[0];
|
|
90684
|
+
const recommended = args.effort === undefined ? effortClarification([args.model]) : undefined;
|
|
90685
|
+
if (recommended) {
|
|
90686
|
+
return needsEffortResult(recommended, `with effort: "<level>" (effort: "${KEEP_EFFORT}" keeps Claude Code's own)`);
|
|
90687
|
+
}
|
|
90262
90688
|
const workDir = args.work_dir;
|
|
90263
90689
|
const plan = await prehydrateCredentialsForSpawn([requestedModel], {
|
|
90264
90690
|
pin: workDir === undefined || resolve8(workDir) === process.cwd()
|
|
@@ -90282,7 +90708,8 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
90282
90708
|
type: "text",
|
|
90283
90709
|
text: JSON.stringify({
|
|
90284
90710
|
session_id: sessionId,
|
|
90285
|
-
state: sessionManager.getSession(sessionId).state
|
|
90711
|
+
state: sessionManager.getSession(sessionId).state,
|
|
90712
|
+
...stripped.length > 0 ? { model: requestedModel, note: strippedNote(stripped) } : {}
|
|
90286
90713
|
})
|
|
90287
90714
|
}
|
|
90288
90715
|
]
|
|
@@ -90540,8 +90967,8 @@ function mcpDebugLogEnabled(argv, env) {
|
|
|
90540
90967
|
}
|
|
90541
90968
|
async function main() {
|
|
90542
90969
|
const iso = isolateProtocolStdout();
|
|
90543
|
-
|
|
90544
|
-
|
|
90970
|
+
const argv = process.argv.slice(2);
|
|
90971
|
+
initLogger(mcpDebugLogEnabled(argv, process.env), "debug", argv.includes("--log-off"), "claudish-mcp", 500);
|
|
90545
90972
|
if (!iso.active)
|
|
90546
90973
|
log(`[mcp] protocol stdout not isolated: ${iso.reason ?? "unknown"}`);
|
|
90547
90974
|
loadHooksOnce({ hostMode: "mcp" });
|
|
@@ -90608,9 +91035,7 @@ async function main() {
|
|
|
90608
91035
|
await server.connect(transport);
|
|
90609
91036
|
installMcpShutdown(sessionManager);
|
|
90610
91037
|
if (!nested)
|
|
90611
|
-
ensureSwept(sockRootFor()).catch(() => {
|
|
90612
|
-
return;
|
|
90613
|
-
});
|
|
91038
|
+
ensureSwept(sockRootFor()).catch((err) => log(`[mcp] stale pane sweep failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
90614
91039
|
}
|
|
90615
91040
|
function installMcpShutdown(sessionManager) {
|
|
90616
91041
|
const before = async () => {
|
|
@@ -90650,14 +91075,16 @@ Each session is an interactive Claude Code running the model in its own headless
|
|
|
90650
91075
|
5. FAILED or TIMEOUT \u2014 or COMPLETED with an empty or surprising answer \u2014 call get_diagnostics. It returns the child's final screen, the upstream error bodies, the recent state records, the resolved model chain and the paths to the full records. It needs no re-run and no debug flag.
|
|
90651
91076
|
6. capture_session reads a session's current screen; resize_session sets its terminal size (any time, mid-turn included); cancel_session stops it. Nothing stops a session for being idle: a child inside a long build is silent and working.
|
|
90652
91077
|
|
|
90653
|
-
The session_id from create_session is the key for every session tool.`, proxyInstance = null, proxyStarting = null, SCORE_TIE_EPSILON = 0.000001, NEXT_STEP, sanitize2, TOOL_MODES;
|
|
91078
|
+
The session_id from create_session is the key for every session tool.`, proxyInstance = null, proxyStarting = null, SCORE_TIE_EPSILON = 0.000001, NEXT_STEP, KEEP_EFFORT = "default", sanitize2, TOOL_MODES;
|
|
90654
91079
|
var init_mcp_server = __esm(() => {
|
|
90655
91080
|
init_server2();
|
|
90656
91081
|
init_stdio2();
|
|
90657
91082
|
init_types2();
|
|
91083
|
+
init_base_api_format();
|
|
90658
91084
|
init_model_catalog();
|
|
90659
91085
|
init_prehydrate();
|
|
90660
91086
|
init_prompt_role();
|
|
91087
|
+
init_fs_atomic();
|
|
90661
91088
|
init_hooks();
|
|
90662
91089
|
init_output_capture();
|
|
90663
91090
|
init_logger();
|
|
@@ -90671,11 +91098,15 @@ var init_mcp_server = __esm(() => {
|
|
|
90671
91098
|
init_child_env();
|
|
90672
91099
|
init_pane();
|
|
90673
91100
|
init_port_manager();
|
|
91101
|
+
init_all_models_cache();
|
|
91102
|
+
init_effort_recommendations();
|
|
90674
91103
|
init_endpoint_registration();
|
|
91104
|
+
init_model_parser();
|
|
90675
91105
|
init_native_route();
|
|
90676
91106
|
init_onepassword();
|
|
90677
91107
|
init_preflight_chain();
|
|
90678
91108
|
init_probe_live();
|
|
91109
|
+
init_provider_definitions();
|
|
90679
91110
|
init_proxy_server();
|
|
90680
91111
|
init_recommended_listing();
|
|
90681
91112
|
init_redact();
|
|
@@ -90707,7 +91138,7 @@ var init_mcp_server = __esm(() => {
|
|
|
90707
91138
|
});
|
|
90708
91139
|
|
|
90709
91140
|
// src/serve-command.ts
|
|
90710
|
-
import { existsSync as existsSync38, readFileSync as
|
|
91141
|
+
import { existsSync as existsSync38, readFileSync as readFileSync38 } from "fs";
|
|
90711
91142
|
function parseServeArgs(args) {
|
|
90712
91143
|
const out = {};
|
|
90713
91144
|
for (let i = 0;i < args.length; i++) {
|
|
@@ -90731,7 +91162,7 @@ function loadModelMap(path) {
|
|
|
90731
91162
|
}
|
|
90732
91163
|
let raw;
|
|
90733
91164
|
try {
|
|
90734
|
-
raw =
|
|
91165
|
+
raw = readFileSync38(path, "utf-8");
|
|
90735
91166
|
} catch (e) {
|
|
90736
91167
|
throw new Error(`failed to read --models file ${path}: ${e instanceof Error ? e.message : String(e)}`);
|
|
90737
91168
|
}
|
|
@@ -90812,7 +91243,7 @@ var init_serve_command = __esm(() => {
|
|
|
90812
91243
|
var HOOKS_AMBIENT_DTS = '// claudish hook types \u2014 written by `claudish hooks init`. Do not edit: run\n// `claudish hooks init` from a newer claudish to refresh it.\n// With this file beside your hook, `import type { HookDefinition } from\n// "claudish/hooks"` type-checks with nothing installed.\ndeclare module "claudish/hooks" {\n /**\n * claudish/hooks \u2014 the public hook contract.\n *\n * Everything a hook author can import lives here, and nothing else does. This\n * file imports nothing from the rest of claudish and has no side effects, so it\n * can be built on its own into `dist/hooks.js` + `dist/hooks.d.ts` and served to\n * user modules as the `claudish/hooks` virtual module (see `loader.ts`).\n *\n * Every internal hooks module takes its types from here, so the contract has a\n * single source.\n *\n * ## Process isolation\n *\n * A hook module\'s top-level state is PER PROCESS. In the interactive launcher,\n * proxy events (`request` \u2026 `responseEnd`, raw) and session events\n * (`sessionStart` \u2026 `sessionEnd`) run in one process. In `create_session` and\n * team children they do not: proxy events run in the pane child, and session\n * events run in the MCP server or the CLI process that drives the pane. Pass\n * per-turn data from a proxy event to `sessionIdle` with `annotateTurn`, never\n * with module variables.\n *\n * ## Execution: a hook chain\n *\n * The hooks of one event run one after another, in effective order. Each hook\'s\n * actions are applied before the next hook is called, so `ctx.request`,\n * `ctx.tool.args` and `ctx.response` show what the earlier hooks did, and\n * `ctx.prior` lists it. A warn-severity or failing hook changes nothing for the\n * next one. Each event has a budget for all its hooks together; a hook\'s timeout\n * is cut to what is left of it.\n *\n * ## Output\n *\n * Log with `ctx.log`. `console.*` and `process.stdout`/`stderr` writes made by a\n * hook are routed to claudish\'s debug log, never to the terminal or the MCP\n * protocol stream.\n */\n export const HOOK_API_VERSION = 1;\n export type Severity = "off" | "warn" | "fix";\n export type HookOrder = "pre" | "normal" | "post";\n /** native = RouteInfo.native true; foreign = RouteInfo.native false; all = both */\n export type RouteScope = "foreign" | "native" | "all";\n export type HostMode = "interactive" | "pane-child" | "serve" | "mcp" | "other";\n export type JsonValue = string | number | boolean | null | ReadonlyArray<JsonValue> | {\n readonly [k: string]: JsonValue;\n };\n export interface HarnessFacts {\n readonly planModeActive: boolean;\n readonly planFilePath?: string;\n readonly planDir?: string;\n /** Claude Code session id from request metadata */\n readonly sessionId?: string;\n /** empty = no listing found, not "no skills" */\n readonly skills?: ReadonlyArray<{\n name: string;\n description: string;\n }>;\n }\n export interface RouteInfo {\n /** bare model name the handler serves, e.g. "glm-5" */\n readonly modelId: string;\n /** claudish provider name, e.g. "openrouter"; "anthropic" for native */\n readonly provider: string;\n /**\n * true when the request is served by the native Anthropic handler, OR when\n * !forceForeignModel && (/^claude[-.]/i.test(modelId) || provider === "anthropic")\n * where forceForeignModel is the provider profile\'s opt-in override. This is the exact\n * rule the plan-mode built-in has always used (a claude-* uid on an aggregator that sets\n * forceForeignModel is foreign).\n */\n readonly native: boolean;\n }\n export interface ClaudeTool {\n name: string;\n description?: string;\n input_schema?: unknown;\n }\n /** A Claude-format content block. Only `text` blocks are editable by closed actions. */\n export type ClaudeContentBlock = {\n type: "text";\n text: string;\n } | {\n type: "tool_use";\n id: string;\n name: string;\n input: unknown;\n } | {\n type: "tool_result";\n tool_use_id: string;\n content?: unknown;\n is_error?: boolean;\n } | {\n type: "thinking";\n thinking: string;\n signature?: string;\n } | {\n type: string;\n [k: string]: unknown;\n };\n export interface ClaudeMessage {\n role: "user" | "assistant";\n content: string | ReadonlyArray<ClaudeContentBlock>;\n }\n /**\n * In `request`, the request as the earlier steps of the hook chain left it. On\n * the response side and in `claims()`, the request chain\'s final view.\n */\n export interface RequestFacts {\n /** as Claude Code asked for it; frozen */\n readonly model: string;\n /** frozen */\n readonly stream: boolean;\n /** system prompt flattened to text, after earlier steps */\n readonly systemText: string;\n /** read-only view after earlier steps; change it through actions */\n readonly messages: ReadonlyArray<ClaudeMessage>;\n /**\n * read-only view after earlier steps; `description` includes earlier description actions as\n * stage B will apply them to the Claude-format tool (the provider copy may be summarised)\n */\n readonly tools: ReadonlyArray<ClaudeTool>;\n }\n /** Which session a proxy event belongs to, when claudish knows. */\n export interface ProxySessionRef {\n readonly kind: SessionKind;\n readonly id: string;\n readonly role: "slot" | "judge" | null;\n }\n /** One action an earlier step of this hook chain applied or handed on. */\n export interface PriorAction {\n readonly hookId: string;\n readonly action: HookAction;\n }\n interface BaseContext {\n readonly hookId: string;\n /** "warn" or "fix" (an "off" hook is never called) */\n readonly severity: Severity;\n /** writes to claudish\'s debug log; never to the terminal */\n log(message: string): void;\n /**\n * this step\'s own signal: aborted when its step timeout elapses (its own timeout, or the\n * event budget left, whichever is shorter) or when the dispatch is aborted. Never shared\n * with another hook\'s step.\n */\n readonly signal: AbortSignal;\n /**\n * actions earlier steps of this hook chain applied (or, for responseEnd/sessionStart/\n * sessionIdle, handed on), in order. Empty for the first step and in claims()/the toolCall\n * predicate. Never lists warn actions or anything a warn-severity hook returned.\n */\n readonly prior: ReadonlyArray<PriorAction>;\n }\n export interface ProxyContext extends BaseContext {\n readonly host: {\n mode: HostMode;\n };\n readonly route: RouteInfo;\n readonly request: RequestFacts;\n readonly harness: HarnessFacts;\n readonly session: ProxySessionRef | null;\n }\n export interface RequestContext extends ProxyContext {\n readonly event: "request";\n }\n export interface ToolCallContext extends ProxyContext {\n readonly event: "toolCall";\n readonly tool: {\n id: string;\n name: string;\n /** the arguments after every repair earlier hooks in the chain applied */\n args: Readonly<Record<string, unknown>>;\n /** the argument JSON exactly as the model produced it; never rewritten */\n rawArgs: string;\n };\n }\n export type ResponseBlock = {\n type: "text";\n text: string;\n } | {\n type: "thinking";\n thinking: string;\n } | {\n type: "tool_use";\n id: string;\n name: string;\n input: unknown;\n } | {\n type: "other";\n blockType: string;\n };\n export interface ResponseView {\n blocks: ReadonlyArray<ResponseBlock>;\n /** every text block, joined with "\\n\\n" */\n text: string;\n /** every thinking block, joined with "\\n\\n" */\n reasoning: string;\n toolNames: ReadonlyArray<string>;\n /** "tool_use" = an intermediate step of a tool loop; the turn continues after the tool runs */\n stopReason: string | null;\n }\n /** response = the held response after every text action earlier hooks in the chain applied */\n export interface ResponseRewriteContext extends ProxyContext {\n readonly event: "responseRewrite";\n readonly response: ResponseView;\n }\n /** response = the final bytes the client received: after any rewrite AND any raw `response` replacement */\n export interface ResponseEndContext extends ProxyContext {\n readonly event: "responseEnd";\n readonly response: ResponseView;\n }\n export type SessionKind = "interactive" | "channel" | "team";\n export interface SessionInfo {\n kind: SessionKind;\n /** team only; null otherwise */\n role: "slot" | "judge" | null;\n /** channel: the 8-hex session_id \xB7 team: "<run_id>:<slot id>" \xB7 interactive: the Claude Code session id */\n id: string;\n claudeSessionId: string | null;\n /** as the caller asked for it */\n model: string;\n cwd: string;\n /** a one-shot session stays "one-shot" through a hook-extended turn chain */\n shape: "interactive" | "one-shot";\n injection: "available" | "unavailable";\n }\n export interface SessionStartContext extends BaseContext {\n readonly event: "sessionStart";\n readonly session: SessionInfo;\n }\n export interface TurnAnnotation {\n hookId: string;\n key: string;\n value: JsonValue;\n }\n export interface SessionIdleContext extends BaseContext {\n readonly event: "sessionIdle";\n readonly session: SessionInfo;\n readonly turn: {\n /** 1-based within the session; a re-woken turn keeps its index */\n index: number;\n /** this turn\'s assistant text */\n answer: string;\n stopReason: string | null;\n apiError: boolean;\n /** this turn was started by an injection */\n hookCaused: boolean;\n /** annotateTurn actions from this turn\'s responses, in arrival order */\n annotations: ReadonlyArray<TurnAnnotation>;\n };\n readonly consecutiveHookTurns: number;\n /** caller/human input is queued; an injection returned now will be dropped as stale */\n readonly callerInputPending: boolean;\n }\n export interface SessionBlockedContext extends BaseContext {\n readonly event: "sessionBlocked";\n readonly session: SessionInfo;\n readonly block: {\n kind: "question" | "permission";\n text: string;\n };\n }\n export interface SessionEndContext extends BaseContext {\n readonly event: "sessionEnd";\n readonly session: SessionInfo;\n readonly outcome: {\n state: string;\n reason: string | null;\n exitCode: number | null;\n };\n }\n type TextMatch = {\n find: string;\n regex?: boolean;\n flags?: string;\n };\n /** default ["user"] */\n type MessageRoles = {\n roles?: ReadonlyArray<"user" | "assistant">;\n };\n export type InjectSystemNote = {\n type: "injectSystemNote";\n text: string;\n };\n export type AppendUserText = {\n type: "appendUserText";\n text: string;\n };\n export type ReplaceMessageText = {\n type: "replaceMessageText";\n replace: string;\n } & TextMatch & MessageRoles;\n export type RemoveMessageText = {\n type: "removeMessageText";\n } & TextMatch & MessageRoles;\n export type RewriteToolDescription = {\n type: "rewriteToolDescription";\n tool: string;\n append: string;\n };\n export type ReplaceToolDescription = {\n type: "replaceToolDescription";\n tool: string;\n description: string;\n };\n export type ReplaceToolSchema = {\n type: "replaceToolSchema";\n tool: string;\n inputSchema: {\n type: "object";\n [k: string]: unknown;\n };\n };\n export type RemoveTool = {\n type: "removeTool";\n tool: string;\n };\n export type RepairToolArgs = {\n type: "repairToolArgs";\n args: Record<string, unknown>;\n reason: string;\n };\n export type AppendText = {\n type: "appendText";\n text: string;\n };\n export type PrependText = {\n type: "prependText";\n text: string;\n };\n export type ReplaceText = {\n type: "replaceText";\n replace: string;\n } & TextMatch;\n export type RemoveText = {\n type: "removeText";\n } & TextMatch;\n export type InjectUserTurn = {\n type: "injectUserTurn";\n text: string;\n };\n export type AnnotateTurn = {\n type: "annotateTurn";\n key: string;\n value: JsonValue;\n };\n export type Warn = {\n type: "warn";\n message: string;\n };\n export type RequestAction = InjectSystemNote | AppendUserText | ReplaceMessageText | RemoveMessageText | RewriteToolDescription | ReplaceToolDescription | ReplaceToolSchema | RemoveTool | Warn;\n export type ToolCallAction = RepairToolArgs | Warn;\n export type RewriteAction = AppendText | PrependText | ReplaceText | RemoveText | Warn;\n export type ResponseEndAction = InjectSystemNote | InjectUserTurn | AnnotateTurn | Warn;\n export type SessionAction = InjectUserTurn | Warn;\n export type ObserveAction = Warn;\n export type HookAction = RequestAction | ToolCallAction | RewriteAction | ResponseEndAction | SessionAction;\n export type HookResult<A> = A[] | void | Promise<A[] | void>;\n export interface HookHandlers {\n request?(ctx: RequestContext): HookResult<RequestAction>;\n toolCall?: {\n /** tool names whose completed arguments this hook sees; "*" = every tool (costs streaming of all tool input) */\n tools: ReadonlyArray<string>;\n /** synchronous, per request; default true. false = not armed for this request */\n armed?(ctx: RequestContext): boolean;\n /** true = see the call after it was forwarded; can only warn; never holds the stream */\n observe?: boolean;\n handle(ctx: ToolCallContext): HookResult<ToolCallAction>;\n };\n responseRewrite?: {\n /** synchronous, per request, evaluated before the response starts; default true */\n claims?(ctx: RequestContext): boolean;\n handle(ctx: ResponseRewriteContext): HookResult<RewriteAction>;\n };\n responseEnd?(ctx: ResponseEndContext): HookResult<ResponseEndAction>;\n sessionStart?(ctx: SessionStartContext): HookResult<SessionAction>;\n sessionIdle?(ctx: SessionIdleContext): HookResult<SessionAction>;\n sessionBlocked?(ctx: SessionBlockedContext): HookResult<ObserveAction>;\n sessionEnd?(ctx: SessionEndContext): HookResult<ObserveAction>;\n }\n export interface RawProviderRequestContext {\n readonly hookId: string;\n readonly route: RouteInfo;\n claudeRequest: any;\n messages: any[];\n tools: any[];\n }\n export interface RawProviderChunkContext {\n readonly hookId: string;\n readonly route: RouteInfo;\n /** A clone of the parsed provider event. Whatever this field holds when the call returns is\n * what the parser reads from then on, so it may be edited in place or replaced. */\n chunk: any;\n /** The delta object inside `chunk` at call time (Responses wire: `chunk` itself). Edit it in\n * place; assigning a new object to this field has no effect. */\n delta: any;\n /** per-stream, shared across this hook\'s chunk calls; never cloned */\n metadata: Map<string, unknown>;\n }\n export interface RawProviderStreamEndContext {\n readonly hookId: string;\n readonly route: RouteInfo;\n metadata: Map<string, unknown>;\n }\n export interface RawResponseContext {\n readonly hookId: string;\n readonly route: RouteInfo;\n readonly request: RequestFacts;\n /** A replay of the current Claude-format response (SSE, or JSON for stream:false), read at the\n * hook\'s own pace. claudish drains the original itself, so leaving this unread delays nothing. */\n response: Response;\n }\n export interface RawMiddleware {\n /**\n * Receives clones. They replace the live request only when this call returns (or its promise\n * resolves) within its timeout. A throw, a rejection or a timeout discards every change.\n */\n providerRequest?(ctx: RawProviderRequestContext): void | Promise<void>;\n /**\n * MUST be synchronous. Called on the parser\'s loop, on a clone of the chunk. On a normal return\n * of anything but a thenable, the clone (whatever `ctx.chunk` holds then) is committed: it\n * becomes the object the parser reads, deletions included. On a throw nothing is committed.\n * A declared `async` function is rejected at load. Any other thenable return is an invalid\n * invocation: the clone is discarded even if the hook mutated it before returning, the call is\n * journaled `invalid` (`async_return`) and counts toward the circuit breaker, and a rejection\n * handler is attached, so a rejection is journaled `error` and never becomes an\n * unhandledRejection.\n */\n providerChunk?(ctx: RawProviderChunkContext): void;\n providerStreamEnd?(ctx: RawProviderStreamEndContext): void | Promise<void>;\n /**\n * Return a replacement Response, or nothing to keep the current one. A replacement is read\n * whole and forwarded only when it completes cleanly; on any failure the original is forwarded.\n * The client never sees a partial replacement. A replacement must close within this hook\'s\n * timeout after the later of this call\'s return and the end of the original; the original\'s end\n * never depends on whether `ctx.response` is read.\n */\n response?(ctx: RawResponseContext): Response | void | Promise<Response | void>;\n }\n interface HookBase {\n apiVersion: 1;\n id: string;\n description?: string;\n /** default "fix" for user hooks */\n defaultSeverity?: Severity;\n /** default "normal" */\n order?: HookOrder;\n /** globs on RouteInfo.modelId; default "*"; proxy events only */\n models?: string | ReadonlyArray<string>;\n /** default "all"; proxy events only */\n routes?: RouteScope;\n /** per call; clamped to the event\'s maximum and to the event budget left when the hook\'s turn comes */\n timeoutMs?: number;\n on?: HookHandlers;\n }\n export interface SafeHook extends HookBase {\n unsafe?: never;\n raw?: never;\n }\n export interface UnsafeHook extends HookBase {\n unsafe: true;\n raw: RawMiddleware;\n }\n /**\n * One hook. Module-level state is per process: in `create_session` and team\n * children, proxy events run in the pane child and session events in the MCP\n * server or CLI process. Pass per-turn data from proxy events to `sessionIdle`\n * with `annotateTurn`, never with module variables.\n */\n export type HookDefinition = SafeHook | UnsafeHook;\n /** Identity function: gives editor type-checking and inference. */\n export function defineHook<const H extends HookDefinition>(hook: H): H;\n /** Action constructors (plain data; equivalent to writing the object literal). */\n export const act: {\n injectSystemNote(text: string): InjectSystemNote;\n appendUserText(text: string): AppendUserText;\n replaceMessageText(find: string, replace: string, opts?: {\n regex?: boolean;\n flags?: string;\n roles?: ReadonlyArray<"user" | "assistant">;\n }): ReplaceMessageText;\n removeMessageText(find: string, opts?: {\n regex?: boolean;\n flags?: string;\n roles?: ReadonlyArray<"user" | "assistant">;\n }): RemoveMessageText;\n rewriteToolDescription(tool: string, append: string): RewriteToolDescription;\n replaceToolDescription(tool: string, description: string): ReplaceToolDescription;\n replaceToolSchema(tool: string, inputSchema: {\n type: "object";\n [k: string]: unknown;\n }): ReplaceToolSchema;\n removeTool(tool: string): RemoveTool;\n repairToolArgs(args: Record<string, unknown>, reason: string): RepairToolArgs;\n appendText(text: string): AppendText;\n prependText(text: string): PrependText;\n replaceText(find: string, replace: string, opts?: {\n regex?: boolean;\n flags?: string;\n }): ReplaceText;\n removeText(find: string, opts?: {\n regex?: boolean;\n flags?: string;\n }): RemoveText;\n injectUserTurn(text: string): InjectUserTurn;\n annotateTurn(key: string, value: JsonValue): AnnotateTurn;\n warn(message: string): Warn;\n };\n}\n';
|
|
90813
91244
|
|
|
90814
91245
|
// src/hooks/observer/corpus.ts
|
|
90815
|
-
import { appendFileSync as appendFileSync8, readFileSync as
|
|
91246
|
+
import { appendFileSync as appendFileSync8, readFileSync as readFileSync39, readdirSync as readdirSync10, statSync as statSync17 } from "fs";
|
|
90816
91247
|
import { homedir as homedir38 } from "os";
|
|
90817
91248
|
import { join as join57 } from "path";
|
|
90818
91249
|
function directoryOf2(filePath) {
|
|
@@ -90836,7 +91267,7 @@ function writeTargetsOf(row) {
|
|
|
90836
91267
|
function replayTranscript(file) {
|
|
90837
91268
|
let text;
|
|
90838
91269
|
try {
|
|
90839
|
-
text =
|
|
91270
|
+
text = readFileSync39(file, "utf8");
|
|
90840
91271
|
} catch {
|
|
90841
91272
|
return [];
|
|
90842
91273
|
}
|
|
@@ -90895,7 +91326,7 @@ function listTranscripts(root) {
|
|
|
90895
91326
|
for (const project of projects) {
|
|
90896
91327
|
const dir = join57(root, project);
|
|
90897
91328
|
try {
|
|
90898
|
-
if (!
|
|
91329
|
+
if (!statSync17(dir).isDirectory())
|
|
90899
91330
|
continue;
|
|
90900
91331
|
for (const f of readdirSync10(dir)) {
|
|
90901
91332
|
if (f.endsWith(".jsonl"))
|
|
@@ -90928,7 +91359,7 @@ var init_corpus = __esm(() => {
|
|
|
90928
91359
|
});
|
|
90929
91360
|
|
|
90930
91361
|
// src/hooks-command.ts
|
|
90931
|
-
import { existsSync as existsSync39, mkdirSync as
|
|
91362
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync25, readFileSync as readFileSync40, writeFileSync as writeFileSync24 } from "fs";
|
|
90932
91363
|
import { homedir as homedir39 } from "os";
|
|
90933
91364
|
import { join as join58, resolve as resolve9 } from "path";
|
|
90934
91365
|
function severityColor(sev) {
|
|
@@ -91064,9 +91495,9 @@ function init(dirArg) {
|
|
|
91064
91495
|
console.error(`${path} already exists; not overwriting it.`);
|
|
91065
91496
|
return 1;
|
|
91066
91497
|
}
|
|
91067
|
-
|
|
91498
|
+
mkdirSync25(dir, { recursive: true });
|
|
91068
91499
|
for (const [path, text] of files)
|
|
91069
|
-
|
|
91500
|
+
writeFileSync24(path, text, { flag: "wx" });
|
|
91070
91501
|
console.log(`
|
|
91071
91502
|
wrote ${files.map(([p]) => p).join(`
|
|
91072
91503
|
wrote `)}
|
|
@@ -91132,7 +91563,7 @@ function setTelemetryEnabled(value) {
|
|
|
91132
91563
|
let cfg = {};
|
|
91133
91564
|
try {
|
|
91134
91565
|
if (existsSync39(path)) {
|
|
91135
|
-
const parsed = JSON.parse(
|
|
91566
|
+
const parsed = JSON.parse(readFileSync40(path, "utf-8"));
|
|
91136
91567
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
91137
91568
|
cfg = parsed;
|
|
91138
91569
|
}
|
|
@@ -91141,7 +91572,7 @@ function setTelemetryEnabled(value) {
|
|
|
91141
91572
|
const hooks = cfg.hooks && typeof cfg.hooks === "object" && !Array.isArray(cfg.hooks) ? { ...cfg.hooks } : {};
|
|
91142
91573
|
hooks.telemetry = { enabled: value };
|
|
91143
91574
|
cfg.hooks = hooks;
|
|
91144
|
-
|
|
91575
|
+
writeFileSync24(path, `${JSON.stringify(cfg, null, 2)}
|
|
91145
91576
|
`, "utf-8");
|
|
91146
91577
|
}
|
|
91147
91578
|
function telemetry(action, json) {
|
|
@@ -91152,7 +91583,7 @@ function telemetry(action, json) {
|
|
|
91152
91583
|
try {
|
|
91153
91584
|
const path = outboxPath();
|
|
91154
91585
|
if (existsSync39(path))
|
|
91155
|
-
pending =
|
|
91586
|
+
pending = readFileSync40(path, "utf8").split(`
|
|
91156
91587
|
`).filter(Boolean).length;
|
|
91157
91588
|
} catch {}
|
|
91158
91589
|
if (json) {
|
|
@@ -91259,7 +91690,7 @@ var init_hooks_command = __esm(() => {
|
|
|
91259
91690
|
|
|
91260
91691
|
// src/team-grid.ts
|
|
91261
91692
|
import { spawn as spawn3 } from "child_process";
|
|
91262
|
-
import { existsSync as existsSync40, readFileSync as
|
|
91693
|
+
import { existsSync as existsSync40, readFileSync as readFileSync41, writeFileSync as writeFileSync25 } from "fs";
|
|
91263
91694
|
import { connect as netConnect2 } from "net";
|
|
91264
91695
|
import { join as join59 } from "path";
|
|
91265
91696
|
import { setTimeout as wait } from "timers/promises";
|
|
@@ -91412,8 +91843,8 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
91412
91843
|
const manifest = setupSession(sessionPath, models, input);
|
|
91413
91844
|
const startedAt = new Date().toISOString();
|
|
91414
91845
|
const gridfilePath = join59(sessionPath, "gridfile.txt");
|
|
91415
|
-
const prompt =
|
|
91416
|
-
const rawPrompt =
|
|
91846
|
+
const prompt = readFileSync41(join59(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''").replace(/\n/g, " ");
|
|
91847
|
+
const rawPrompt = readFileSync41(join59(sessionPath, "input.md"), "utf-8");
|
|
91417
91848
|
const usedBannerColors = new Set;
|
|
91418
91849
|
const routeLines = mode === "interactive" ? new Map : await resolvePaneRouteLines(Object.values(manifest.models).map((entry) => entry.model));
|
|
91419
91850
|
const gridLines = Object.entries(manifest.models).map(([anonId]) => {
|
|
@@ -91425,7 +91856,7 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
91425
91856
|
const header = buildPaneHeader(model, routeLines.get(model) ?? "", rawPrompt, bg);
|
|
91426
91857
|
return `${header} claudish --model ${model} -y --quiet '${prompt}'`;
|
|
91427
91858
|
});
|
|
91428
|
-
|
|
91859
|
+
writeFileSync25(gridfilePath, `${gridLines.join(`
|
|
91429
91860
|
`)}
|
|
91430
91861
|
`, "utf-8");
|
|
91431
91862
|
const magmuxPath = findMagmuxBinary();
|
|
@@ -91446,7 +91877,7 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
91446
91877
|
const [{ results }] = await Promise.all([subscription, procExit]);
|
|
91447
91878
|
const status = buildTeamStatus(manifest, startedAt, results?.panes ?? null);
|
|
91448
91879
|
const statusPath = join59(sessionPath, "status.json");
|
|
91449
|
-
|
|
91880
|
+
writeFileSync25(statusPath, JSON.stringify(status, null, 2), "utf-8");
|
|
91450
91881
|
return status;
|
|
91451
91882
|
}
|
|
91452
91883
|
var BANNER_BG_COLORS;
|
|
@@ -91465,7 +91896,7 @@ var init_team_grid = __esm(() => {
|
|
|
91465
91896
|
});
|
|
91466
91897
|
|
|
91467
91898
|
// src/team-cli.ts
|
|
91468
|
-
import { readFileSync as
|
|
91899
|
+
import { readFileSync as readFileSync42 } from "fs";
|
|
91469
91900
|
import { join as join60 } from "path";
|
|
91470
91901
|
async function runPaneTeam(sessionPath, models, input, opts) {
|
|
91471
91902
|
installPaneShutdownHooks({ exitAfter: true });
|
|
@@ -91611,7 +92042,7 @@ async function teamCommand(args) {
|
|
|
91611
92042
|
}
|
|
91612
92043
|
case "judge": {
|
|
91613
92044
|
await judgeResponses(sessionPath, { judges });
|
|
91614
|
-
console.log(
|
|
92045
|
+
console.log(readFileSync42(join60(sessionPath, "verdict.md"), "utf-8"));
|
|
91615
92046
|
break;
|
|
91616
92047
|
}
|
|
91617
92048
|
case "run-and-judge": {
|
|
@@ -91627,7 +92058,7 @@ async function teamCommand(args) {
|
|
|
91627
92058
|
});
|
|
91628
92059
|
printStatus(status);
|
|
91629
92060
|
await judgeResponses(sessionPath, { judges });
|
|
91630
|
-
console.log(
|
|
92061
|
+
console.log(readFileSync42(join60(sessionPath, "verdict.md"), "utf-8"));
|
|
91631
92062
|
break;
|
|
91632
92063
|
}
|
|
91633
92064
|
case "status": {
|
|
@@ -92582,7 +93013,7 @@ var init_subscription_models_command = __esm(() => {
|
|
|
92582
93013
|
|
|
92583
93014
|
// src/auth/antigravity-oauth.ts
|
|
92584
93015
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
92585
|
-
import { existsSync as existsSync41, unlinkSync as
|
|
93016
|
+
import { existsSync as existsSync41, unlinkSync as unlinkSync11 } from "fs";
|
|
92586
93017
|
import { homedir as homedir40 } from "os";
|
|
92587
93018
|
import { join as join61 } from "path";
|
|
92588
93019
|
async function defaultSuggestModel() {
|
|
@@ -92705,7 +93136,7 @@ No session detected yet. Starting the Antigravity CLI interactively \u2014
|
|
|
92705
93136
|
try {
|
|
92706
93137
|
const tokenFile = join61(homedir40(), ".gemini", "antigravity-cli", "antigravity-oauth-token");
|
|
92707
93138
|
if (existsSync41(tokenFile))
|
|
92708
|
-
|
|
93139
|
+
unlinkSync11(tokenFile);
|
|
92709
93140
|
} catch {}
|
|
92710
93141
|
log("[AntigravityOAuth] Antigravity session cleared (keychain + agy token file)");
|
|
92711
93142
|
}
|
|
@@ -100851,7 +101282,7 @@ var init_own_pane = __esm(() => {
|
|
|
100851
101282
|
});
|
|
100852
101283
|
|
|
100853
101284
|
// src/hooks/session/interactive-driver.ts
|
|
100854
|
-
import { existsSync as existsSync42, statSync as
|
|
101285
|
+
import { existsSync as existsSync42, statSync as statSync18 } from "fs";
|
|
100855
101286
|
import { join as join62 } from "path";
|
|
100856
101287
|
function nextDriverPhase(phase, ev) {
|
|
100857
101288
|
const row = EDGES[phase];
|
|
@@ -101615,7 +102046,7 @@ function assertNeverPhase(p) {
|
|
|
101615
102046
|
}
|
|
101616
102047
|
function fileSizeOf(path) {
|
|
101617
102048
|
try {
|
|
101618
|
-
return
|
|
102049
|
+
return statSync18(path).size;
|
|
101619
102050
|
} catch {
|
|
101620
102051
|
return 0;
|
|
101621
102052
|
}
|
|
@@ -102169,20 +102600,20 @@ var init_terminal_isolation = __esm(() => {
|
|
|
102169
102600
|
|
|
102170
102601
|
// src/claude-runner.ts
|
|
102171
102602
|
import { spawn as spawn4, spawnSync as spawnSync4 } from "child_process";
|
|
102172
|
-
import { randomUUID as
|
|
102603
|
+
import { randomUUID as randomUUID9 } from "crypto";
|
|
102173
102604
|
import {
|
|
102174
102605
|
chmodSync as chmodSync4,
|
|
102175
102606
|
closeSync as closeSync12,
|
|
102176
102607
|
existsSync as existsSync44,
|
|
102177
|
-
mkdirSync as
|
|
102608
|
+
mkdirSync as mkdirSync26,
|
|
102178
102609
|
mkdtempSync as mkdtempSync4,
|
|
102179
102610
|
openSync as openSync12,
|
|
102180
|
-
readFileSync as
|
|
102611
|
+
readFileSync as readFileSync43,
|
|
102181
102612
|
readdirSync as readdirSync11,
|
|
102182
102613
|
rmSync as rmSync11,
|
|
102183
|
-
statSync as
|
|
102184
|
-
unlinkSync as
|
|
102185
|
-
writeFileSync as
|
|
102614
|
+
statSync as statSync19,
|
|
102615
|
+
unlinkSync as unlinkSync12,
|
|
102616
|
+
writeFileSync as writeFileSync26
|
|
102186
102617
|
} from "fs";
|
|
102187
102618
|
import { homedir as homedir41, tmpdir as tmpdir3 } from "os";
|
|
102188
102619
|
import { dirname as dirname20, join as join63 } from "path";
|
|
@@ -102352,7 +102783,7 @@ function settingsAuthSource(settings) {
|
|
|
102352
102783
|
return null;
|
|
102353
102784
|
}
|
|
102354
102785
|
function readableClaudeSettingsLayers(config, env, deps) {
|
|
102355
|
-
const readFile = deps.readFile ?? ((path) =>
|
|
102786
|
+
const readFile = deps.readFile ?? ((path) => readFileSync43(path, "utf-8"));
|
|
102356
102787
|
const home = deps.home ?? homedir41();
|
|
102357
102788
|
const cwd = deps.cwd ?? process.cwd();
|
|
102358
102789
|
const files = [
|
|
@@ -102399,7 +102830,7 @@ function managedSettingsPath() {
|
|
|
102399
102830
|
}
|
|
102400
102831
|
return "/etc/claude-code/managed-settings.json";
|
|
102401
102832
|
}
|
|
102402
|
-
function managedSettingsForcesClaudeAi(readFile =
|
|
102833
|
+
function managedSettingsForcesClaudeAi(readFile = readFileSync43) {
|
|
102403
102834
|
try {
|
|
102404
102835
|
const raw = readFile(managedSettingsPath(), "utf-8");
|
|
102405
102836
|
const parsed = JSON.parse(raw);
|
|
@@ -102547,13 +102978,13 @@ process.stdin.on('end', () => {
|
|
|
102547
102978
|
}
|
|
102548
102979
|
});
|
|
102549
102980
|
`;
|
|
102550
|
-
|
|
102981
|
+
writeFileSync26(scriptPath, script, "utf-8");
|
|
102551
102982
|
return scriptPath;
|
|
102552
102983
|
}
|
|
102553
102984
|
function initializeTokenFile(tokenFilePath) {
|
|
102554
102985
|
try {
|
|
102555
|
-
|
|
102556
|
-
|
|
102986
|
+
mkdirSync26(dirname20(tokenFilePath), { recursive: true });
|
|
102987
|
+
writeFileSync26(tokenFilePath, JSON.stringify({
|
|
102557
102988
|
input_tokens: 0,
|
|
102558
102989
|
output_tokens: 0,
|
|
102559
102990
|
total_tokens: 0,
|
|
@@ -102586,9 +103017,9 @@ function cleanupStaleTokenFiles(dir, now = Date.now(), maxAgeMs = STALE_TOKEN_FI
|
|
|
102586
103017
|
scanned++;
|
|
102587
103018
|
const full = join63(dir, name);
|
|
102588
103019
|
try {
|
|
102589
|
-
if (
|
|
103020
|
+
if (statSync19(full).mtimeMs >= cutoff)
|
|
102590
103021
|
continue;
|
|
102591
|
-
|
|
103022
|
+
unlinkSync12(full);
|
|
102592
103023
|
removed++;
|
|
102593
103024
|
} catch {}
|
|
102594
103025
|
}
|
|
@@ -102601,7 +103032,7 @@ function parseSettingsArg(value) {
|
|
|
102601
103032
|
if (value.trimStart().startsWith("{")) {
|
|
102602
103033
|
return JSON.parse(value);
|
|
102603
103034
|
}
|
|
102604
|
-
return JSON.parse(
|
|
103035
|
+
return JSON.parse(readFileSync43(value, "utf-8"));
|
|
102605
103036
|
}
|
|
102606
103037
|
function parseSettingsArgSafe(value) {
|
|
102607
103038
|
try {
|
|
@@ -102658,7 +103089,7 @@ function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLi
|
|
|
102658
103089
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir3();
|
|
102659
103090
|
const claudishDir = join63(homeDir, ".claudish");
|
|
102660
103091
|
try {
|
|
102661
|
-
|
|
103092
|
+
mkdirSync26(claudishDir, { recursive: true });
|
|
102662
103093
|
} catch {}
|
|
102663
103094
|
const tempPath = join63(claudishDir, `settings-${process.pid}-${Date.now()}.json`);
|
|
102664
103095
|
const assignedFile = assignedTokenFile(process.env) !== null;
|
|
@@ -102697,7 +103128,7 @@ function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLi
|
|
|
102697
103128
|
padding: 0
|
|
102698
103129
|
};
|
|
102699
103130
|
const settings = buildClaudishSettingsOverlay(statusLine, proxyAuthMode);
|
|
102700
|
-
|
|
103131
|
+
writeFileSync26(tempPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
102701
103132
|
return { path: tempPath, statusLine, tokenFilePath };
|
|
102702
103133
|
}
|
|
102703
103134
|
function scrubChildEnv(env, opts) {
|
|
@@ -102740,7 +103171,7 @@ function mergeUserSettingsIfPresent(config, tempSettingsPath, statusLine, proxyA
|
|
|
102740
103171
|
if (paneChild) {
|
|
102741
103172
|
userSettings.editorMode = "normal";
|
|
102742
103173
|
}
|
|
102743
|
-
|
|
103174
|
+
writeFileSync26(tempSettingsPath, JSON.stringify(userSettings, null, 2), "utf-8");
|
|
102744
103175
|
} catch {
|
|
102745
103176
|
if (!config.quiet) {
|
|
102746
103177
|
console.warn(`[claudish] Warning: could not merge user settings: ${userSettingsValue}`);
|
|
@@ -103074,7 +103505,7 @@ Or set CLAUDE_PATH to your custom installation:`);
|
|
|
103074
103505
|
const sessionFlags = sessionFlagsOf(config.claudeArgs);
|
|
103075
103506
|
let driverLaunch = null;
|
|
103076
103507
|
if (surfaces.driver) {
|
|
103077
|
-
const minted = sessionFlags.sessionId || sessionFlags.resumes ? null :
|
|
103508
|
+
const minted = sessionFlags.sessionId || sessionFlags.resumes ? null : randomUUID9();
|
|
103078
103509
|
const turnDir = mkdtempSync4(join63(tmpdir3(), "claudish-turns-"));
|
|
103079
103510
|
chmodSync4(turnDir, 448);
|
|
103080
103511
|
claudeArgs.unshift(...driverLeadingArgs({ mintedSessionId: minted, turnDir }));
|
|
@@ -103187,7 +103618,7 @@ Or set CLAUDE_PATH to your custom installation:`);
|
|
|
103187
103618
|
log(exitSignal ? `[Claude Code] Exited from ${exitSignal} (exit code ${exitCode})` : `[Claude Code] Exited with code ${exitCode}`);
|
|
103188
103619
|
releaseTerminalIsolation();
|
|
103189
103620
|
try {
|
|
103190
|
-
|
|
103621
|
+
unlinkSync12(tempSettingsPath);
|
|
103191
103622
|
} catch {}
|
|
103192
103623
|
return exitCode;
|
|
103193
103624
|
}
|
|
@@ -103210,7 +103641,7 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
|
|
|
103210
103641
|
} catch {}
|
|
103211
103642
|
}
|
|
103212
103643
|
try {
|
|
103213
|
-
|
|
103644
|
+
unlinkSync12(tempSettingsPath);
|
|
103214
103645
|
} catch {}
|
|
103215
103646
|
process.exit(128 + (SIGNAL_EXIT_NUMBERS[signal] ?? 0));
|
|
103216
103647
|
});
|
|
@@ -103338,13 +103769,13 @@ var init_claude_runner = __esm(() => {
|
|
|
103338
103769
|
});
|
|
103339
103770
|
|
|
103340
103771
|
// src/diag-output.ts
|
|
103341
|
-
import { createWriteStream as createWriteStream2, mkdirSync as
|
|
103772
|
+
import { createWriteStream as createWriteStream2, mkdirSync as mkdirSync27, unlinkSync as unlinkSync13, writeFileSync as writeFileSync27 } from "fs";
|
|
103342
103773
|
import { homedir as homedir42 } from "os";
|
|
103343
103774
|
import { join as join64 } from "path";
|
|
103344
103775
|
function getClaudishDir() {
|
|
103345
103776
|
const dir = join64(homedir42(), ".claudish");
|
|
103346
103777
|
try {
|
|
103347
|
-
|
|
103778
|
+
mkdirSync27(dir, { recursive: true });
|
|
103348
103779
|
} catch {}
|
|
103349
103780
|
return dir;
|
|
103350
103781
|
}
|
|
@@ -103358,7 +103789,7 @@ class LogFileDiagOutput {
|
|
|
103358
103789
|
constructor() {
|
|
103359
103790
|
this.logPath = getDiagLogPath();
|
|
103360
103791
|
try {
|
|
103361
|
-
|
|
103792
|
+
writeFileSync27(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
|
|
103362
103793
|
`);
|
|
103363
103794
|
} catch {}
|
|
103364
103795
|
this.stream = createWriteStream2(this.logPath, { flags: "a" });
|
|
@@ -103377,7 +103808,7 @@ class LogFileDiagOutput {
|
|
|
103377
103808
|
this.stream.end();
|
|
103378
103809
|
} catch {}
|
|
103379
103810
|
try {
|
|
103380
|
-
|
|
103811
|
+
unlinkSync13(this.logPath);
|
|
103381
103812
|
} catch {}
|
|
103382
103813
|
}
|
|
103383
103814
|
getLogPath() {
|
|
@@ -103914,7 +104345,7 @@ var init_advisor_startup = __esm(() => {
|
|
|
103914
104345
|
});
|
|
103915
104346
|
|
|
103916
104347
|
// src/session/conversation.ts
|
|
103917
|
-
import { closeSync as closeSync13, openSync as openSync13, readSync as readSync7, statSync as
|
|
104348
|
+
import { closeSync as closeSync13, openSync as openSync13, readSync as readSync7, statSync as statSync20 } from "fs";
|
|
103918
104349
|
import { StringDecoder } from "string_decoder";
|
|
103919
104350
|
function looksLikeTurn(line) {
|
|
103920
104351
|
const assistant = line.includes('"type":"assistant"');
|
|
@@ -103969,7 +104400,7 @@ function readConversation(file, opts = {}) {
|
|
|
103969
104400
|
};
|
|
103970
104401
|
let fd = null;
|
|
103971
104402
|
try {
|
|
103972
|
-
const size =
|
|
104403
|
+
const size = statSync20(file).size;
|
|
103973
104404
|
fd = openSync13(file, "r");
|
|
103974
104405
|
const buf = Buffer.allocUnsafe(chunkBytes);
|
|
103975
104406
|
const decoder = new StringDecoder("utf-8");
|
|
@@ -105628,11 +106059,11 @@ var exports_session_stats = {};
|
|
|
105628
106059
|
__export(exports_session_stats, {
|
|
105629
106060
|
readSessionStats: () => readSessionStats
|
|
105630
106061
|
});
|
|
105631
|
-
import { readFileSync as
|
|
106062
|
+
import { readFileSync as readFileSync44 } from "fs";
|
|
105632
106063
|
function readSessionStats(port, opts) {
|
|
105633
106064
|
let raw;
|
|
105634
106065
|
try {
|
|
105635
|
-
raw = JSON.parse(
|
|
106066
|
+
raw = JSON.parse(readFileSync44(resolveTokenFilePath(port), "utf-8"));
|
|
105636
106067
|
} catch {
|
|
105637
106068
|
return null;
|
|
105638
106069
|
}
|
|
@@ -106010,7 +106441,7 @@ init_launch_env();
|
|
|
106010
106441
|
init_op_source();
|
|
106011
106442
|
init_startup_trace();
|
|
106012
106443
|
init_picker_cancelled();
|
|
106013
|
-
import { existsSync as existsSync45, readFileSync as
|
|
106444
|
+
import { existsSync as existsSync45, readFileSync as readFileSync45 } from "fs";
|
|
106014
106445
|
import { join as join65, resolve as resolve10 } from "path";
|
|
106015
106446
|
|
|
106016
106447
|
// src/tui/runtime/should-open-picker.ts
|
|
@@ -106028,7 +106459,7 @@ function requiresExplicitModel(gate, tty) {
|
|
|
106028
106459
|
var autoloadDropped = [...droppedAtLaunch, ...takeLauncherDropped(process.env)];
|
|
106029
106460
|
var dotenvText;
|
|
106030
106461
|
try {
|
|
106031
|
-
dotenvText =
|
|
106462
|
+
dotenvText = readFileSync45(join65(process.cwd(), ".env"));
|
|
106032
106463
|
} catch {}
|
|
106033
106464
|
if (dotenvText !== undefined) {
|
|
106034
106465
|
await Promise.resolve().then(() => init_dotenv_allowlist());
|
|
@@ -106349,7 +106780,7 @@ async function runCli() {
|
|
|
106349
106780
|
if (cliConfig.team && cliConfig.team.length > 0) {
|
|
106350
106781
|
let prompt = cliConfig.claudeArgs.join(" ");
|
|
106351
106782
|
if (cliConfig.inputFile) {
|
|
106352
|
-
prompt =
|
|
106783
|
+
prompt = readFileSync45(cliConfig.inputFile, "utf-8");
|
|
106353
106784
|
}
|
|
106354
106785
|
if (!prompt.trim()) {
|
|
106355
106786
|
console.error("Error: --team requires a prompt (positional args or -f <file>)");
|
|
@@ -106378,7 +106809,7 @@ async function runCli() {
|
|
|
106378
106809
|
for (const anonId of Object.keys(status.models)) {
|
|
106379
106810
|
const responsePath = join65(sessionPath, `response-${anonId}.md`);
|
|
106380
106811
|
try {
|
|
106381
|
-
const raw =
|
|
106812
|
+
const raw = readFileSync45(responsePath, "utf-8").trim();
|
|
106382
106813
|
try {
|
|
106383
106814
|
result.responses[anonId] = JSON.parse(raw);
|
|
106384
106815
|
} catch {
|