claudish 13.2.0 → 13.4.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 +303 -167
- package/package.json +5 -5
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 = "13.
|
|
578
|
+
var VERSION = "13.4.0";
|
|
579
579
|
|
|
580
580
|
// src/logger.ts
|
|
581
581
|
import { appendFile, existsSync as existsSync2, mkdirSync, readdirSync, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
@@ -6484,6 +6484,12 @@ function isOptInWireId(wireId) {
|
|
|
6484
6484
|
return /-contributor(?:-free)?$/i.test(wireId.split("/").pop() ?? wireId);
|
|
6485
6485
|
}
|
|
6486
6486
|
function isOptInConnection(connection) {
|
|
6487
|
+
if ("contentUse" in connection) {
|
|
6488
|
+
if (connection.contentUse === "contributor")
|
|
6489
|
+
return true;
|
|
6490
|
+
if (connection.contentUse === "standard")
|
|
6491
|
+
return false;
|
|
6492
|
+
}
|
|
6487
6493
|
return typeof connection.externalModelId === "string" && isOptInWireId(connection.externalModelId);
|
|
6488
6494
|
}
|
|
6489
6495
|
function splitOptInConnections(entry) {
|
|
@@ -6715,6 +6721,7 @@ var init_catalog_route_bindings = __esm(() => {
|
|
|
6715
6721
|
vertex: { routeId: "vertex", routeProfileId: "google-cloud" },
|
|
6716
6722
|
deepseek: { routeId: "deepseek", routeProfileId: "direct-api" },
|
|
6717
6723
|
mistralai: { routeId: "mistralai", routeProfileId: "direct-api" },
|
|
6724
|
+
"meta-muse-code": { routeId: "meta", routeProfileId: "muse-code-subscription" },
|
|
6718
6725
|
meta: { routeId: "meta", routeProfileId: "direct-api" }
|
|
6719
6726
|
};
|
|
6720
6727
|
LOOKUP_ONLY_ROUTE_BINDINGS = {
|
|
@@ -35570,6 +35577,9 @@ function effectiveBaseUrl(registryBaseUrl, definitionBaseUrl, resolvedBaseUrl) {
|
|
|
35570
35577
|
}
|
|
35571
35578
|
return { baseUrl: resolvedBaseUrl.replace(/\/+$/, ""), overridden: true };
|
|
35572
35579
|
}
|
|
35580
|
+
function requestBaseUrl(connection, api) {
|
|
35581
|
+
return connection.provider === "meta-muse-code" ? `${MUSE_CODE_BASE_URL}/v1` : connectionBaseUrl(connection, api);
|
|
35582
|
+
}
|
|
35573
35583
|
function describeConnectionWire(connection) {
|
|
35574
35584
|
const where = `${connection.route.routeId}/${connection.route.routeProfileId} \xB7 ${connection.externalModelId}`;
|
|
35575
35585
|
const { wire } = connection;
|
|
@@ -35579,7 +35589,7 @@ function describeConnectionWire(connection) {
|
|
|
35579
35589
|
const apis = Object.keys(connection.profile.apis).join(", ") || "none";
|
|
35580
35590
|
return `${where}: wire unknown \u2014 tries ${apis} in turn`;
|
|
35581
35591
|
}
|
|
35582
|
-
const base =
|
|
35592
|
+
const base = requestBaseUrl(connection, wire.api);
|
|
35583
35593
|
const url = base ? wireRequestUrl(base, wire.api, connection.externalModelId) : "no base URL";
|
|
35584
35594
|
const status = (value) => typeof value === "string" ? value : value.status;
|
|
35585
35595
|
const parts = [`${wire.api} ${url}`, `limit ${status(wire.tokenParam)}`];
|
|
@@ -35748,11 +35758,14 @@ function tryInTurn(ctx, definitionName, connection, why) {
|
|
|
35748
35758
|
};
|
|
35749
35759
|
}
|
|
35750
35760
|
function buildKnownWireHandler(ctx, definitionName, connection, wire) {
|
|
35751
|
-
const registryBase =
|
|
35761
|
+
const registryBase = requestBaseUrl(connection, wire.api);
|
|
35752
35762
|
if (!registryBase)
|
|
35753
35763
|
return null;
|
|
35754
35764
|
const definition = getProviderByName(definitionName);
|
|
35755
|
-
const { baseUrl, overridden } = effectiveBaseUrl(registryBase, definition?.baseUrl, ctx.provider.baseUrl);
|
|
35765
|
+
const { baseUrl, overridden } = definitionName === "meta-muse-code" ? { baseUrl: registryBase, overridden: false } : effectiveBaseUrl(registryBase, definition?.baseUrl, ctx.provider.baseUrl);
|
|
35766
|
+
if (definitionName === "meta-muse-code" && ctx.provider.baseUrl && ctx.provider.baseUrl !== definition?.baseUrl) {
|
|
35767
|
+
log(`[Wire] meta-muse-code: user base URL ignored \u2192 ${baseUrl}`);
|
|
35768
|
+
}
|
|
35756
35769
|
const url = wireRequestUrl(baseUrl, wire.api, connection.externalModelId);
|
|
35757
35770
|
if (overridden)
|
|
35758
35771
|
log(`[Wire] ${definitionName}: base URL overridden by user config \u2192 ${baseUrl}`);
|
|
@@ -35780,6 +35793,7 @@ var init_wire_handler = __esm(() => {
|
|
|
35780
35793
|
init_catalog_client();
|
|
35781
35794
|
init_connection_resolver();
|
|
35782
35795
|
init_connection_wire();
|
|
35796
|
+
init_muse_mint();
|
|
35783
35797
|
init_provider_definitions();
|
|
35784
35798
|
init_anthropic_compat();
|
|
35785
35799
|
init_gemini_apikey();
|
|
@@ -50416,12 +50430,15 @@ function projectRecommendations(recommendations, catalog, richModels = [], now =
|
|
|
50416
50430
|
const priority = (rankByTier.get(recommended.tier) ?? 0) + 1;
|
|
50417
50431
|
rankByTier.set(recommended.tier, priority);
|
|
50418
50432
|
const rich = richById.get(recommended.modelId);
|
|
50433
|
+
const nativeProvider = nativeProviderForVendor(rich?.provider ?? model.provider ?? "");
|
|
50434
|
+
const nativeRouteAvailable = Boolean(nativeProvider && model.aggregators?.some((connection) => connection.routeStatus === "mapped" && catalogRouteMatchesProvider(connection.route, nativeProvider)));
|
|
50419
50435
|
const subscription = recommended.tier === "subscription" ? subscriptionRouteFor(recommended, model, catalog.plans) : undefined;
|
|
50420
50436
|
models.push({
|
|
50421
50437
|
id: recommended.modelId,
|
|
50422
50438
|
name: rich?.displayName ?? model.displayName ?? recommended.modelId,
|
|
50423
50439
|
description: rich?.description ?? "",
|
|
50424
50440
|
provider: rich?.provider ?? model.provider ?? "",
|
|
50441
|
+
nativeRouteAvailable,
|
|
50425
50442
|
recommendationTier: recommended.tier,
|
|
50426
50443
|
priority,
|
|
50427
50444
|
pricing: {
|
|
@@ -50628,7 +50645,7 @@ function uniqueRecommendedModels(entries) {
|
|
|
50628
50645
|
}
|
|
50629
50646
|
function collectRoutingPrefixes(group, getNativePrefix) {
|
|
50630
50647
|
const slug = (group.primary.provider || "").toLowerCase();
|
|
50631
|
-
const native = getNativePrefix(slug);
|
|
50648
|
+
const native = group.primary.nativeRouteAvailable === false ? null : getNativePrefix(slug);
|
|
50632
50649
|
const seen = new Set;
|
|
50633
50650
|
const out = [];
|
|
50634
50651
|
if (native) {
|
|
@@ -50873,13 +50890,14 @@ function getAvailableModels() {
|
|
|
50873
50890
|
_cachedModelIds = result;
|
|
50874
50891
|
return result;
|
|
50875
50892
|
}
|
|
50876
|
-
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 =
|
|
50893
|
+
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;
|
|
50877
50894
|
var init_model_loader = __esm(() => {
|
|
50878
50895
|
init_all_models_cache();
|
|
50879
50896
|
init_auto_route();
|
|
50880
50897
|
init_cache_ttl();
|
|
50881
50898
|
init_catalog_client();
|
|
50882
50899
|
init_catalog_route_bindings();
|
|
50900
|
+
init_route_candidates();
|
|
50883
50901
|
RECOMMENDATION_SECTIONS = [
|
|
50884
50902
|
{ recommendationTier: "flagship", title: "Flagship", quickPickEligible: true },
|
|
50885
50903
|
{
|
|
@@ -76454,23 +76472,122 @@ var init_team_orchestrator = __esm(() => {
|
|
|
76454
76472
|
CANCELLED_DETAIL = `Stopped on the caller's instruction via team(mode:"cancel"). ` + "Whatever the child had written up to that point is in its response file.";
|
|
76455
76473
|
});
|
|
76456
76474
|
|
|
76475
|
+
// src/mcp-session/inherited-settings.ts
|
|
76476
|
+
import { existsSync as existsSync34, readFileSync as readFileSync33, statSync as statSync13 } from "fs";
|
|
76477
|
+
import { join as join51, resolve as resolve6 } from "path";
|
|
76478
|
+
function isPlainObject6(value) {
|
|
76479
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
76480
|
+
}
|
|
76481
|
+
function uniqueByJson(values) {
|
|
76482
|
+
const seen = new Set;
|
|
76483
|
+
return values.filter((value) => {
|
|
76484
|
+
const key = JSON.stringify(value);
|
|
76485
|
+
if (seen.has(key))
|
|
76486
|
+
return false;
|
|
76487
|
+
seen.add(key);
|
|
76488
|
+
return true;
|
|
76489
|
+
});
|
|
76490
|
+
}
|
|
76491
|
+
function mergeSettingsLayers(base, over) {
|
|
76492
|
+
const merged = structuredClone(base);
|
|
76493
|
+
for (const [key, value] of Object.entries(over)) {
|
|
76494
|
+
const current = merged[key];
|
|
76495
|
+
if (isPlainObject6(current) && isPlainObject6(value)) {
|
|
76496
|
+
merged[key] = mergeSettingsLayers(current, value);
|
|
76497
|
+
} else if (Array.isArray(current) && Array.isArray(value)) {
|
|
76498
|
+
merged[key] = uniqueByJson([...current, ...structuredClone(value)]);
|
|
76499
|
+
} else {
|
|
76500
|
+
merged[key] = structuredClone(value);
|
|
76501
|
+
}
|
|
76502
|
+
}
|
|
76503
|
+
return merged;
|
|
76504
|
+
}
|
|
76505
|
+
function parseLayer(text, source) {
|
|
76506
|
+
let parsed;
|
|
76507
|
+
try {
|
|
76508
|
+
parsed = JSON.parse(text);
|
|
76509
|
+
} catch (err) {
|
|
76510
|
+
throw new Error(`invalid_args: settings ${source} is not valid JSON (${err.message})`);
|
|
76511
|
+
}
|
|
76512
|
+
if (!isPlainObject6(parsed)) {
|
|
76513
|
+
throw new Error(`invalid_args: settings ${source} is not a JSON object`);
|
|
76514
|
+
}
|
|
76515
|
+
return parsed;
|
|
76516
|
+
}
|
|
76517
|
+
function readSettingsValue(value) {
|
|
76518
|
+
if (value.trim().startsWith("{"))
|
|
76519
|
+
return parseLayer(value, value);
|
|
76520
|
+
let text;
|
|
76521
|
+
try {
|
|
76522
|
+
text = readFileSync33(value, "utf-8");
|
|
76523
|
+
} catch (err) {
|
|
76524
|
+
throw new Error(`invalid_args: settings ${value} cannot be read (${err.message})`);
|
|
76525
|
+
}
|
|
76526
|
+
return parseLayer(text, value);
|
|
76527
|
+
}
|
|
76528
|
+
function buildInheritedSettingsLayer(setupFrom, callerFlags) {
|
|
76529
|
+
const layers = [];
|
|
76530
|
+
for (const name of ["settings.json", "settings.local.json"]) {
|
|
76531
|
+
const file = join51(setupFrom, ".claude", name);
|
|
76532
|
+
if (!existsSync34(file))
|
|
76533
|
+
continue;
|
|
76534
|
+
layers.push(parseLayer(readFileSync33(file, "utf-8"), file));
|
|
76535
|
+
}
|
|
76536
|
+
const restFlags = [];
|
|
76537
|
+
for (let i = 0;i < callerFlags.length; i++) {
|
|
76538
|
+
const flag = callerFlags[i];
|
|
76539
|
+
if (flag === "--settings") {
|
|
76540
|
+
const value = callerFlags[i + 1];
|
|
76541
|
+
if (value === undefined)
|
|
76542
|
+
throw new Error("invalid_args: --settings needs a value");
|
|
76543
|
+
layers.push(readSettingsValue(value));
|
|
76544
|
+
i++;
|
|
76545
|
+
} else if (flag.startsWith("--settings=")) {
|
|
76546
|
+
layers.push(readSettingsValue(flag.slice("--settings=".length)));
|
|
76547
|
+
} else {
|
|
76548
|
+
restFlags.push(flag);
|
|
76549
|
+
}
|
|
76550
|
+
}
|
|
76551
|
+
if (layers.length === 0)
|
|
76552
|
+
return { layer: null, restFlags };
|
|
76553
|
+
const layer = layers.reduce((acc, next) => mergeSettingsLayers(acc, next), {});
|
|
76554
|
+
if (isPlainObject6(layer.permissions))
|
|
76555
|
+
delete layer.permissions.additionalDirectories;
|
|
76556
|
+
return { layer, restFlags };
|
|
76557
|
+
}
|
|
76558
|
+
function resolveSetupFrom(arg, workDir, serverCwd) {
|
|
76559
|
+
if (arg === null)
|
|
76560
|
+
return;
|
|
76561
|
+
let setupFrom = serverCwd;
|
|
76562
|
+
if (typeof arg === "string") {
|
|
76563
|
+
setupFrom = resolve6(arg);
|
|
76564
|
+
if (!statSync13(setupFrom, { throwIfNoEntry: false })?.isDirectory()) {
|
|
76565
|
+
throw new Error(`invalid_args: setup_from ${setupFrom} is not an existing directory`);
|
|
76566
|
+
}
|
|
76567
|
+
} else if (arg !== undefined) {
|
|
76568
|
+
throw new Error("invalid_args: setup_from must be a directory path or null");
|
|
76569
|
+
}
|
|
76570
|
+
return setupFrom === resolve6(workDir ?? serverCwd) ? undefined : setupFrom;
|
|
76571
|
+
}
|
|
76572
|
+
var init_inherited_settings = () => {};
|
|
76573
|
+
|
|
76457
76574
|
// src/mcp-session/session-manager.ts
|
|
76458
76575
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
76459
76576
|
import {
|
|
76460
76577
|
appendFileSync as appendFileSync7,
|
|
76461
76578
|
closeSync as closeSync11,
|
|
76462
76579
|
createWriteStream,
|
|
76463
|
-
existsSync as
|
|
76580
|
+
existsSync as existsSync35,
|
|
76464
76581
|
mkdirSync as mkdirSync22,
|
|
76465
76582
|
openSync as openSync11,
|
|
76466
|
-
readFileSync as
|
|
76583
|
+
readFileSync as readFileSync34,
|
|
76467
76584
|
readSync as readSync6,
|
|
76468
76585
|
renameSync as renameSync5,
|
|
76469
76586
|
rmSync as rmSync9,
|
|
76470
|
-
statSync as
|
|
76587
|
+
statSync as statSync14,
|
|
76471
76588
|
writeFileSync as writeFileSync23
|
|
76472
76589
|
} from "fs";
|
|
76473
|
-
import { join as
|
|
76590
|
+
import { join as join52, resolve as resolve7, sep as sep2 } from "path";
|
|
76474
76591
|
function normaliseTimeoutSeconds(raw) {
|
|
76475
76592
|
const n = typeof raw === "string" && raw.trim() !== "" ? Number(raw) : raw;
|
|
76476
76593
|
if (typeof n !== "number" || !Number.isFinite(n))
|
|
@@ -76570,7 +76687,7 @@ function anomalyKey(a) {
|
|
|
76570
76687
|
function readTailText(path, maxBytes) {
|
|
76571
76688
|
let fd = null;
|
|
76572
76689
|
try {
|
|
76573
|
-
const size =
|
|
76690
|
+
const size = statSync14(path).size;
|
|
76574
76691
|
if (size === 0)
|
|
76575
76692
|
return { text: "", truncated: false };
|
|
76576
76693
|
const start = Math.max(0, size - maxBytes);
|
|
@@ -76601,7 +76718,7 @@ function readTailLines2(path, maxBytes) {
|
|
|
76601
76718
|
}
|
|
76602
76719
|
function fileSize2(path) {
|
|
76603
76720
|
try {
|
|
76604
|
-
return
|
|
76721
|
+
return statSync14(path).size;
|
|
76605
76722
|
} catch {
|
|
76606
76723
|
return 0;
|
|
76607
76724
|
}
|
|
@@ -76610,7 +76727,7 @@ function readJsonObject(path, maxBytes) {
|
|
|
76610
76727
|
try {
|
|
76611
76728
|
if (fileSize2(path) > maxBytes)
|
|
76612
76729
|
return null;
|
|
76613
|
-
const parsed = JSON.parse(
|
|
76730
|
+
const parsed = JSON.parse(readFileSync34(path, "utf-8"));
|
|
76614
76731
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
76615
76732
|
return null;
|
|
76616
76733
|
return parsed;
|
|
@@ -76636,7 +76753,7 @@ function dropLeadingFragment(tail) {
|
|
|
76636
76753
|
return firstBreak === -1 ? tail.text : tail.text.slice(firstBreak + 1);
|
|
76637
76754
|
}
|
|
76638
76755
|
function diskAccounting(sessionDir) {
|
|
76639
|
-
const stats = readTokenStatsAt(
|
|
76756
|
+
const stats = readTokenStatsAt(join52(sessionDir, "tokens.json"));
|
|
76640
76757
|
return {
|
|
76641
76758
|
tokensIn: stats?.billed_input_tokens ?? null,
|
|
76642
76759
|
tokensOut: stats?.output_tokens ?? null,
|
|
@@ -76719,7 +76836,7 @@ class SessionManager {
|
|
|
76719
76836
|
let dir = "";
|
|
76720
76837
|
for (let attempt = 0;; attempt++) {
|
|
76721
76838
|
id = `team-${randomUUID7().replace(/-/g, "").slice(0, 8)}`;
|
|
76722
|
-
dir =
|
|
76839
|
+
dir = join52(this.sessionsDir, id);
|
|
76723
76840
|
try {
|
|
76724
76841
|
mkdirSync22(dir);
|
|
76725
76842
|
break;
|
|
@@ -76734,7 +76851,7 @@ class SessionManager {
|
|
|
76734
76851
|
sessionId: id,
|
|
76735
76852
|
parentClaudeSessionId: opts.parentClaudeSessionId,
|
|
76736
76853
|
startedAt,
|
|
76737
|
-
teamPath:
|
|
76854
|
+
teamPath: resolve7(opts.teamPath),
|
|
76738
76855
|
slots: opts.slots
|
|
76739
76856
|
});
|
|
76740
76857
|
this.teamRunStarts.set(id, startedAt);
|
|
@@ -76751,9 +76868,9 @@ class SessionManager {
|
|
|
76751
76868
|
if (dir === null)
|
|
76752
76869
|
throw new Error("not a record id");
|
|
76753
76870
|
const completedAt = new Date().toISOString();
|
|
76754
|
-
const startedAt = this.teamRunStarts.get(record) ?? metaString(readJsonObject(
|
|
76871
|
+
const startedAt = this.teamRunStarts.get(record) ?? metaString(readJsonObject(join52(dir, "spawn.json"), META_READ_LIMIT)?.startedAt) ?? completedAt;
|
|
76755
76872
|
const elapsedMs = Date.parse(completedAt) - Date.parse(startedAt);
|
|
76756
|
-
writeJsonAtomic(
|
|
76873
|
+
writeJsonAtomic(join52(dir, "meta.json"), {
|
|
76757
76874
|
kind: "team",
|
|
76758
76875
|
status: outcome.status,
|
|
76759
76876
|
startedAt,
|
|
@@ -76785,7 +76902,7 @@ class SessionManager {
|
|
|
76785
76902
|
startedAt,
|
|
76786
76903
|
...rest
|
|
76787
76904
|
};
|
|
76788
|
-
writeJsonAtomic(
|
|
76905
|
+
writeJsonAtomic(join52(dir, "spawn.json"), body);
|
|
76789
76906
|
}
|
|
76790
76907
|
async createSession(opts) {
|
|
76791
76908
|
if (this.activeSessions + this.starting >= this.maxSessions) {
|
|
@@ -76794,10 +76911,12 @@ class SessionManager {
|
|
|
76794
76911
|
if (opts.sessionId !== undefined && this.sessions.has(opts.sessionId)) {
|
|
76795
76912
|
throw new Error(`Session id already in use: ${opts.sessionId}`);
|
|
76796
76913
|
}
|
|
76797
|
-
const
|
|
76798
|
-
const flagCheck = checkChildFlags(
|
|
76914
|
+
const callerFlags = opts.claudishFlags ?? [];
|
|
76915
|
+
const flagCheck = checkChildFlags(callerFlags);
|
|
76799
76916
|
if (!flagCheck.ok)
|
|
76800
76917
|
throw new Error(`invalid_args: ${flagCheck.message}`);
|
|
76918
|
+
const inherited = opts.setupFrom ? buildInheritedSettingsLayer(opts.setupFrom, callerFlags) : { layer: null, restFlags: callerFlags };
|
|
76919
|
+
let flags = callerFlags;
|
|
76801
76920
|
const readAvailable = !flagsRemoveRead(flags);
|
|
76802
76921
|
if (opts.prompt) {
|
|
76803
76922
|
const refusal = deliveryRefusal(opts.prompt, readAvailable);
|
|
@@ -76817,11 +76936,14 @@ class SessionManager {
|
|
|
76817
76936
|
reservePanes(1, sockRootFor(parentEnv));
|
|
76818
76937
|
let entry;
|
|
76819
76938
|
try {
|
|
76820
|
-
entry = this.recordSession(opts);
|
|
76939
|
+
entry = this.recordSession(opts, inherited.layer);
|
|
76821
76940
|
} catch (err) {
|
|
76822
76941
|
releasePaneReservations(1);
|
|
76823
76942
|
throw err;
|
|
76824
76943
|
}
|
|
76944
|
+
if (inherited.layer) {
|
|
76945
|
+
flags = [...inherited.restFlags, "--settings", join52(entry.sessionDir, INHERITED_SETTINGS)];
|
|
76946
|
+
}
|
|
76825
76947
|
this.sessions.set(entry.info.sessionId, entry);
|
|
76826
76948
|
uncount();
|
|
76827
76949
|
const started = this.startPane(entry, opts, { flags, readAvailable, parentEnv });
|
|
@@ -76839,15 +76961,15 @@ class SessionManager {
|
|
|
76839
76961
|
uncount();
|
|
76840
76962
|
}
|
|
76841
76963
|
}
|
|
76842
|
-
recordSession(opts) {
|
|
76964
|
+
recordSession(opts, inheritedLayer) {
|
|
76843
76965
|
const sessionId = opts.sessionId ?? randomUUID7().slice(0, 8);
|
|
76844
76966
|
const claudeSessionId = randomUUID7();
|
|
76845
76967
|
const timeout = normaliseTimeoutSeconds(opts.timeoutSeconds);
|
|
76846
76968
|
const startedAt = new Date().toISOString();
|
|
76847
|
-
const sessionDir = opts.sessionDir ??
|
|
76969
|
+
const sessionDir = opts.sessionDir ?? join52(this.sessionsDir, sessionId);
|
|
76848
76970
|
mkdirSync22(sessionDir, { recursive: true });
|
|
76849
76971
|
if (opts.prompt)
|
|
76850
|
-
writeFileSync23(
|
|
76972
|
+
writeFileSync23(join52(sessionDir, "prompt.md"), opts.prompt, "utf-8");
|
|
76851
76973
|
this.writeSpawnRecord(sessionDir, {
|
|
76852
76974
|
kind: "session",
|
|
76853
76975
|
sessionId,
|
|
@@ -76855,12 +76977,17 @@ class SessionManager {
|
|
|
76855
76977
|
startedAt,
|
|
76856
76978
|
model: opts.model,
|
|
76857
76979
|
timeoutSeconds: timeout,
|
|
76858
|
-
claudeSessionId
|
|
76980
|
+
claudeSessionId,
|
|
76981
|
+
...opts.setupFrom ? { setupFrom: opts.setupFrom } : {}
|
|
76859
76982
|
});
|
|
76983
|
+
if (inheritedLayer) {
|
|
76984
|
+
writeFileSync23(join52(sessionDir, INHERITED_SETTINGS), `${JSON.stringify(inheritedLayer, null, 2)}
|
|
76985
|
+
`, { encoding: "utf-8", mode: 384 });
|
|
76986
|
+
}
|
|
76860
76987
|
const cwd = opts.cwd ?? process.cwd();
|
|
76861
76988
|
const parentEnv = opts.parentEnv ?? this.parentEnv;
|
|
76862
76989
|
const spawnModel = opts.spawnModel ?? null;
|
|
76863
|
-
const tokenFile = opts.tokenFile ??
|
|
76990
|
+
const tokenFile = opts.tokenFile ?? join52(sessionDir, "tokens.json");
|
|
76864
76991
|
return {
|
|
76865
76992
|
info: {
|
|
76866
76993
|
sessionId,
|
|
@@ -76896,18 +77023,18 @@ class SessionManager {
|
|
|
76896
77023
|
},
|
|
76897
77024
|
session: null,
|
|
76898
77025
|
scrollback: new ScrollbackBuffer(this.scrollbackCapacity),
|
|
76899
|
-
outputLogStream: createWriteStream(
|
|
77026
|
+
outputLogStream: createWriteStream(join52(sessionDir, "output.log")),
|
|
76900
77027
|
sessionDir,
|
|
76901
77028
|
cwd,
|
|
76902
77029
|
tokenFile,
|
|
76903
|
-
eventLogPath:
|
|
77030
|
+
eventLogPath: join52(sessionDir, "events.jsonl"),
|
|
76904
77031
|
eventLogBytes: 0,
|
|
76905
|
-
upstreamErrorLogPath:
|
|
77032
|
+
upstreamErrorLogPath: join52(sessionDir, "upstream-errors.jsonl"),
|
|
76906
77033
|
eventRing: [],
|
|
76907
77034
|
proseBytes: 0,
|
|
76908
77035
|
answeredTurns: new Map,
|
|
76909
77036
|
inboxPath: null,
|
|
76910
|
-
waitLogPath:
|
|
77037
|
+
waitLogPath: join52(sessionDir, "waits.jsonl"),
|
|
76911
77038
|
waitLogBytes: 0,
|
|
76912
77039
|
waitSince: null,
|
|
76913
77040
|
ended: false,
|
|
@@ -77096,7 +77223,7 @@ class SessionManager {
|
|
|
77096
77223
|
try {
|
|
77097
77224
|
const text = screenLines.join(`
|
|
77098
77225
|
`).replace(/\s+$/, "");
|
|
77099
|
-
writeFileSync23(
|
|
77226
|
+
writeFileSync23(join52(entry.sessionDir, "screen.txt"), `${redactSecrets2(text)}
|
|
77100
77227
|
`, "utf-8");
|
|
77101
77228
|
} catch {}
|
|
77102
77229
|
}
|
|
@@ -77110,7 +77237,7 @@ class SessionManager {
|
|
|
77110
77237
|
entry.waitSince = null;
|
|
77111
77238
|
}
|
|
77112
77239
|
try {
|
|
77113
|
-
writeJsonAtomic(
|
|
77240
|
+
writeJsonAtomic(join52(entry.sessionDir, "meta.json"), toMetaRecord(entry.info, entry.cwd));
|
|
77114
77241
|
} catch (err) {
|
|
77115
77242
|
process.stderr.write(`[claudish] session ${entry.info.sessionId}: could not write meta.json: ` + `${err instanceof Error ? err.message : String(err)}
|
|
77116
77243
|
`);
|
|
@@ -77369,9 +77496,9 @@ class SessionManager {
|
|
|
77369
77496
|
diskSessionDir(sessionId) {
|
|
77370
77497
|
if (!SESSION_ID_RE.test(sessionId))
|
|
77371
77498
|
return null;
|
|
77372
|
-
const root =
|
|
77373
|
-
const dir =
|
|
77374
|
-
if (dir !==
|
|
77499
|
+
const root = resolve7(this.sessionsDir);
|
|
77500
|
+
const dir = resolve7(root, sessionId);
|
|
77501
|
+
if (dir !== join52(root, sessionId))
|
|
77375
77502
|
return null;
|
|
77376
77503
|
if (!dir.startsWith(root + sep2))
|
|
77377
77504
|
return null;
|
|
@@ -77383,17 +77510,17 @@ class SessionManager {
|
|
|
77383
77510
|
return null;
|
|
77384
77511
|
let dirMtimeMs;
|
|
77385
77512
|
try {
|
|
77386
|
-
const stat =
|
|
77513
|
+
const stat = statSync14(sessionDir);
|
|
77387
77514
|
if (!stat.isDirectory())
|
|
77388
77515
|
return null;
|
|
77389
77516
|
dirMtimeMs = stat.mtimeMs;
|
|
77390
77517
|
} catch {
|
|
77391
77518
|
return null;
|
|
77392
77519
|
}
|
|
77393
|
-
const spawnRecord = readJsonObject(
|
|
77520
|
+
const spawnRecord = readJsonObject(join52(sessionDir, "spawn.json"), META_READ_LIMIT);
|
|
77394
77521
|
if (spawnRecord?.kind === "team")
|
|
77395
77522
|
return null;
|
|
77396
|
-
const meta = readJsonObject(
|
|
77523
|
+
const meta = readJsonObject(join52(sessionDir, "meta.json"), META_READ_LIMIT);
|
|
77397
77524
|
if (meta?.kind === "team")
|
|
77398
77525
|
return null;
|
|
77399
77526
|
const partial = meta === null;
|
|
@@ -77408,14 +77535,14 @@ class SessionManager {
|
|
|
77408
77535
|
diskTranscriptPath(meta, uuid) {
|
|
77409
77536
|
const stored = metaString(meta?.transcriptPath) ?? "";
|
|
77410
77537
|
const cwd = metaString(meta?.cwd);
|
|
77411
|
-
if (stored &&
|
|
77538
|
+
if (stored && existsSync35(stored))
|
|
77412
77539
|
return stored;
|
|
77413
77540
|
if (cwd && uuid)
|
|
77414
77541
|
return transcriptPathFor(cwd, uuid, projectsDir(this.parentEnv));
|
|
77415
77542
|
return stored;
|
|
77416
77543
|
}
|
|
77417
77544
|
diskOutput(record, tailLines) {
|
|
77418
|
-
const tail = readTailText(
|
|
77545
|
+
const tail = readTailText(join52(record.sessionDir, "output.log"), OUTPUT_TAIL_BYTES);
|
|
77419
77546
|
const buffer = new ScrollbackBuffer(this.scrollbackCapacity);
|
|
77420
77547
|
if (tail?.text)
|
|
77421
77548
|
buffer.append(dropLeadingFragment(tail));
|
|
@@ -77435,12 +77562,12 @@ class SessionManager {
|
|
|
77435
77562
|
}
|
|
77436
77563
|
diskDiagnostics(record, limit) {
|
|
77437
77564
|
const { sessionDir, info } = record;
|
|
77438
|
-
const eventLogPath =
|
|
77439
|
-
const upstreamErrorLogPath =
|
|
77440
|
-
const outputLogPath =
|
|
77565
|
+
const eventLogPath = join52(sessionDir, "events.jsonl");
|
|
77566
|
+
const upstreamErrorLogPath = join52(sessionDir, "upstream-errors.jsonl");
|
|
77567
|
+
const outputLogPath = join52(sessionDir, "output.log");
|
|
77441
77568
|
const events = readTailLines2(eventLogPath, EVENT_TAIL_BYTES);
|
|
77442
77569
|
const outputTail = readTailText(outputLogPath, OUTPUT_TAIL_BYTES);
|
|
77443
|
-
const screen = readTailText(
|
|
77570
|
+
const screen = readTailText(join52(sessionDir, "screen.txt"), SCREEN_READ_BYTES);
|
|
77444
77571
|
return {
|
|
77445
77572
|
sessionId: info.sessionId,
|
|
77446
77573
|
state: info.state,
|
|
@@ -77677,7 +77804,7 @@ function diskInfo(d) {
|
|
|
77677
77804
|
function diskCaptureSource(v) {
|
|
77678
77805
|
return v === "transcript" || v === "screen" || v === "none" ? v : null;
|
|
77679
77806
|
}
|
|
77680
|
-
var DEFAULT_MAX_SESSIONS = 20, DEFAULT_SCROLLBACK = 2000, DEFAULT_TIMEOUT = 600, MAX_TIMEOUT = 3600, TERMINAL_RETENTION_MS, MAX_TERMINAL_SESSIONS = 50, EVENT_LOG_LIMIT, WAIT_LOG_LIMIT, EVENT_RING_SIZE = 200, EVENT_PREVIEW_CHARS = 800, DEFAULT_EVENT_LIMIT = 40, UPSTREAM_ERROR_TAIL_BYTES, SPAWN_RECORD_SCHEMA = 1, NON_TOOL_ACTIVITY, META_STATUS, STATE_OF_10_4_STATUS, SESSION_ID_RE, META_READ_LIMIT, OUTPUT_TAIL_BYTES, EVENT_TAIL_BYTES, SCREEN_READ_BYTES, NO_TERMINAL_RECORD = "claudish_no_terminal_record", CLAUDISH_NOTE_PREFIX = "[claudish] ", metaString = (v) => typeof v === "string" && v.length > 0 ? v : null, optionalParent = (id) => id ? { parentClaudeSessionId: id } : {}, metaNumber = (v) => typeof v === "number" && Number.isFinite(v) ? v : null, metaReason = (v) => typeof v === "string" && FAILURE_REASONS.includes(v) ? v : null;
|
|
77807
|
+
var DEFAULT_MAX_SESSIONS = 20, DEFAULT_SCROLLBACK = 2000, DEFAULT_TIMEOUT = 600, MAX_TIMEOUT = 3600, TERMINAL_RETENTION_MS, MAX_TERMINAL_SESSIONS = 50, EVENT_LOG_LIMIT, WAIT_LOG_LIMIT, EVENT_RING_SIZE = 200, EVENT_PREVIEW_CHARS = 800, DEFAULT_EVENT_LIMIT = 40, UPSTREAM_ERROR_TAIL_BYTES, SPAWN_RECORD_SCHEMA = 1, INHERITED_SETTINGS = "inherited-settings.json", NON_TOOL_ACTIVITY, META_STATUS, STATE_OF_10_4_STATUS, SESSION_ID_RE, META_READ_LIMIT, OUTPUT_TAIL_BYTES, EVENT_TAIL_BYTES, SCREEN_READ_BYTES, NO_TERMINAL_RECORD = "claudish_no_terminal_record", CLAUDISH_NOTE_PREFIX = "[claudish] ", metaString = (v) => typeof v === "string" && v.length > 0 ? v : null, optionalParent = (id) => id ? { parentClaudeSessionId: id } : {}, metaNumber = (v) => typeof v === "number" && Number.isFinite(v) ? v : null, metaReason = (v) => typeof v === "string" && FAILURE_REASONS.includes(v) ? v : null;
|
|
77681
77808
|
var init_session_manager = __esm(() => {
|
|
77682
77809
|
init_config();
|
|
77683
77810
|
init_upstream_error_capture();
|
|
@@ -77692,6 +77819,7 @@ var init_session_manager = __esm(() => {
|
|
|
77692
77819
|
init_team_orchestrator();
|
|
77693
77820
|
init_team_stats();
|
|
77694
77821
|
init_home_dir();
|
|
77822
|
+
init_inherited_settings();
|
|
77695
77823
|
init_parent_session();
|
|
77696
77824
|
init_scrollback_buffer();
|
|
77697
77825
|
TERMINAL_RETENTION_MS = 30 * 60000;
|
|
@@ -77836,7 +77964,7 @@ var init_progress_heartbeat = __esm(() => {
|
|
|
77836
77964
|
import { spawn as spawn2 } from "child_process";
|
|
77837
77965
|
import { mkdirSync as mkdirSync23, mkdtempSync as mkdtempSync3, rmSync as rmSync10, writeFileSync as writeFileSync24 } from "fs";
|
|
77838
77966
|
import { tmpdir as tmpdir2 } from "os";
|
|
77839
|
-
import { join as
|
|
77967
|
+
import { join as join53 } from "path";
|
|
77840
77968
|
function claudeCodePrintArgv(model, systemPromptFile) {
|
|
77841
77969
|
const head = [PRINT_FLAGS[0], "--model", model, ...PRINT_FLAGS.slice(1)];
|
|
77842
77970
|
return systemPromptFile !== undefined ? [...head, "--system-prompt-file", systemPromptFile] : [...head, "--system-prompt", ""];
|
|
@@ -77954,13 +78082,13 @@ async function runPromptViaClaudeCode(model, prompt, systemPrompt, opts = {}) {
|
|
|
77954
78082
|
} catch (e) {
|
|
77955
78083
|
throw new Error(`cannot start claudish (${parentEnv.CLAUDISH_BIN?.trim() || "claudish"}): ${e instanceof Error ? e.message : String(e)}`);
|
|
77956
78084
|
}
|
|
77957
|
-
const root = mkdtempSync3(
|
|
78085
|
+
const root = mkdtempSync3(join53(tmpdir2(), "claudish-run-prompt-"));
|
|
77958
78086
|
try {
|
|
77959
|
-
const cwd =
|
|
78087
|
+
const cwd = join53(root, "cwd");
|
|
77960
78088
|
mkdirSync23(cwd, { mode: 448 });
|
|
77961
78089
|
let systemPromptFile;
|
|
77962
78090
|
if (typeof systemPrompt === "string" && systemPrompt.length > 0) {
|
|
77963
|
-
systemPromptFile =
|
|
78091
|
+
systemPromptFile = join53(root, "system-prompt.txt");
|
|
77964
78092
|
writeFileSync24(systemPromptFile, systemPrompt, { mode: 384 });
|
|
77965
78093
|
}
|
|
77966
78094
|
const argv = claudeCodePrintArgv(model, systemPromptFile);
|
|
@@ -78066,14 +78194,14 @@ var init_run_prompt_claude_code = __esm(() => {
|
|
|
78066
78194
|
});
|
|
78067
78195
|
|
|
78068
78196
|
// src/mcp-server.ts
|
|
78069
|
-
import { existsSync as
|
|
78197
|
+
import { existsSync as existsSync36, mkdirSync as mkdirSync24, readFileSync as readFileSync35, readdirSync as readdirSync9, writeFileSync as writeFileSync25 } from "fs";
|
|
78070
78198
|
import { homedir as homedir35 } from "os";
|
|
78071
|
-
import { dirname as dirname17, join as
|
|
78199
|
+
import { dirname as dirname17, join as join54, resolve as resolve8 } from "path";
|
|
78072
78200
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
78073
78201
|
async function loadAllModels(forceRefresh = false) {
|
|
78074
|
-
if (!forceRefresh &&
|
|
78202
|
+
if (!forceRefresh && existsSync36(OPENROUTER_MODELS_CACHE_PATH)) {
|
|
78075
78203
|
try {
|
|
78076
|
-
const cacheData = JSON.parse(
|
|
78204
|
+
const cacheData = JSON.parse(readFileSync35(OPENROUTER_MODELS_CACHE_PATH, "utf-8"));
|
|
78077
78205
|
const lastUpdated = new Date(cacheData.lastUpdated);
|
|
78078
78206
|
const ageInDays = (Date.now() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
|
|
78079
78207
|
if (ageInDays <= CACHE_MAX_AGE_DAYS) {
|
|
@@ -78091,8 +78219,8 @@ async function loadAllModels(forceRefresh = false) {
|
|
|
78091
78219
|
writeFileSync25(OPENROUTER_MODELS_CACHE_PATH, JSON.stringify({ lastUpdated: new Date().toISOString(), models }), "utf-8");
|
|
78092
78220
|
return models;
|
|
78093
78221
|
} catch {
|
|
78094
|
-
if (
|
|
78095
|
-
const cacheData = JSON.parse(
|
|
78222
|
+
if (existsSync36(OPENROUTER_MODELS_CACHE_PATH)) {
|
|
78223
|
+
const cacheData = JSON.parse(readFileSync35(OPENROUTER_MODELS_CACHE_PATH, "utf-8"));
|
|
78096
78224
|
return cacheData.models || [];
|
|
78097
78225
|
}
|
|
78098
78226
|
return [];
|
|
@@ -78908,8 +79036,8 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
78908
79036
|
const promptText = () => {
|
|
78909
79037
|
if (input !== undefined)
|
|
78910
79038
|
return input;
|
|
78911
|
-
const existing =
|
|
78912
|
-
return
|
|
79039
|
+
const existing = join54(resolved, "input.md");
|
|
79040
|
+
return existsSync36(existing) ? readFileSync35(existing, "utf-8") : undefined;
|
|
78913
79041
|
};
|
|
78914
79042
|
switch (mode) {
|
|
78915
79043
|
case "run": {
|
|
@@ -79059,7 +79187,7 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
79059
79187
|
let stderrFull = stderr_snippet || "";
|
|
79060
79188
|
if (error_log_path) {
|
|
79061
79189
|
try {
|
|
79062
|
-
stderrFull =
|
|
79190
|
+
stderrFull = readFileSync35(error_log_path, "utf-8");
|
|
79063
79191
|
} catch {}
|
|
79064
79192
|
}
|
|
79065
79193
|
const sessionData = {};
|
|
@@ -79067,16 +79195,16 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
79067
79195
|
const sp = session_path;
|
|
79068
79196
|
for (const file of ["status.json", "manifest.json", "input.md"]) {
|
|
79069
79197
|
try {
|
|
79070
|
-
sessionData[file] =
|
|
79198
|
+
sessionData[file] = readFileSync35(join54(sp, file), "utf-8");
|
|
79071
79199
|
} catch {}
|
|
79072
79200
|
}
|
|
79073
79201
|
try {
|
|
79074
|
-
const errorDir =
|
|
79075
|
-
if (
|
|
79202
|
+
const errorDir = join54(sp, "errors");
|
|
79203
|
+
if (existsSync36(errorDir)) {
|
|
79076
79204
|
for (const f of readdirSync9(errorDir)) {
|
|
79077
79205
|
if (f.endsWith(".log")) {
|
|
79078
79206
|
try {
|
|
79079
|
-
sessionData[`errors/${f}`] =
|
|
79207
|
+
sessionData[`errors/${f}`] = readFileSync35(join54(errorDir, f), "utf-8");
|
|
79080
79208
|
} catch {}
|
|
79081
79209
|
}
|
|
79082
79210
|
}
|
|
@@ -79086,7 +79214,7 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
79086
79214
|
for (const f of readdirSync9(sp)) {
|
|
79087
79215
|
if (f.startsWith("response-") && f.endsWith(".md")) {
|
|
79088
79216
|
try {
|
|
79089
|
-
const content =
|
|
79217
|
+
const content = readFileSync35(join54(sp, f), "utf-8");
|
|
79090
79218
|
sessionData[f] = content.slice(0, 200) + (content.length > 200 ? "... (truncated)" : "");
|
|
79091
79219
|
} catch {}
|
|
79092
79220
|
}
|
|
@@ -79095,9 +79223,9 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
79095
79223
|
}
|
|
79096
79224
|
let version = "unknown";
|
|
79097
79225
|
try {
|
|
79098
|
-
const pkgPath =
|
|
79099
|
-
if (
|
|
79100
|
-
version = JSON.parse(
|
|
79226
|
+
const pkgPath = join54(__dirname3, "../package.json");
|
|
79227
|
+
if (existsSync36(pkgPath)) {
|
|
79228
|
+
version = JSON.parse(readFileSync35(pkgPath, "utf-8")).version;
|
|
79101
79229
|
}
|
|
79102
79230
|
} catch {}
|
|
79103
79231
|
const report = {
|
|
@@ -79204,6 +79332,10 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
79204
79332
|
work_dir: {
|
|
79205
79333
|
type: "string",
|
|
79206
79334
|
description: "Working directory for the session (default: current directory)"
|
|
79335
|
+
},
|
|
79336
|
+
setup_from: {
|
|
79337
|
+
type: ["string", "null"],
|
|
79338
|
+
description: "Directory whose .claude/settings.json and settings.local.json the session " + "inherits (enabled plugins, permissions, env), so a session in another work_dir " + "keeps the caller's plugins and agents; an explicit path must be an existing " + "directory. Default: the caller's project directory, " + "when work_dir differs from it. null keeps the session on work_dir's own settings only."
|
|
79207
79339
|
}
|
|
79208
79340
|
},
|
|
79209
79341
|
required: ["model"]
|
|
@@ -79219,7 +79351,7 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
79219
79351
|
const requestedModel = args.model;
|
|
79220
79352
|
const workDir = args.work_dir;
|
|
79221
79353
|
const plan = await prehydrateCredentialsForSpawn([requestedModel], {
|
|
79222
|
-
pin: workDir === undefined ||
|
|
79354
|
+
pin: workDir === undefined || resolve8(workDir) === process.cwd()
|
|
79223
79355
|
});
|
|
79224
79356
|
const parentClaudeSessionId = await parentSessionForCall({
|
|
79225
79357
|
hostPid: sessionManager.hostPid
|
|
@@ -79231,6 +79363,7 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
79231
79363
|
timeoutSeconds: args.timeout_seconds,
|
|
79232
79364
|
claudishFlags,
|
|
79233
79365
|
cwd: workDir,
|
|
79366
|
+
setupFrom: resolveSetupFrom(args.setup_from, workDir, process.cwd()),
|
|
79234
79367
|
parentClaudeSessionId
|
|
79235
79368
|
});
|
|
79236
79369
|
return {
|
|
@@ -79620,6 +79753,7 @@ var init_mcp_server = __esm(() => {
|
|
|
79620
79753
|
init_output_capture();
|
|
79621
79754
|
init_logger();
|
|
79622
79755
|
init_mcp_session();
|
|
79756
|
+
init_inherited_settings();
|
|
79623
79757
|
init_parent_session();
|
|
79624
79758
|
init_nested_mode();
|
|
79625
79759
|
init_progress_heartbeat();
|
|
@@ -79640,8 +79774,8 @@ var init_mcp_server = __esm(() => {
|
|
|
79640
79774
|
init_team_orchestrator();
|
|
79641
79775
|
__filename3 = fileURLToPath3(import.meta.url);
|
|
79642
79776
|
__dirname3 = dirname17(__filename3);
|
|
79643
|
-
CLAUDISH_CACHE_DIR =
|
|
79644
|
-
OPENROUTER_MODELS_CACHE_PATH =
|
|
79777
|
+
CLAUDISH_CACHE_DIR = join54(homedir35(), ".claudish");
|
|
79778
|
+
OPENROUTER_MODELS_CACHE_PATH = join54(CLAUDISH_CACHE_DIR, "openrouter-models.json");
|
|
79645
79779
|
NEXT_STEP = {
|
|
79646
79780
|
cancelled: "you stopped this slot; nothing is wrong with it. Re-run it if you still want its vote",
|
|
79647
79781
|
timeout: "grid mode only \u2014 magmux ended the pane. The orchestrator has no deadline",
|
|
@@ -79664,7 +79798,7 @@ var init_mcp_server = __esm(() => {
|
|
|
79664
79798
|
});
|
|
79665
79799
|
|
|
79666
79800
|
// src/serve-command.ts
|
|
79667
|
-
import { existsSync as
|
|
79801
|
+
import { existsSync as existsSync37, readFileSync as readFileSync36 } from "fs";
|
|
79668
79802
|
function parseServeArgs(args) {
|
|
79669
79803
|
const out = {};
|
|
79670
79804
|
for (let i = 0;i < args.length; i++) {
|
|
@@ -79683,12 +79817,12 @@ function parseServeArgs(args) {
|
|
|
79683
79817
|
return out;
|
|
79684
79818
|
}
|
|
79685
79819
|
function loadModelMap(path) {
|
|
79686
|
-
if (!
|
|
79820
|
+
if (!existsSync37(path)) {
|
|
79687
79821
|
throw new Error(`--models file not found: ${path}`);
|
|
79688
79822
|
}
|
|
79689
79823
|
let raw;
|
|
79690
79824
|
try {
|
|
79691
|
-
raw =
|
|
79825
|
+
raw = readFileSync36(path, "utf-8");
|
|
79692
79826
|
} catch (e) {
|
|
79693
79827
|
throw new Error(`failed to read --models file ${path}: ${e instanceof Error ? e.message : String(e)}`);
|
|
79694
79828
|
}
|
|
@@ -79769,9 +79903,9 @@ var init_serve_command = __esm(() => {
|
|
|
79769
79903
|
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';
|
|
79770
79904
|
|
|
79771
79905
|
// src/hooks/observer/corpus.ts
|
|
79772
|
-
import { appendFileSync as appendFileSync8, readFileSync as
|
|
79906
|
+
import { appendFileSync as appendFileSync8, readFileSync as readFileSync37, readdirSync as readdirSync10, statSync as statSync15 } from "fs";
|
|
79773
79907
|
import { homedir as homedir36 } from "os";
|
|
79774
|
-
import { join as
|
|
79908
|
+
import { join as join55 } from "path";
|
|
79775
79909
|
function directoryOf2(filePath) {
|
|
79776
79910
|
const slash = filePath.lastIndexOf("/");
|
|
79777
79911
|
return slash > 0 ? filePath.slice(0, slash) : undefined;
|
|
@@ -79793,7 +79927,7 @@ function writeTargetsOf(row) {
|
|
|
79793
79927
|
function replayTranscript(file) {
|
|
79794
79928
|
let text;
|
|
79795
79929
|
try {
|
|
79796
|
-
text =
|
|
79930
|
+
text = readFileSync37(file, "utf8");
|
|
79797
79931
|
} catch {
|
|
79798
79932
|
return [];
|
|
79799
79933
|
}
|
|
@@ -79850,26 +79984,26 @@ function listTranscripts(root) {
|
|
|
79850
79984
|
return files;
|
|
79851
79985
|
}
|
|
79852
79986
|
for (const project of projects) {
|
|
79853
|
-
const dir =
|
|
79987
|
+
const dir = join55(root, project);
|
|
79854
79988
|
try {
|
|
79855
|
-
if (!
|
|
79989
|
+
if (!statSync15(dir).isDirectory())
|
|
79856
79990
|
continue;
|
|
79857
79991
|
for (const f of readdirSync10(dir)) {
|
|
79858
79992
|
if (f.endsWith(".jsonl"))
|
|
79859
|
-
files.push(
|
|
79993
|
+
files.push(join55(dir, f));
|
|
79860
79994
|
}
|
|
79861
79995
|
} catch {}
|
|
79862
79996
|
}
|
|
79863
79997
|
return files;
|
|
79864
79998
|
}
|
|
79865
79999
|
function buildCorpus(options = {}) {
|
|
79866
|
-
const root = options.projectsRoot ??
|
|
80000
|
+
const root = options.projectsRoot ?? join55(homedir36(), ".claude", "projects");
|
|
79867
80001
|
const files = listTranscripts(root);
|
|
79868
80002
|
const records = [];
|
|
79869
80003
|
for (const f of files)
|
|
79870
80004
|
records.push(...replayTranscript(f));
|
|
79871
80005
|
if (options.write && records.length > 0) {
|
|
79872
|
-
const outputPath = options.outputPath ??
|
|
80006
|
+
const outputPath = options.outputPath ?? join55(homedir36(), ".claudish", "behavior-divergences.jsonl");
|
|
79873
80007
|
try {
|
|
79874
80008
|
appendFileSync8(outputPath, `${records.map((r) => JSON.stringify(r)).join(`
|
|
79875
80009
|
`)}
|
|
@@ -79885,9 +80019,9 @@ var init_corpus = __esm(() => {
|
|
|
79885
80019
|
});
|
|
79886
80020
|
|
|
79887
80021
|
// src/hooks-command.ts
|
|
79888
|
-
import { existsSync as
|
|
80022
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync25, readFileSync as readFileSync38, writeFileSync as writeFileSync26 } from "fs";
|
|
79889
80023
|
import { homedir as homedir37 } from "os";
|
|
79890
|
-
import { join as
|
|
80024
|
+
import { join as join56, resolve as resolve9 } from "path";
|
|
79891
80025
|
function severityColor(sev) {
|
|
79892
80026
|
if (sev === "fix")
|
|
79893
80027
|
return green(sev);
|
|
@@ -79977,7 +80111,7 @@ async function check(file, json) {
|
|
|
79977
80111
|
console.error("Usage: claudish hooks check <file> [--json]");
|
|
79978
80112
|
return 1;
|
|
79979
80113
|
}
|
|
79980
|
-
const path =
|
|
80114
|
+
const path = resolve9(process.cwd(), file);
|
|
79981
80115
|
const notes = [];
|
|
79982
80116
|
const loaded = await loadUserHooks({
|
|
79983
80117
|
modules: [path],
|
|
@@ -80010,12 +80144,12 @@ async function check(file, json) {
|
|
|
80010
80144
|
return valid ? 0 : 1;
|
|
80011
80145
|
}
|
|
80012
80146
|
function init(dirArg) {
|
|
80013
|
-
const dir = dirArg ?
|
|
80147
|
+
const dir = dirArg ? resolve9(process.cwd(), dirArg) : join56(homedir37(), ".claudish", "hooks");
|
|
80014
80148
|
const files = [
|
|
80015
|
-
[
|
|
80016
|
-
[
|
|
80149
|
+
[join56(dir, "example-hook.ts"), EXAMPLE_HOOK],
|
|
80150
|
+
[join56(dir, "claudish-hooks.d.ts"), HOOKS_AMBIENT_DTS]
|
|
80017
80151
|
];
|
|
80018
|
-
const existing = files.filter(([path]) =>
|
|
80152
|
+
const existing = files.filter(([path]) => existsSync38(path)).map(([path]) => path);
|
|
80019
80153
|
if (existing.length > 0) {
|
|
80020
80154
|
for (const path of existing)
|
|
80021
80155
|
console.error(`${path} already exists; not overwriting it.`);
|
|
@@ -80088,8 +80222,8 @@ function setTelemetryEnabled(value) {
|
|
|
80088
80222
|
const path = activeConfigFile();
|
|
80089
80223
|
let cfg = {};
|
|
80090
80224
|
try {
|
|
80091
|
-
if (
|
|
80092
|
-
const parsed = JSON.parse(
|
|
80225
|
+
if (existsSync38(path)) {
|
|
80226
|
+
const parsed = JSON.parse(readFileSync38(path, "utf-8"));
|
|
80093
80227
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
80094
80228
|
cfg = parsed;
|
|
80095
80229
|
}
|
|
@@ -80108,8 +80242,8 @@ function telemetry(action, json) {
|
|
|
80108
80242
|
let pending = 0;
|
|
80109
80243
|
try {
|
|
80110
80244
|
const path = outboxPath();
|
|
80111
|
-
if (
|
|
80112
|
-
pending =
|
|
80245
|
+
if (existsSync38(path))
|
|
80246
|
+
pending = readFileSync38(path, "utf8").split(`
|
|
80113
80247
|
`).filter(Boolean).length;
|
|
80114
80248
|
} catch {}
|
|
80115
80249
|
if (json) {
|
|
@@ -80216,9 +80350,9 @@ var init_hooks_command = __esm(() => {
|
|
|
80216
80350
|
|
|
80217
80351
|
// src/team-grid.ts
|
|
80218
80352
|
import { spawn as spawn3 } from "child_process";
|
|
80219
|
-
import { existsSync as
|
|
80353
|
+
import { existsSync as existsSync39, readFileSync as readFileSync39, writeFileSync as writeFileSync27 } from "fs";
|
|
80220
80354
|
import { connect as netConnect2 } from "net";
|
|
80221
|
-
import { join as
|
|
80355
|
+
import { join as join57 } from "path";
|
|
80222
80356
|
import { setTimeout as wait } from "timers/promises";
|
|
80223
80357
|
function paneRouteLine(explanation) {
|
|
80224
80358
|
const origin = describeRouteExplanation(explanation);
|
|
@@ -80273,7 +80407,7 @@ function withoutControlPanes(evt) {
|
|
|
80273
80407
|
async function subscribeToMagmux(sockPath, onEvent) {
|
|
80274
80408
|
let client = null;
|
|
80275
80409
|
for (let attempt = 0;attempt < 40; attempt++) {
|
|
80276
|
-
if (
|
|
80410
|
+
if (existsSync39(sockPath)) {
|
|
80277
80411
|
try {
|
|
80278
80412
|
client = await new Promise((resolve, reject) => {
|
|
80279
80413
|
const s = netConnect2(sockPath);
|
|
@@ -80368,9 +80502,9 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
80368
80502
|
const keep = opts?.keep ?? false;
|
|
80369
80503
|
const manifest = setupSession(sessionPath, models, input);
|
|
80370
80504
|
const startedAt = new Date().toISOString();
|
|
80371
|
-
const gridfilePath =
|
|
80372
|
-
const prompt =
|
|
80373
|
-
const rawPrompt =
|
|
80505
|
+
const gridfilePath = join57(sessionPath, "gridfile.txt");
|
|
80506
|
+
const prompt = readFileSync39(join57(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''").replace(/\n/g, " ");
|
|
80507
|
+
const rawPrompt = readFileSync39(join57(sessionPath, "input.md"), "utf-8");
|
|
80374
80508
|
const usedBannerColors = new Set;
|
|
80375
80509
|
const routeLines = mode === "interactive" ? new Map : await resolvePaneRouteLines(Object.values(manifest.models).map((entry) => entry.model));
|
|
80376
80510
|
const gridLines = Object.entries(manifest.models).map(([anonId]) => {
|
|
@@ -80402,7 +80536,7 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
80402
80536
|
});
|
|
80403
80537
|
const [{ results }] = await Promise.all([subscription, procExit]);
|
|
80404
80538
|
const status = buildTeamStatus(manifest, startedAt, results?.panes ?? null);
|
|
80405
|
-
const statusPath =
|
|
80539
|
+
const statusPath = join57(sessionPath, "status.json");
|
|
80406
80540
|
writeFileSync27(statusPath, JSON.stringify(status, null, 2), "utf-8");
|
|
80407
80541
|
return status;
|
|
80408
80542
|
}
|
|
@@ -80422,8 +80556,8 @@ var init_team_grid = __esm(() => {
|
|
|
80422
80556
|
});
|
|
80423
80557
|
|
|
80424
80558
|
// src/team-cli.ts
|
|
80425
|
-
import { readFileSync as
|
|
80426
|
-
import { join as
|
|
80559
|
+
import { readFileSync as readFileSync40 } from "fs";
|
|
80560
|
+
import { join as join58 } from "path";
|
|
80427
80561
|
async function runPaneTeam(sessionPath, models, input, opts) {
|
|
80428
80562
|
installPaneShutdownHooks({ exitAfter: true });
|
|
80429
80563
|
try {
|
|
@@ -80568,7 +80702,7 @@ async function teamCommand(args) {
|
|
|
80568
80702
|
}
|
|
80569
80703
|
case "judge": {
|
|
80570
80704
|
await judgeResponses(sessionPath, { judges });
|
|
80571
|
-
console.log(
|
|
80705
|
+
console.log(readFileSync40(join58(sessionPath, "verdict.md"), "utf-8"));
|
|
80572
80706
|
break;
|
|
80573
80707
|
}
|
|
80574
80708
|
case "run-and-judge": {
|
|
@@ -80584,7 +80718,7 @@ async function teamCommand(args) {
|
|
|
80584
80718
|
});
|
|
80585
80719
|
printStatus(status);
|
|
80586
80720
|
await judgeResponses(sessionPath, { judges });
|
|
80587
|
-
console.log(
|
|
80721
|
+
console.log(readFileSync40(join58(sessionPath, "verdict.md"), "utf-8"));
|
|
80588
80722
|
break;
|
|
80589
80723
|
}
|
|
80590
80724
|
case "status": {
|
|
@@ -81539,9 +81673,9 @@ var init_subscription_models_command = __esm(() => {
|
|
|
81539
81673
|
|
|
81540
81674
|
// src/auth/antigravity-oauth.ts
|
|
81541
81675
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
81542
|
-
import { existsSync as
|
|
81676
|
+
import { existsSync as existsSync40, unlinkSync as unlinkSync9 } from "fs";
|
|
81543
81677
|
import { homedir as homedir38 } from "os";
|
|
81544
|
-
import { join as
|
|
81678
|
+
import { join as join59 } from "path";
|
|
81545
81679
|
async function defaultSuggestModel() {
|
|
81546
81680
|
try {
|
|
81547
81681
|
const token = await getValidAntigravityAccessToken();
|
|
@@ -81660,8 +81794,8 @@ No session detected yet. Starting the Antigravity CLI interactively \u2014
|
|
|
81660
81794
|
async logout(deps) {
|
|
81661
81795
|
deleteSharedAntigravityToken(deps);
|
|
81662
81796
|
try {
|
|
81663
|
-
const tokenFile =
|
|
81664
|
-
if (
|
|
81797
|
+
const tokenFile = join59(homedir38(), ".gemini", "antigravity-cli", "antigravity-oauth-token");
|
|
81798
|
+
if (existsSync40(tokenFile))
|
|
81665
81799
|
unlinkSync9(tokenFile);
|
|
81666
81800
|
} catch {}
|
|
81667
81801
|
log("[AntigravityOAuth] Antigravity session cleared (keychain + agy token file)");
|
|
@@ -89807,8 +89941,8 @@ var init_own_pane = __esm(() => {
|
|
|
89807
89941
|
});
|
|
89808
89942
|
|
|
89809
89943
|
// src/hooks/session/interactive-driver.ts
|
|
89810
|
-
import { existsSync as
|
|
89811
|
-
import { join as
|
|
89944
|
+
import { existsSync as existsSync41, statSync as statSync16 } from "fs";
|
|
89945
|
+
import { join as join60 } from "path";
|
|
89812
89946
|
function nextDriverPhase(phase, ev) {
|
|
89813
89947
|
const row = EDGES[phase];
|
|
89814
89948
|
return row[ev] ?? null;
|
|
@@ -90026,7 +90160,7 @@ class InteractiveDriver {
|
|
|
90026
90160
|
}
|
|
90027
90161
|
follow(sid, offset) {
|
|
90028
90162
|
const path = transcriptPathFor(this.o.cwd, sid, this.o.projectsRoot);
|
|
90029
|
-
this.follower = new TranscriptFollower(path,
|
|
90163
|
+
this.follower = new TranscriptFollower(path, join60(path.replace(/\.jsonl$/, ""), "subagents"));
|
|
90030
90164
|
this.sessionId = sid;
|
|
90031
90165
|
this.settledTurn = null;
|
|
90032
90166
|
this.lastPollAt = Date.now();
|
|
@@ -90047,7 +90181,7 @@ class InteractiveDriver {
|
|
|
90047
90181
|
if (!p)
|
|
90048
90182
|
return;
|
|
90049
90183
|
const path = transcriptPathFor(this.o.cwd, p.id, this.o.projectsRoot);
|
|
90050
|
-
if (!
|
|
90184
|
+
if (!existsSync41(path)) {
|
|
90051
90185
|
if (Date.now() - p.since > RETARGET_WAIT_MS) {
|
|
90052
90186
|
log(`[hooks] interactive driver: no transcript for session ${p.id}; not following it`);
|
|
90053
90187
|
this.pendingSid = null;
|
|
@@ -90571,7 +90705,7 @@ function assertNeverPhase(p) {
|
|
|
90571
90705
|
}
|
|
90572
90706
|
function fileSizeOf(path) {
|
|
90573
90707
|
try {
|
|
90574
|
-
return
|
|
90708
|
+
return statSync16(path).size;
|
|
90575
90709
|
} catch {
|
|
90576
90710
|
return 0;
|
|
90577
90711
|
}
|
|
@@ -90716,14 +90850,14 @@ var init_no_surface = __esm(() => {
|
|
|
90716
90850
|
var UI_LEASE_MS = 1e4, FRAME_TICK_MS = 1000;
|
|
90717
90851
|
|
|
90718
90852
|
// src/recovery/magmux-ui.ts
|
|
90719
|
-
import { existsSync as
|
|
90853
|
+
import { existsSync as existsSync42 } from "fs";
|
|
90720
90854
|
import { connect as netConnect3 } from "net";
|
|
90721
90855
|
function resolveControlEndpoint() {
|
|
90722
|
-
if (explicitControlSock &&
|
|
90856
|
+
if (explicitControlSock && existsSync42(explicitControlSock)) {
|
|
90723
90857
|
return { sock: explicitControlSock, wrapped: true };
|
|
90724
90858
|
}
|
|
90725
90859
|
const ambient = process.env.MAGMUX_SOCK;
|
|
90726
|
-
if (ambient &&
|
|
90860
|
+
if (ambient && existsSync42(ambient))
|
|
90727
90861
|
return { sock: ambient, wrapped: false };
|
|
90728
90862
|
return null;
|
|
90729
90863
|
}
|
|
@@ -91129,19 +91263,19 @@ import { randomUUID as randomUUID8 } from "crypto";
|
|
|
91129
91263
|
import {
|
|
91130
91264
|
chmodSync as chmodSync4,
|
|
91131
91265
|
closeSync as closeSync12,
|
|
91132
|
-
existsSync as
|
|
91266
|
+
existsSync as existsSync43,
|
|
91133
91267
|
mkdirSync as mkdirSync26,
|
|
91134
91268
|
mkdtempSync as mkdtempSync4,
|
|
91135
91269
|
openSync as openSync12,
|
|
91136
|
-
readFileSync as
|
|
91270
|
+
readFileSync as readFileSync41,
|
|
91137
91271
|
readdirSync as readdirSync11,
|
|
91138
91272
|
rmSync as rmSync11,
|
|
91139
|
-
statSync as
|
|
91273
|
+
statSync as statSync17,
|
|
91140
91274
|
unlinkSync as unlinkSync10,
|
|
91141
91275
|
writeFileSync as writeFileSync28
|
|
91142
91276
|
} from "fs";
|
|
91143
91277
|
import { homedir as homedir39, tmpdir as tmpdir3 } from "os";
|
|
91144
|
-
import { dirname as dirname18, join as
|
|
91278
|
+
import { dirname as dirname18, join as join61 } from "path";
|
|
91145
91279
|
import { isatty } from "tty";
|
|
91146
91280
|
function releaseTerminalIsolation() {
|
|
91147
91281
|
if (!restoreTerminal)
|
|
@@ -91208,12 +91342,12 @@ function isRealAnthropicEnvCredential(env, name) {
|
|
|
91208
91342
|
}
|
|
91209
91343
|
function hasResolvableAnthropicAuth(deps = {}) {
|
|
91210
91344
|
const env = deps.env ?? process.env;
|
|
91211
|
-
const fileExists = deps.fileExists ??
|
|
91345
|
+
const fileExists = deps.fileExists ?? existsSync43;
|
|
91212
91346
|
const keychainProbe = deps.keychainProbe ?? defaultKeychainAnthropicProbe;
|
|
91213
91347
|
if (isRealAnthropicEnvCredential(env, "ANTHROPIC_API_KEY") || isRealAnthropicEnvCredential(env, "ANTHROPIC_AUTH_TOKEN")) {
|
|
91214
91348
|
return true;
|
|
91215
91349
|
}
|
|
91216
|
-
if (fileExists(
|
|
91350
|
+
if (fileExists(join61(homedir39(), ".claude", ".credentials.json")))
|
|
91217
91351
|
return true;
|
|
91218
91352
|
return keychainProbe();
|
|
91219
91353
|
}
|
|
@@ -91228,14 +91362,14 @@ function isProxyAuthMode(config) {
|
|
|
91228
91362
|
}
|
|
91229
91363
|
function managedSettingsPath() {
|
|
91230
91364
|
if (isWindows2()) {
|
|
91231
|
-
return
|
|
91365
|
+
return join61(process.env.PROGRAMDATA || "C:\\ProgramData", "ClaudeCode", "managed-settings.json");
|
|
91232
91366
|
}
|
|
91233
91367
|
if (process.platform === "darwin") {
|
|
91234
91368
|
return "/Library/Application Support/ClaudeCode/managed-settings.json";
|
|
91235
91369
|
}
|
|
91236
91370
|
return "/etc/claude-code/managed-settings.json";
|
|
91237
91371
|
}
|
|
91238
|
-
function managedSettingsForcesClaudeAi(readFile =
|
|
91372
|
+
function managedSettingsForcesClaudeAi(readFile = readFileSync41) {
|
|
91239
91373
|
try {
|
|
91240
91374
|
const raw = readFile(managedSettingsPath(), "utf-8");
|
|
91241
91375
|
const parsed = JSON.parse(raw);
|
|
@@ -91249,9 +91383,9 @@ function isWindows2() {
|
|
|
91249
91383
|
}
|
|
91250
91384
|
function createStatusLineScript(tokenFilePath) {
|
|
91251
91385
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir3();
|
|
91252
|
-
const claudishDir =
|
|
91386
|
+
const claudishDir = join61(homeDir, ".claudish");
|
|
91253
91387
|
const timestamp = Date.now();
|
|
91254
|
-
const scriptPath =
|
|
91388
|
+
const scriptPath = join61(claudishDir, `status-${timestamp}.js`);
|
|
91255
91389
|
const escapedTokenPath = tokenFilePath.replace(/\\/g, "\\\\");
|
|
91256
91390
|
const light = getThemeMode() === "light";
|
|
91257
91391
|
const cyanCode = light ? "38;2;14;116;144" : "96";
|
|
@@ -91421,9 +91555,9 @@ function cleanupStaleTokenFiles(dir, now = Date.now(), maxAgeMs = STALE_TOKEN_FI
|
|
|
91421
91555
|
if (!name.startsWith("tokens-") || !name.endsWith(".json"))
|
|
91422
91556
|
continue;
|
|
91423
91557
|
scanned++;
|
|
91424
|
-
const full =
|
|
91558
|
+
const full = join61(dir, name);
|
|
91425
91559
|
try {
|
|
91426
|
-
if (
|
|
91560
|
+
if (statSync17(full).mtimeMs >= cutoff)
|
|
91427
91561
|
continue;
|
|
91428
91562
|
unlinkSync10(full);
|
|
91429
91563
|
removed++;
|
|
@@ -91438,7 +91572,7 @@ function parseSettingsArg(value) {
|
|
|
91438
91572
|
if (value.trimStart().startsWith("{")) {
|
|
91439
91573
|
return JSON.parse(value);
|
|
91440
91574
|
}
|
|
91441
|
-
return JSON.parse(
|
|
91575
|
+
return JSON.parse(readFileSync41(value, "utf-8"));
|
|
91442
91576
|
}
|
|
91443
91577
|
function parseSettingsArgSafe(value) {
|
|
91444
91578
|
try {
|
|
@@ -91450,13 +91584,13 @@ function parseSettingsArgSafe(value) {
|
|
|
91450
91584
|
}
|
|
91451
91585
|
function userSettingsFileCandidates(cwd) {
|
|
91452
91586
|
return [
|
|
91453
|
-
|
|
91454
|
-
|
|
91455
|
-
|
|
91587
|
+
join61(homedir39(), ".claude", "settings.json"),
|
|
91588
|
+
join61(cwd, ".claude", "settings.json"),
|
|
91589
|
+
join61(cwd, ".claude", "settings.local.json")
|
|
91456
91590
|
];
|
|
91457
91591
|
}
|
|
91458
91592
|
function discoverUserStatusLineCommand(claudeArgs = [], cwd = process.cwd()) {
|
|
91459
|
-
const sources = userSettingsFileCandidates(cwd).filter((file) =>
|
|
91593
|
+
const sources = userSettingsFileCandidates(cwd).filter((file) => existsSync43(file));
|
|
91460
91594
|
const idx = claudeArgs.indexOf("--settings");
|
|
91461
91595
|
const settingsArg = idx === -1 ? undefined : claudeArgs[idx + 1];
|
|
91462
91596
|
if (settingsArg)
|
|
@@ -91493,12 +91627,12 @@ function buildChainedStatusCommand(userCommand, claudishBody, claudishSegment) {
|
|
|
91493
91627
|
}
|
|
91494
91628
|
function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLineCommand) {
|
|
91495
91629
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir3();
|
|
91496
|
-
const claudishDir =
|
|
91630
|
+
const claudishDir = join61(homeDir, ".claudish");
|
|
91497
91631
|
try {
|
|
91498
91632
|
mkdirSync26(claudishDir, { recursive: true });
|
|
91499
91633
|
} catch {}
|
|
91500
91634
|
const timestamp = Date.now();
|
|
91501
|
-
const tempPath =
|
|
91635
|
+
const tempPath = join61(claudishDir, `settings-${timestamp}.json`);
|
|
91502
91636
|
const assignedFile = assignedTokenFile(process.env) !== null;
|
|
91503
91637
|
const tokenFilePath = resolveTokenFilePath(port);
|
|
91504
91638
|
cleanupStaleTokenFiles(claudishDir);
|
|
@@ -91589,13 +91723,15 @@ function mergeUserSettingsIfPresent(config, tempSettingsPath, statusLine, proxyA
|
|
|
91589
91723
|
async function resolveLocalContextWindow(spec, cachePath) {
|
|
91590
91724
|
const parsed = parseModelSpec(spec);
|
|
91591
91725
|
let provider = parsed.provider;
|
|
91726
|
+
let wireId = parsed.model;
|
|
91592
91727
|
if (!parsed.isExplicitProvider) {
|
|
91593
91728
|
const plan = await route(spec);
|
|
91594
91729
|
if (plan.kind !== "ok")
|
|
91595
91730
|
return null;
|
|
91596
91731
|
provider = plan.primary.provider;
|
|
91732
|
+
wireId = parseModelSpec(plan.primary.modelSpec).model;
|
|
91597
91733
|
}
|
|
91598
|
-
const win = await discoverContextWindow(provider, parsed.model) ??
|
|
91734
|
+
const win = await discoverContextWindow(provider, wireId) ?? lookupModelForProvider(parsed.model, provider, cachePath) ?? (wireId !== parsed.model ? lookupModelForProvider(wireId, provider, cachePath) : null);
|
|
91599
91735
|
return {
|
|
91600
91736
|
modelId: parsed.model,
|
|
91601
91737
|
window: typeof win === "number" && win > 0 ? win : null
|
|
@@ -91649,13 +91785,13 @@ function resolveAdvisorToolEnv(config, processEnv = process.env) {
|
|
|
91649
91785
|
return { vars: { [ADVISOR_TOOL_ENV_VAR]: "1" }, source: "claudish" };
|
|
91650
91786
|
}
|
|
91651
91787
|
function discoverUserAdvisorModel(claudeArgs = [], cwd = process.cwd()) {
|
|
91652
|
-
const sources = userSettingsFileCandidates(cwd).filter((file) =>
|
|
91788
|
+
const sources = userSettingsFileCandidates(cwd).filter((file) => existsSync43(file));
|
|
91653
91789
|
const idx = claudeArgs.indexOf("--settings");
|
|
91654
91790
|
const settingsArg = idx === -1 ? undefined : claudeArgs[idx + 1];
|
|
91655
91791
|
if (settingsArg)
|
|
91656
91792
|
sources.push(settingsArg);
|
|
91657
91793
|
const managed = managedSettingsPath();
|
|
91658
|
-
if (
|
|
91794
|
+
if (existsSync43(managed))
|
|
91659
91795
|
sources.push(managed);
|
|
91660
91796
|
let effective;
|
|
91661
91797
|
for (const source of sources) {
|
|
@@ -91876,7 +92012,7 @@ async function runClaudeWithProxy(config, proxyUrl, onCleanup) {
|
|
|
91876
92012
|
console.error(`
|
|
91877
92013
|
Or set CLAUDE_PATH to your custom installation:`);
|
|
91878
92014
|
const home = homedir39();
|
|
91879
|
-
const localPath = isWindows2() ?
|
|
92015
|
+
const localPath = isWindows2() ? join61(home, ".claude", "local", "claude.exe") : join61(home, ".claude", "local", "claude");
|
|
91880
92016
|
console.error(` export CLAUDE_PATH=${localPath}`);
|
|
91881
92017
|
process.exit(1);
|
|
91882
92018
|
}
|
|
@@ -91911,7 +92047,7 @@ Or set CLAUDE_PATH to your custom installation:`);
|
|
|
91911
92047
|
let driverLaunch = null;
|
|
91912
92048
|
if (surfaces.driver) {
|
|
91913
92049
|
const minted = sessionFlags.sessionId || sessionFlags.resumes ? null : randomUUID8();
|
|
91914
|
-
const turnDir = mkdtempSync4(
|
|
92050
|
+
const turnDir = mkdtempSync4(join61(tmpdir3(), "claudish-turns-"));
|
|
91915
92051
|
chmodSync4(turnDir, 448);
|
|
91916
92052
|
claudeArgs.unshift(...driverLeadingArgs({ mintedSessionId: minted, turnDir }));
|
|
91917
92053
|
const sink = new InProcessSink;
|
|
@@ -92055,23 +92191,23 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
|
|
|
92055
92191
|
async function findClaudeBinary() {
|
|
92056
92192
|
const isWindows = process.platform === "win32";
|
|
92057
92193
|
if (process.env.CLAUDE_PATH) {
|
|
92058
|
-
if (
|
|
92194
|
+
if (existsSync43(process.env.CLAUDE_PATH)) {
|
|
92059
92195
|
return process.env.CLAUDE_PATH;
|
|
92060
92196
|
}
|
|
92061
92197
|
}
|
|
92062
92198
|
const home = homedir39();
|
|
92063
|
-
const localPath = isWindows ?
|
|
92064
|
-
if (
|
|
92199
|
+
const localPath = isWindows ? join61(home, ".claude", "local", "claude.exe") : join61(home, ".claude", "local", "claude");
|
|
92200
|
+
if (existsSync43(localPath)) {
|
|
92065
92201
|
return localPath;
|
|
92066
92202
|
}
|
|
92067
92203
|
if (isWindows) {
|
|
92068
92204
|
const windowsPaths = [
|
|
92069
|
-
|
|
92070
|
-
|
|
92071
|
-
|
|
92205
|
+
join61(home, "AppData", "Roaming", "npm", "claude.cmd"),
|
|
92206
|
+
join61(home, ".npm-global", "claude.cmd"),
|
|
92207
|
+
join61(home, "node_modules", ".bin", "claude.cmd")
|
|
92072
92208
|
];
|
|
92073
92209
|
for (const path of windowsPaths) {
|
|
92074
|
-
if (
|
|
92210
|
+
if (existsSync43(path)) {
|
|
92075
92211
|
return path;
|
|
92076
92212
|
}
|
|
92077
92213
|
}
|
|
@@ -92079,14 +92215,14 @@ async function findClaudeBinary() {
|
|
|
92079
92215
|
const commonPaths = [
|
|
92080
92216
|
"/usr/local/bin/claude",
|
|
92081
92217
|
"/opt/homebrew/bin/claude",
|
|
92082
|
-
|
|
92083
|
-
|
|
92084
|
-
|
|
92218
|
+
join61(home, ".npm-global/bin/claude"),
|
|
92219
|
+
join61(home, ".local/bin/claude"),
|
|
92220
|
+
join61(home, "node_modules/.bin/claude"),
|
|
92085
92221
|
"/data/data/com.termux/files/usr/bin/claude",
|
|
92086
|
-
|
|
92222
|
+
join61(home, "../usr/bin/claude")
|
|
92087
92223
|
];
|
|
92088
92224
|
for (const path of commonPaths) {
|
|
92089
|
-
if (
|
|
92225
|
+
if (existsSync43(path)) {
|
|
92090
92226
|
return path;
|
|
92091
92227
|
}
|
|
92092
92228
|
}
|
|
@@ -92176,16 +92312,16 @@ var init_claude_runner = __esm(() => {
|
|
|
92176
92312
|
// src/diag-output.ts
|
|
92177
92313
|
import { createWriteStream as createWriteStream2, mkdirSync as mkdirSync27, unlinkSync as unlinkSync11, writeFileSync as writeFileSync29 } from "fs";
|
|
92178
92314
|
import { homedir as homedir40 } from "os";
|
|
92179
|
-
import { join as
|
|
92315
|
+
import { join as join62 } from "path";
|
|
92180
92316
|
function getClaudishDir() {
|
|
92181
|
-
const dir =
|
|
92317
|
+
const dir = join62(homedir40(), ".claudish");
|
|
92182
92318
|
try {
|
|
92183
92319
|
mkdirSync27(dir, { recursive: true });
|
|
92184
92320
|
} catch {}
|
|
92185
92321
|
return dir;
|
|
92186
92322
|
}
|
|
92187
92323
|
function getDiagLogPath() {
|
|
92188
|
-
return
|
|
92324
|
+
return join62(getClaudishDir(), `diag-${process.pid}.log`);
|
|
92189
92325
|
}
|
|
92190
92326
|
|
|
92191
92327
|
class LogFileDiagOutput {
|
|
@@ -92721,7 +92857,7 @@ var init_advisor_startup = __esm(() => {
|
|
|
92721
92857
|
});
|
|
92722
92858
|
|
|
92723
92859
|
// src/session/conversation.ts
|
|
92724
|
-
import { closeSync as closeSync13, openSync as openSync13, readSync as readSync7, statSync as
|
|
92860
|
+
import { closeSync as closeSync13, openSync as openSync13, readSync as readSync7, statSync as statSync18 } from "fs";
|
|
92725
92861
|
import { StringDecoder } from "string_decoder";
|
|
92726
92862
|
function looksLikeTurn(line) {
|
|
92727
92863
|
const assistant = line.includes('"type":"assistant"');
|
|
@@ -92776,7 +92912,7 @@ function readConversation(file, opts = {}) {
|
|
|
92776
92912
|
};
|
|
92777
92913
|
let fd = null;
|
|
92778
92914
|
try {
|
|
92779
|
-
const size =
|
|
92915
|
+
const size = statSync18(file).size;
|
|
92780
92916
|
fd = openSync13(file, "r");
|
|
92781
92917
|
const buf = Buffer.allocUnsafe(chunkBytes);
|
|
92782
92918
|
const decoder = new StringDecoder("utf-8");
|
|
@@ -94435,11 +94571,11 @@ var exports_session_stats = {};
|
|
|
94435
94571
|
__export(exports_session_stats, {
|
|
94436
94572
|
readSessionStats: () => readSessionStats
|
|
94437
94573
|
});
|
|
94438
|
-
import { readFileSync as
|
|
94574
|
+
import { readFileSync as readFileSync42 } from "fs";
|
|
94439
94575
|
function readSessionStats(port, opts) {
|
|
94440
94576
|
let raw;
|
|
94441
94577
|
try {
|
|
94442
|
-
raw = JSON.parse(
|
|
94578
|
+
raw = JSON.parse(readFileSync42(resolveTokenFilePath(port), "utf-8"));
|
|
94443
94579
|
} catch {
|
|
94444
94580
|
return null;
|
|
94445
94581
|
}
|
|
@@ -94817,8 +94953,8 @@ init_launch_env();
|
|
|
94817
94953
|
init_op_source();
|
|
94818
94954
|
init_startup_trace();
|
|
94819
94955
|
init_picker_cancelled();
|
|
94820
|
-
import { existsSync as
|
|
94821
|
-
import { join as
|
|
94956
|
+
import { existsSync as existsSync44, readFileSync as readFileSync43 } from "fs";
|
|
94957
|
+
import { join as join63, resolve as resolve10 } from "path";
|
|
94822
94958
|
|
|
94823
94959
|
// src/tui/runtime/should-open-picker.ts
|
|
94824
94960
|
function noModelConfigured(gate) {
|
|
@@ -94835,7 +94971,7 @@ function requiresExplicitModel(gate, tty) {
|
|
|
94835
94971
|
var autoloadDropped = [...droppedAtLaunch, ...takeLauncherDropped(process.env)];
|
|
94836
94972
|
var dotenvText;
|
|
94837
94973
|
try {
|
|
94838
|
-
dotenvText =
|
|
94974
|
+
dotenvText = readFileSync43(join63(process.cwd(), ".env"));
|
|
94839
94975
|
} catch {}
|
|
94840
94976
|
if (dotenvText !== undefined) {
|
|
94841
94977
|
await Promise.resolve().then(() => init_dotenv_allowlist());
|
|
@@ -94950,8 +95086,8 @@ async function applyOpImport() {
|
|
|
94950
95086
|
async function applyConfigOverride() {
|
|
94951
95087
|
await Promise.resolve();
|
|
94952
95088
|
const plan = planConfigOverride(process.argv.slice(2), process.env, {
|
|
94953
|
-
resolve:
|
|
94954
|
-
exists:
|
|
95089
|
+
resolve: resolve10,
|
|
95090
|
+
exists: existsSync44
|
|
94955
95091
|
});
|
|
94956
95092
|
if (plan.kind === "none")
|
|
94957
95093
|
return;
|
|
@@ -95156,14 +95292,14 @@ async function runCli() {
|
|
|
95156
95292
|
if (cliConfig.team && cliConfig.team.length > 0) {
|
|
95157
95293
|
let prompt = cliConfig.claudeArgs.join(" ");
|
|
95158
95294
|
if (cliConfig.inputFile) {
|
|
95159
|
-
prompt =
|
|
95295
|
+
prompt = readFileSync43(cliConfig.inputFile, "utf-8");
|
|
95160
95296
|
}
|
|
95161
95297
|
if (!prompt.trim()) {
|
|
95162
95298
|
console.error("Error: --team requires a prompt (positional args or -f <file>)");
|
|
95163
95299
|
process.exit(1);
|
|
95164
95300
|
}
|
|
95165
95301
|
const mode = cliConfig.teamMode ?? "default";
|
|
95166
|
-
const sessionPath =
|
|
95302
|
+
const sessionPath = join63(process.cwd(), `.claudish-team-${Date.now()}`);
|
|
95167
95303
|
if (mode === "json") {
|
|
95168
95304
|
await Promise.resolve().then(() => init_pane());
|
|
95169
95305
|
await Promise.resolve().then(() => init_team_orchestrator());
|
|
@@ -95183,9 +95319,9 @@ async function runCli() {
|
|
|
95183
95319
|
const status = await runModels(sessionPath);
|
|
95184
95320
|
const result = { ...status, responses: {} };
|
|
95185
95321
|
for (const anonId of Object.keys(status.models)) {
|
|
95186
|
-
const responsePath =
|
|
95322
|
+
const responsePath = join63(sessionPath, `response-${anonId}.md`);
|
|
95187
95323
|
try {
|
|
95188
|
-
const raw =
|
|
95324
|
+
const raw = readFileSync43(responsePath, "utf-8").trim();
|
|
95189
95325
|
try {
|
|
95190
95326
|
result.responses[anonId] = JSON.parse(raw);
|
|
95191
95327
|
} catch {
|