anygate 0.5.3 → 0.5.4
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/LICENSE +21 -21
- package/README.md +613 -613
- package/dist/{chunk-QPXRFBQI.js → chunk-E2MV3GDX.js} +340 -79
- package/dist/chunk-E2MV3GDX.js.map +1 -0
- package/dist/{chunk-YYSUTRMV.js → chunk-VKROC37K.js} +1 -1
- package/dist/chunk-VKROC37K.js.map +1 -0
- package/dist/cli.js +11 -6
- package/dist/cli.js.map +1 -1
- package/dist/{command-M5GMEJCO.js → command-GJYPBC6E.js} +73 -24
- package/dist/command-GJYPBC6E.js.map +1 -0
- package/dist/{provider-templates-75KU6VA6.js → provider-templates-TWR5XSYI.js} +2 -2
- package/dist/ui/dist/assets/index-BXZwvwW9.css +1 -0
- package/dist/ui/dist/assets/index-CRD31gqp.js +5 -0
- package/dist/ui/dist/favicon.svg +13 -0
- package/dist/ui/dist/index.html +18 -0
- package/package.json +94 -92
- package/dist/chunk-QPXRFBQI.js.map +0 -1
- package/dist/chunk-YYSUTRMV.js.map +0 -1
- package/dist/command-M5GMEJCO.js.map +0 -1
- package/dist/ui/public/app.js +0 -2450
- package/dist/ui/public/icon-antigravity-ide.png +0 -0
- package/dist/ui/public/icon-antigravity.png +0 -0
- package/dist/ui/public/index.html +0 -217
- package/dist/ui/public/style.css +0 -1751
- /package/dist/{provider-templates-75KU6VA6.js.map → provider-templates-TWR5XSYI.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
getTemplateById
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VKROC37K.js";
|
|
5
5
|
|
|
6
6
|
// src/core/constants.ts
|
|
7
7
|
import { homedir } from "os";
|
|
@@ -10,7 +10,7 @@ import { join } from "path";
|
|
|
10
10
|
// package.json
|
|
11
11
|
var package_default = {
|
|
12
12
|
name: "anygate",
|
|
13
|
-
version: "0.5.
|
|
13
|
+
version: "0.5.4",
|
|
14
14
|
publishConfig: {
|
|
15
15
|
access: "public"
|
|
16
16
|
},
|
|
@@ -47,13 +47,15 @@ var package_default = {
|
|
|
47
47
|
node: ">=18"
|
|
48
48
|
},
|
|
49
49
|
scripts: {
|
|
50
|
-
build: "tsup && node scripts/copy-ui-assets.mjs",
|
|
50
|
+
build: "tsup && npm run ui:build && node scripts/copy-ui-assets.mjs",
|
|
51
51
|
dev: "tsup --watch",
|
|
52
52
|
test: "vitest run",
|
|
53
53
|
"test:watch": "vitest",
|
|
54
54
|
typecheck: "tsc --noEmit",
|
|
55
55
|
"refresh:models-dev": "node scripts/refresh-models-dev-cache.mjs",
|
|
56
|
-
prepublishOnly: `node -e "if (require('./package.json').version !== require('./package-lock.json').version) { console.error('Error: package.json and package-lock.json versions are out of sync! Run npm install to sync.'); process.exit(1); }" && npm run build
|
|
56
|
+
prepublishOnly: `node -e "if (require('./package.json').version !== require('./package-lock.json').version) { console.error('Error: package.json and package-lock.json versions are out of sync! Run npm install to sync.'); process.exit(1); }" && npm run build`,
|
|
57
|
+
"ui:dev": "npm --prefix ui run dev",
|
|
58
|
+
"ui:build": "npm --prefix ui run build"
|
|
57
59
|
},
|
|
58
60
|
dependencies: {
|
|
59
61
|
"@ai-sdk/alibaba": "^1.0.26",
|
|
@@ -3903,7 +3905,7 @@ function printTraceLog(debugLogPath) {
|
|
|
3903
3905
|
|
|
3904
3906
|
// src/gateway/anthropic-proxy.ts
|
|
3905
3907
|
import { createServer } from "http";
|
|
3906
|
-
import { appendFileSync as
|
|
3908
|
+
import { appendFileSync as appendFileSync3, openSync as openSync3, writeSync as writeSync3, closeSync as closeSync3 } from "fs";
|
|
3907
3909
|
|
|
3908
3910
|
// src/core/http-utils.ts
|
|
3909
3911
|
import * as zlib from "zlib";
|
|
@@ -5403,7 +5405,7 @@ async function writeAnthropicStream(fullStream, modelId, write, log7) {
|
|
|
5403
5405
|
log7?.(() => `sdk stream error (${errorType}): ${errMsg}`);
|
|
5404
5406
|
closeOpen();
|
|
5405
5407
|
emit("error", { type: "error", error: { type: errorType, message: errMsg } });
|
|
5406
|
-
return;
|
|
5408
|
+
return { inputTokens: 0, outputTokens: 0 };
|
|
5407
5409
|
}
|
|
5408
5410
|
default:
|
|
5409
5411
|
break;
|
|
@@ -5413,6 +5415,7 @@ async function writeAnthropicStream(fullStream, modelId, write, log7) {
|
|
|
5413
5415
|
ensureStart();
|
|
5414
5416
|
emit("message_delta", { type: "message_delta", delta: { stop_reason: finishReason, stop_sequence: null }, usage });
|
|
5415
5417
|
emit("message_stop", { type: "message_stop" });
|
|
5418
|
+
return { inputTokens: usage.input_tokens, outputTokens: usage.output_tokens };
|
|
5416
5419
|
}
|
|
5417
5420
|
async function streamAnthropicResponse(model, params, modelId, write, log7) {
|
|
5418
5421
|
const result = streamText({ model, ...params, onError: () => {
|
|
@@ -5427,7 +5430,7 @@ async function streamAnthropicResponse(model, params, modelId, write, log7) {
|
|
|
5427
5430
|
});
|
|
5428
5431
|
Promise.resolve(result.usage).catch(() => {
|
|
5429
5432
|
});
|
|
5430
|
-
await writeAnthropicStream(result.fullStream, modelId, write, log7);
|
|
5433
|
+
return await writeAnthropicStream(result.fullStream, modelId, write, log7);
|
|
5431
5434
|
}
|
|
5432
5435
|
async function generateAnthropicResponse(model, params, modelId, options) {
|
|
5433
5436
|
let text4;
|
|
@@ -5459,7 +5462,196 @@ async function generateAnthropicResponse(model, params, modelId, options) {
|
|
|
5459
5462
|
}))
|
|
5460
5463
|
],
|
|
5461
5464
|
stop_reason: finishReason === "tool-calls" ? "tool_use" : "end_turn",
|
|
5462
|
-
usage: { input_tokens: usage?.inputTokens ?? 0, output_tokens: usage?.outputTokens ?? 0 }
|
|
5465
|
+
usage: { input_tokens: usage?.inputTokens ?? 0, output_tokens: usage?.outputTokens ?? 0 },
|
|
5466
|
+
// Internal: surfaced to call sites so they can log analytics without re-parsing.
|
|
5467
|
+
_usage: { inputTokens: usage?.inputTokens ?? 0, outputTokens: usage?.outputTokens ?? 0 }
|
|
5468
|
+
};
|
|
5469
|
+
}
|
|
5470
|
+
|
|
5471
|
+
// src/core/analytics-log.ts
|
|
5472
|
+
import { appendFileSync as appendFileSync2, openSync as openSync2, writeSync as writeSync2, closeSync as closeSync2, readFileSync as readFileSync9, existsSync as existsSync9 } from "fs";
|
|
5473
|
+
import { join as join9 } from "path";
|
|
5474
|
+
var ANALYTICS_FILE = "analytics.jsonl";
|
|
5475
|
+
function analyticsPath() {
|
|
5476
|
+
return join9(getAppHome(), ANALYTICS_FILE);
|
|
5477
|
+
}
|
|
5478
|
+
function appendAtomic(path, line) {
|
|
5479
|
+
try {
|
|
5480
|
+
const fd = openSync2(path, "a", 384);
|
|
5481
|
+
try {
|
|
5482
|
+
writeSync2(fd, line + "\n");
|
|
5483
|
+
} finally {
|
|
5484
|
+
closeSync2(fd);
|
|
5485
|
+
}
|
|
5486
|
+
} catch {
|
|
5487
|
+
try {
|
|
5488
|
+
appendFileSync2(path, line + "\n");
|
|
5489
|
+
} catch {
|
|
5490
|
+
}
|
|
5491
|
+
}
|
|
5492
|
+
}
|
|
5493
|
+
function recordUsage(event) {
|
|
5494
|
+
if (!event?.ts || typeof event.modelId !== "string" || typeof event.app !== "string") return;
|
|
5495
|
+
const inputTokens = Math.max(0, Math.floor(event.inputTokens || 0));
|
|
5496
|
+
const outputTokens = Math.max(0, Math.floor(event.outputTokens || 0));
|
|
5497
|
+
if (inputTokens === 0 && outputTokens === 0) return;
|
|
5498
|
+
const clean = {
|
|
5499
|
+
ts: event.ts,
|
|
5500
|
+
modelId: event.modelId,
|
|
5501
|
+
app: event.app,
|
|
5502
|
+
inputTokens,
|
|
5503
|
+
outputTokens
|
|
5504
|
+
};
|
|
5505
|
+
if (event.npm) clean.npm = event.npm;
|
|
5506
|
+
if (event.providerId) clean.providerId = event.providerId;
|
|
5507
|
+
appendAtomic(analyticsPath(), JSON.stringify(clean));
|
|
5508
|
+
}
|
|
5509
|
+
function readAnalyticsLog() {
|
|
5510
|
+
const path = analyticsPath();
|
|
5511
|
+
if (!existsSync9(path)) return [];
|
|
5512
|
+
let raw;
|
|
5513
|
+
try {
|
|
5514
|
+
raw = readFileSync9(path, "utf8");
|
|
5515
|
+
} catch {
|
|
5516
|
+
return [];
|
|
5517
|
+
}
|
|
5518
|
+
const out = [];
|
|
5519
|
+
for (const line of raw.split("\n")) {
|
|
5520
|
+
const t = line.trim();
|
|
5521
|
+
if (!t) continue;
|
|
5522
|
+
try {
|
|
5523
|
+
const e = JSON.parse(t);
|
|
5524
|
+
if (e && typeof e.ts === "string" && typeof e.modelId === "string") out.push(e);
|
|
5525
|
+
} catch {
|
|
5526
|
+
}
|
|
5527
|
+
}
|
|
5528
|
+
return out;
|
|
5529
|
+
}
|
|
5530
|
+
var MODEL_PALETTE = [
|
|
5531
|
+
"oklch(75% 0.16 65)",
|
|
5532
|
+
// amber (accent)
|
|
5533
|
+
"oklch(70% 0.15 200)",
|
|
5534
|
+
// sky blue
|
|
5535
|
+
"oklch(68% 0.16 150)",
|
|
5536
|
+
// teal/green
|
|
5537
|
+
"oklch(72% 0.17 300)",
|
|
5538
|
+
// violet
|
|
5539
|
+
"oklch(70% 0.18 20)",
|
|
5540
|
+
// rose/red
|
|
5541
|
+
"oklch(74% 0.15 95)"
|
|
5542
|
+
// gold/yellow
|
|
5543
|
+
];
|
|
5544
|
+
function rangeDays(range) {
|
|
5545
|
+
if (range === "7d") return 7;
|
|
5546
|
+
if (range === "30d") return 30;
|
|
5547
|
+
return 365;
|
|
5548
|
+
}
|
|
5549
|
+
function dayKey(iso) {
|
|
5550
|
+
return iso.slice(0, 10);
|
|
5551
|
+
}
|
|
5552
|
+
function aggregateAnalytics(range) {
|
|
5553
|
+
const all = readAnalyticsLog();
|
|
5554
|
+
const today = /* @__PURE__ */ new Date();
|
|
5555
|
+
today.setUTCHours(0, 0, 0, 0);
|
|
5556
|
+
const cutoff = new Date(today);
|
|
5557
|
+
cutoff.setUTCDate(today.getUTCDate() - (rangeDays(range) - 1));
|
|
5558
|
+
const cutoffIso = cutoff.toISOString();
|
|
5559
|
+
const endIso = new Date(today.getTime() + 864e5).toISOString();
|
|
5560
|
+
const events = all.filter((e) => e.ts >= cutoffIso && e.ts <= endIso);
|
|
5561
|
+
const eventsByDay = /* @__PURE__ */ new Map();
|
|
5562
|
+
const tokensByDay = /* @__PURE__ */ new Map();
|
|
5563
|
+
const hourCounts = new Array(24).fill(0);
|
|
5564
|
+
const activeDaySet = /* @__PURE__ */ new Set();
|
|
5565
|
+
const modelMap = /* @__PURE__ */ new Map();
|
|
5566
|
+
let totalTokens = 0;
|
|
5567
|
+
let messages = 0;
|
|
5568
|
+
for (const e of events) {
|
|
5569
|
+
const day = dayKey(e.ts);
|
|
5570
|
+
const tok = e.inputTokens + e.outputTokens;
|
|
5571
|
+
totalTokens += tok;
|
|
5572
|
+
messages += 1;
|
|
5573
|
+
eventsByDay.set(day, (eventsByDay.get(day) ?? 0) + 1);
|
|
5574
|
+
tokensByDay.set(day, (tokensByDay.get(day) ?? 0) + tok);
|
|
5575
|
+
activeDaySet.add(day);
|
|
5576
|
+
const hour = Number(e.ts.slice(11, 13));
|
|
5577
|
+
if (Number.isFinite(hour) && hour >= 0 && hour < 24) hourCounts[hour] += 1;
|
|
5578
|
+
const provider = e.providerId ?? e.npm?.replace(/^@/, "").replace(/\//g, "-") ?? "unknown";
|
|
5579
|
+
const key = `${provider}|${e.modelId}`;
|
|
5580
|
+
const m = modelMap.get(key) ?? { provider, model: e.modelId, app: e.app, inputTokens: 0, outputTokens: 0 };
|
|
5581
|
+
m.inputTokens += e.inputTokens;
|
|
5582
|
+
m.outputTokens += e.outputTokens;
|
|
5583
|
+
modelMap.set(key, m);
|
|
5584
|
+
}
|
|
5585
|
+
const busiestDay = Math.max(1, ...[...eventsByDay.values()]);
|
|
5586
|
+
const heatmap = [];
|
|
5587
|
+
for (let i = rangeDays(range) - 1; i >= 0; i--) {
|
|
5588
|
+
const d = new Date(today);
|
|
5589
|
+
d.setUTCDate(today.getUTCDate() - i);
|
|
5590
|
+
const date = d.toISOString().slice(0, 10);
|
|
5591
|
+
const count = eventsByDay.get(date) ?? 0;
|
|
5592
|
+
const intensity = Math.min(4, Math.round(count / busiestDay * 4)) || 0;
|
|
5593
|
+
heatmap.push({ date, count, intensity });
|
|
5594
|
+
}
|
|
5595
|
+
const dailyTokens = [];
|
|
5596
|
+
for (let i = rangeDays(range) - 1; i >= 0; i--) {
|
|
5597
|
+
const d = new Date(today);
|
|
5598
|
+
d.setUTCDate(today.getUTCDate() - i);
|
|
5599
|
+
const date = d.toISOString().slice(0, 10);
|
|
5600
|
+
dailyTokens.push({ date, tokens: tokensByDay.get(date) ?? 0 });
|
|
5601
|
+
}
|
|
5602
|
+
let currentStreak = 0;
|
|
5603
|
+
for (let i = 0; i < rangeDays(range); i++) {
|
|
5604
|
+
const d = new Date(today);
|
|
5605
|
+
d.setUTCDate(today.getUTCDate() - i);
|
|
5606
|
+
const date = d.toISOString().slice(0, 10);
|
|
5607
|
+
if (eventsByDay.has(date)) currentStreak++;
|
|
5608
|
+
else break;
|
|
5609
|
+
}
|
|
5610
|
+
let longestStreak = 0;
|
|
5611
|
+
let run3 = 0;
|
|
5612
|
+
for (const day of heatmap) {
|
|
5613
|
+
if (day.count > 0) {
|
|
5614
|
+
run3++;
|
|
5615
|
+
longestStreak = Math.max(longestStreak, run3);
|
|
5616
|
+
} else run3 = 0;
|
|
5617
|
+
}
|
|
5618
|
+
let peakHour = 0;
|
|
5619
|
+
let peakCount = -1;
|
|
5620
|
+
for (let h = 0; h < 24; h++) {
|
|
5621
|
+
if (hourCounts[h] > peakCount) {
|
|
5622
|
+
peakCount = hourCounts[h];
|
|
5623
|
+
peakHour = h;
|
|
5624
|
+
}
|
|
5625
|
+
}
|
|
5626
|
+
const models = [...modelMap.entries()].map(([, m], idx) => {
|
|
5627
|
+
const share = totalTokens > 0 ? (m.inputTokens + m.outputTokens) / totalTokens : 0;
|
|
5628
|
+
return {
|
|
5629
|
+
provider: m.provider,
|
|
5630
|
+
model: m.model,
|
|
5631
|
+
tier: "",
|
|
5632
|
+
// source tier isn't tracked in the log; UI shows it from catalog elsewhere
|
|
5633
|
+
app: m.app,
|
|
5634
|
+
inputTokens: m.inputTokens,
|
|
5635
|
+
outputTokens: m.outputTokens,
|
|
5636
|
+
share,
|
|
5637
|
+
color: MODEL_PALETTE[idx % MODEL_PALETTE.length]
|
|
5638
|
+
};
|
|
5639
|
+
});
|
|
5640
|
+
models.sort((a, b) => b.share - a.share);
|
|
5641
|
+
const favoriteModel = models.length > 0 ? `${models[0].provider}: ${models[0].model}` : "";
|
|
5642
|
+
return {
|
|
5643
|
+
range,
|
|
5644
|
+
sessions: activeDaySet.size,
|
|
5645
|
+
messages,
|
|
5646
|
+
totalTokens,
|
|
5647
|
+
activeDays: activeDaySet.size,
|
|
5648
|
+
currentStreakDays: currentStreak,
|
|
5649
|
+
longestStreakDays: longestStreak,
|
|
5650
|
+
peakHour,
|
|
5651
|
+
favoriteModel,
|
|
5652
|
+
heatmap,
|
|
5653
|
+
dailyTokens,
|
|
5654
|
+
models
|
|
5463
5655
|
};
|
|
5464
5656
|
}
|
|
5465
5657
|
|
|
@@ -5467,16 +5659,16 @@ async function generateAnthropicResponse(model, params, modelId, options) {
|
|
|
5467
5659
|
function appendSecureLog(logPath, line) {
|
|
5468
5660
|
const redacted = redactTraceLine(line);
|
|
5469
5661
|
try {
|
|
5470
|
-
const fd =
|
|
5662
|
+
const fd = openSync3(logPath, "a", 384);
|
|
5471
5663
|
try {
|
|
5472
|
-
|
|
5664
|
+
writeSync3(fd, `${(/* @__PURE__ */ new Date()).toISOString()} ${redacted}
|
|
5473
5665
|
`);
|
|
5474
5666
|
} finally {
|
|
5475
|
-
|
|
5667
|
+
closeSync3(fd);
|
|
5476
5668
|
}
|
|
5477
5669
|
} catch {
|
|
5478
5670
|
try {
|
|
5479
|
-
|
|
5671
|
+
appendFileSync3(logPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${redacted}
|
|
5480
5672
|
`);
|
|
5481
5673
|
} catch {
|
|
5482
5674
|
}
|
|
@@ -5665,7 +5857,16 @@ function startProxyCatalog(routes, defaultAliasId, debug = false) {
|
|
|
5665
5857
|
"Cache-Control": "no-cache",
|
|
5666
5858
|
"Connection": "keep-alive"
|
|
5667
5859
|
});
|
|
5668
|
-
await streamAnthropicResponse(model, params, originalModel, (c) => res.write(c), plog);
|
|
5860
|
+
const usage = await streamAnthropicResponse(model, params, originalModel, (c) => res.write(c), plog);
|
|
5861
|
+
recordUsage({
|
|
5862
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5863
|
+
modelId: route.realModelId,
|
|
5864
|
+
npm: route.npm,
|
|
5865
|
+
providerId: route.providerId,
|
|
5866
|
+
app: route.app ?? "gateway",
|
|
5867
|
+
inputTokens: usage.inputTokens,
|
|
5868
|
+
outputTokens: usage.outputTokens
|
|
5869
|
+
});
|
|
5669
5870
|
res.end();
|
|
5670
5871
|
} else {
|
|
5671
5872
|
const anthropicResponse = await generateAnthropicResponse(
|
|
@@ -5674,12 +5875,22 @@ function startProxyCatalog(routes, defaultAliasId, debug = false) {
|
|
|
5674
5875
|
originalModel,
|
|
5675
5876
|
{ forceStream: openAiOAuth }
|
|
5676
5877
|
);
|
|
5878
|
+
const u = anthropicResponse._usage;
|
|
5879
|
+
recordUsage({
|
|
5880
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5881
|
+
modelId: route.realModelId,
|
|
5882
|
+
npm: route.npm,
|
|
5883
|
+
providerId: route.providerId,
|
|
5884
|
+
app: route.app ?? "gateway",
|
|
5885
|
+
inputTokens: u?.inputTokens ?? 0,
|
|
5886
|
+
outputTokens: u?.outputTokens ?? 0
|
|
5887
|
+
});
|
|
5677
5888
|
sendJson(res, 200, anthropicResponse);
|
|
5678
5889
|
}
|
|
5679
5890
|
} catch (err) {
|
|
5680
5891
|
const message = err instanceof Error ? err.message : String(err);
|
|
5681
5892
|
const body = err && typeof err === "object" && "responseBody" in err ? err.responseBody : void 0;
|
|
5682
|
-
plog(() => `sdk error: ${message}${body ? ` \
|
|
5893
|
+
plog(() => `sdk error: ${message}${body ? ` \u0393\xC7\xF6 body: ${body}` : ""}`);
|
|
5683
5894
|
if (!res.headersSent) {
|
|
5684
5895
|
const status = upstreamHttpStatus(err);
|
|
5685
5896
|
anthropicError(res, status === 500 ? 502 : status, message);
|
|
@@ -5697,7 +5908,7 @@ data: ${JSON.stringify({ type: "error", error: { type: errorType, message } })}
|
|
|
5697
5908
|
if (route.modelFormat === "cloud-code") {
|
|
5698
5909
|
const projectId = route.providerData?.projectId ?? "";
|
|
5699
5910
|
if (!projectId) {
|
|
5700
|
-
anthropicError(res, 500, "Antigravity provider missing projectId \
|
|
5911
|
+
anthropicError(res, 500, "Antigravity provider missing projectId \u0393\xC7\xF6 re-authenticate with anygate providers auth antigravity");
|
|
5701
5912
|
return;
|
|
5702
5913
|
}
|
|
5703
5914
|
const envelope = anthropicToCloudCode(anthropicBody, route.realModelId, projectId);
|
|
@@ -5708,7 +5919,7 @@ data: ${JSON.stringify({ type: "error", error: { type: errorType, message } })}
|
|
|
5708
5919
|
const cloudMaxOutput = envelope.request.generationConfig?.maxOutputTokens;
|
|
5709
5920
|
const baseUrl = upstreamUrl.replace(/\/+$/, "");
|
|
5710
5921
|
const cloudCodeUrl = `${baseUrl}/v1internal:streamGenerateContent?alt=sse`;
|
|
5711
|
-
plog(() => `cloud-code: model=${route.realModelId}, project=${projectId.slice(0, 8)}\
|
|
5922
|
+
plog(() => `cloud-code: model=${route.realModelId}, project=${projectId.slice(0, 8)}\u0393\xC7\xAA msgs=${cloudContents.length} toolCalls=${cloudToolCalls} toolResults=${cloudToolResults} tools=${cloudTools} maxOutput=${cloudMaxOutput ?? "unset"} stream=${clientWantsStream}`);
|
|
5712
5923
|
const fetchCloudCode = (token) => fetch(cloudCodeUrl, {
|
|
5713
5924
|
method: "POST",
|
|
5714
5925
|
headers: {
|
|
@@ -5789,7 +6000,8 @@ function startProxy(completionsUrl, modelId, debug = false, contextWindow, sdk,
|
|
|
5789
6000
|
reasoning: sdk?.reasoning,
|
|
5790
6001
|
interleavedReasoningField: sdk?.interleavedReasoningField,
|
|
5791
6002
|
useResponsesLite: sdk?.useResponsesLite,
|
|
5792
|
-
preferWebSockets: sdk?.preferWebSockets
|
|
6003
|
+
preferWebSockets: sdk?.preferWebSockets,
|
|
6004
|
+
app: sdk?.app
|
|
5793
6005
|
}], clientModelId, debug);
|
|
5794
6006
|
}
|
|
5795
6007
|
|
|
@@ -6959,17 +7171,24 @@ async function generateOpenAiResponse(model, params, responseModelId) {
|
|
|
6959
7171
|
function: { name: tc.toolName, arguments: JSON.stringify(tc.args) }
|
|
6960
7172
|
}));
|
|
6961
7173
|
}
|
|
7174
|
+
const usage = {
|
|
7175
|
+
inputTokens: result.usage?.promptTokens ?? 0,
|
|
7176
|
+
outputTokens: result.usage?.completionTokens ?? 0
|
|
7177
|
+
};
|
|
6962
7178
|
return {
|
|
6963
|
-
|
|
6964
|
-
|
|
6965
|
-
|
|
6966
|
-
|
|
6967
|
-
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
|
|
6972
|
-
|
|
7179
|
+
response: {
|
|
7180
|
+
id: `chatcmpl-${Date.now()}`,
|
|
7181
|
+
object: "chat.completion",
|
|
7182
|
+
created: Math.floor(Date.now() / 1e3),
|
|
7183
|
+
model: responseModelId,
|
|
7184
|
+
choices: [{ index: 0, message, finish_reason: result.finishReason || "stop" }],
|
|
7185
|
+
usage: {
|
|
7186
|
+
prompt_tokens: usage.inputTokens,
|
|
7187
|
+
completion_tokens: usage.outputTokens,
|
|
7188
|
+
total_tokens: usage.inputTokens + usage.outputTokens
|
|
7189
|
+
}
|
|
7190
|
+
},
|
|
7191
|
+
usage
|
|
6973
7192
|
};
|
|
6974
7193
|
}
|
|
6975
7194
|
async function streamOpenAiResponse(model, params, responseModelId, onChunk) {
|
|
@@ -6980,6 +7199,7 @@ async function streamOpenAiResponse(model, params, responseModelId, onChunk) {
|
|
|
6980
7199
|
created: Math.floor(Date.now() / 1e3),
|
|
6981
7200
|
model: responseModelId
|
|
6982
7201
|
};
|
|
7202
|
+
let usage = { inputTokens: 0, outputTokens: 0 };
|
|
6983
7203
|
const send = (delta, finish_reason = null) => onChunk(`data: ${JSON.stringify({ ...baseData, choices: [{ index: 0, delta, finish_reason }] })}
|
|
6984
7204
|
|
|
6985
7205
|
`);
|
|
@@ -6998,11 +7218,15 @@ async function streamOpenAiResponse(model, params, responseModelId, onChunk) {
|
|
|
6998
7218
|
send({ tool_calls: [{ index: 0, function: { arguments: p8.delta ?? p8.text ?? p8.argsTextDelta ?? "" } }] });
|
|
6999
7219
|
break;
|
|
7000
7220
|
case "finish":
|
|
7221
|
+
if (p8.usage) {
|
|
7222
|
+
usage = { inputTokens: p8.usage.promptTokens ?? 0, outputTokens: p8.usage.completionTokens ?? 0 };
|
|
7223
|
+
}
|
|
7001
7224
|
send({}, p8.finishReason || "stop");
|
|
7002
7225
|
break;
|
|
7003
7226
|
}
|
|
7004
7227
|
}
|
|
7005
7228
|
onChunk("data: [DONE]\n\n");
|
|
7229
|
+
return usage;
|
|
7006
7230
|
}
|
|
7007
7231
|
|
|
7008
7232
|
// src/registry/refresh-credentials.ts
|
|
@@ -7305,10 +7529,28 @@ async function handleAnthropicMessages(req, res, options, modelCache, plog) {
|
|
|
7305
7529
|
"Cache-Control": "no-cache",
|
|
7306
7530
|
"Connection": "keep-alive"
|
|
7307
7531
|
});
|
|
7308
|
-
await streamAnthropicResponse(languageModel, params, responseModelId, (chunk) => res.write(chunk));
|
|
7532
|
+
const usage = await streamAnthropicResponse(languageModel, params, responseModelId, (chunk) => res.write(chunk));
|
|
7533
|
+
recordUsage({
|
|
7534
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7535
|
+
modelId: responseModelId,
|
|
7536
|
+
npm: model.npm,
|
|
7537
|
+
providerId: model.providerId,
|
|
7538
|
+
app: "gateway",
|
|
7539
|
+
inputTokens: usage.inputTokens,
|
|
7540
|
+
outputTokens: usage.outputTokens
|
|
7541
|
+
});
|
|
7309
7542
|
res.end();
|
|
7310
7543
|
} else {
|
|
7311
7544
|
const anthropicResponse = await generateAnthropicResponse(languageModel, params, responseModelId);
|
|
7545
|
+
recordUsage({
|
|
7546
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7547
|
+
modelId: responseModelId,
|
|
7548
|
+
npm: model.npm,
|
|
7549
|
+
providerId: model.providerId,
|
|
7550
|
+
app: "gateway",
|
|
7551
|
+
inputTokens: anthropicResponse._usage?.inputTokens ?? 0,
|
|
7552
|
+
outputTokens: anthropicResponse._usage?.outputTokens ?? 0
|
|
7553
|
+
});
|
|
7312
7554
|
sendJson(res, 200, anthropicResponse);
|
|
7313
7555
|
}
|
|
7314
7556
|
} catch (err) {
|
|
@@ -7360,10 +7602,28 @@ async function handleOpenAIChatCompletions(req, res, options, modelCache, plog)
|
|
|
7360
7602
|
"Cache-Control": "no-cache",
|
|
7361
7603
|
"Connection": "keep-alive"
|
|
7362
7604
|
});
|
|
7363
|
-
await streamOpenAiResponse(languageModel, params, responseModelId, (chunk) => res.write(chunk));
|
|
7605
|
+
const usage = await streamOpenAiResponse(languageModel, params, responseModelId, (chunk) => res.write(chunk));
|
|
7606
|
+
recordUsage({
|
|
7607
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7608
|
+
modelId: responseModelId,
|
|
7609
|
+
npm: model.npm ?? (model.modelFormat === "anthropic" ? "@ai-sdk/anthropic" : void 0),
|
|
7610
|
+
providerId: model.providerId,
|
|
7611
|
+
app: "gateway",
|
|
7612
|
+
inputTokens: usage.inputTokens,
|
|
7613
|
+
outputTokens: usage.outputTokens
|
|
7614
|
+
});
|
|
7364
7615
|
res.end();
|
|
7365
7616
|
} else {
|
|
7366
|
-
const response = await generateOpenAiResponse(languageModel, params, responseModelId);
|
|
7617
|
+
const { response, usage } = await generateOpenAiResponse(languageModel, params, responseModelId);
|
|
7618
|
+
recordUsage({
|
|
7619
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7620
|
+
modelId: responseModelId,
|
|
7621
|
+
npm: model.npm ?? (model.modelFormat === "anthropic" ? "@ai-sdk/anthropic" : void 0),
|
|
7622
|
+
providerId: model.providerId,
|
|
7623
|
+
app: "gateway",
|
|
7624
|
+
inputTokens: usage.inputTokens,
|
|
7625
|
+
outputTokens: usage.outputTokens
|
|
7626
|
+
});
|
|
7367
7627
|
sendJson(res, 200, response);
|
|
7368
7628
|
}
|
|
7369
7629
|
} catch (err) {
|
|
@@ -7558,9 +7818,9 @@ async function selectServerProviders(available, initial) {
|
|
|
7558
7818
|
}
|
|
7559
7819
|
|
|
7560
7820
|
// src/gateway/vertex.ts
|
|
7561
|
-
import { existsSync as
|
|
7821
|
+
import { existsSync as existsSync10, readFileSync as readFileSync10 } from "fs";
|
|
7562
7822
|
import { homedir as homedir6 } from "os";
|
|
7563
|
-
import { join as
|
|
7823
|
+
import { join as join10 } from "path";
|
|
7564
7824
|
var DEFAULT_VERTEX_MODELS = [
|
|
7565
7825
|
{ id: "claude-sonnet-4-6", display_name: "Claude Sonnet 4.6" },
|
|
7566
7826
|
{ id: "claude-opus-4-6", display_name: "Claude Opus 4.6" },
|
|
@@ -7584,18 +7844,18 @@ function resolveVertexLocation(env = process.env) {
|
|
|
7584
7844
|
return location.trim() || "global";
|
|
7585
7845
|
}
|
|
7586
7846
|
function defaultAdcCredentialsPath(home = homedir6()) {
|
|
7587
|
-
return
|
|
7847
|
+
return join10(home, ".config", "gcloud", "application_default_credentials.json");
|
|
7588
7848
|
}
|
|
7589
7849
|
function hasApplicationDefaultCredentials(home = homedir6(), adcPath = defaultAdcCredentialsPath(home), env = process.env) {
|
|
7590
7850
|
const explicitPath = env["GOOGLE_APPLICATION_CREDENTIALS"]?.trim();
|
|
7591
|
-
if (explicitPath &&
|
|
7592
|
-
return
|
|
7851
|
+
if (explicitPath && existsSync10(explicitPath)) return true;
|
|
7852
|
+
return existsSync10(adcPath);
|
|
7593
7853
|
}
|
|
7594
7854
|
function loadVertexModelEntries(env = process.env) {
|
|
7595
7855
|
const configPath = getVertexModelsPath(env);
|
|
7596
|
-
if (!
|
|
7856
|
+
if (!existsSync10(configPath)) return DEFAULT_VERTEX_MODELS;
|
|
7597
7857
|
try {
|
|
7598
|
-
const parsed = JSON.parse(
|
|
7858
|
+
const parsed = JSON.parse(readFileSync10(configPath, "utf8"));
|
|
7599
7859
|
if (!Array.isArray(parsed) || parsed.length === 0) return DEFAULT_VERTEX_MODELS;
|
|
7600
7860
|
const models = parsed.filter(
|
|
7601
7861
|
(entry) => !!entry && typeof entry === "object" && typeof entry.id === "string" && entry.id.length > 0 && typeof entry.display_name === "string" && entry.display_name.length > 0
|
|
@@ -8108,12 +8368,12 @@ async function runServerCommand(options = {}) {
|
|
|
8108
8368
|
import {
|
|
8109
8369
|
chmodSync as chmodSync5,
|
|
8110
8370
|
mkdirSync as mkdirSync6,
|
|
8111
|
-
readFileSync as
|
|
8371
|
+
readFileSync as readFileSync11,
|
|
8112
8372
|
renameSync as renameSync2,
|
|
8113
8373
|
unlinkSync as unlinkSync2,
|
|
8114
8374
|
writeFileSync as writeFileSync5
|
|
8115
8375
|
} from "fs";
|
|
8116
|
-
import { join as
|
|
8376
|
+
import { join as join11 } from "path";
|
|
8117
8377
|
var UPDATE_CHECK_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
8118
8378
|
var UPDATE_CHECK_TIMEOUT_MS = 2e3;
|
|
8119
8379
|
var UPDATE_COMMAND = "npm install -g anygate@latest";
|
|
@@ -8159,11 +8419,11 @@ function isNewerVersion(currentVersion, latestVersion) {
|
|
|
8159
8419
|
return comparePrerelease(current.prerelease, latest.prerelease) > 0;
|
|
8160
8420
|
}
|
|
8161
8421
|
function cachePath() {
|
|
8162
|
-
return
|
|
8422
|
+
return join11(getAppHome(), "update-check.json");
|
|
8163
8423
|
}
|
|
8164
8424
|
function readFreshCache(now) {
|
|
8165
8425
|
try {
|
|
8166
|
-
const parsed = JSON.parse(
|
|
8426
|
+
const parsed = JSON.parse(readFileSync11(cachePath(), "utf8"));
|
|
8167
8427
|
if (typeof parsed.latestVersion !== "string" || !parseVersion(parsed.latestVersion)) return null;
|
|
8168
8428
|
if (typeof parsed.checkedAt !== "number" || !Number.isFinite(parsed.checkedAt)) return null;
|
|
8169
8429
|
const age = now - parsed.checkedAt;
|
|
@@ -8244,18 +8504,18 @@ function favoriteProviderDisplayName(provider) {
|
|
|
8244
8504
|
|
|
8245
8505
|
// src/providers/opencode-serve.ts
|
|
8246
8506
|
import { execSync as execSync2, spawn as spawn2 } from "child_process";
|
|
8247
|
-
import { existsSync as
|
|
8507
|
+
import { existsSync as existsSync11 } from "fs";
|
|
8248
8508
|
import { homedir as homedir7 } from "os";
|
|
8249
|
-
import { join as
|
|
8509
|
+
import { join as join12 } from "path";
|
|
8250
8510
|
var isWindows2 = process.platform === "win32";
|
|
8251
8511
|
var OPENCODE_FALLBACK_PATHS = isWindows2 ? [
|
|
8252
|
-
|
|
8253
|
-
|
|
8254
|
-
|
|
8512
|
+
join12(process.env["APPDATA"] ?? homedir7(), "npm", "opencode.cmd"),
|
|
8513
|
+
join12(process.env["APPDATA"] ?? homedir7(), "npm", "opencode"),
|
|
8514
|
+
join12(homedir7(), "AppData", "Roaming", "npm", "opencode.cmd")
|
|
8255
8515
|
] : [
|
|
8256
|
-
|
|
8257
|
-
|
|
8258
|
-
|
|
8516
|
+
join12(homedir7(), ".opencode", "bin", "opencode"),
|
|
8517
|
+
join12(homedir7(), ".local", "bin", "opencode"),
|
|
8518
|
+
join12(homedir7(), ".npm", "bin", "opencode"),
|
|
8259
8519
|
"/usr/local/bin/opencode",
|
|
8260
8520
|
"/opt/homebrew/bin/opencode"
|
|
8261
8521
|
];
|
|
@@ -8271,7 +8531,7 @@ function findOpencodeBinary() {
|
|
|
8271
8531
|
} catch {
|
|
8272
8532
|
}
|
|
8273
8533
|
for (const path of OPENCODE_FALLBACK_PATHS) {
|
|
8274
|
-
if (
|
|
8534
|
+
if (existsSync11(path)) return path;
|
|
8275
8535
|
}
|
|
8276
8536
|
return null;
|
|
8277
8537
|
}
|
|
@@ -9929,9 +10189,9 @@ ${pc6.bold("Device code (works on SSH/VPS):")}
|
|
|
9929
10189
|
|
|
9930
10190
|
// src/agents/codex/app-launch.ts
|
|
9931
10191
|
import { execSync as execSync3, spawn as spawn4 } from "child_process";
|
|
9932
|
-
import { existsSync as
|
|
10192
|
+
import { existsSync as existsSync12, readdirSync, statSync as statSync3 } from "fs";
|
|
9933
10193
|
import { homedir as homedir8 } from "os";
|
|
9934
|
-
import { join as
|
|
10194
|
+
import { join as join13 } from "path";
|
|
9935
10195
|
import * as p6 from "@clack/prompts";
|
|
9936
10196
|
var CODEX_BUNDLE_ID = "com.openai.codex";
|
|
9937
10197
|
var DARWIN_APP_NAMES = ["ChatGPT", "Codex"];
|
|
@@ -9950,33 +10210,33 @@ function runPowerShell(script) {
|
|
|
9950
10210
|
function darwinAppCandidates() {
|
|
9951
10211
|
return DARWIN_APP_NAMES.flatMap((name) => [
|
|
9952
10212
|
`/Applications/${name}.app`,
|
|
9953
|
-
|
|
10213
|
+
join13(homedir8(), "Applications", `${name}.app`)
|
|
9954
10214
|
]);
|
|
9955
10215
|
}
|
|
9956
10216
|
function winLocalAppData() {
|
|
9957
|
-
return process.env.LOCALAPPDATA ??
|
|
10217
|
+
return process.env.LOCALAPPDATA ?? join13(homedir8(), "AppData", "Local");
|
|
9958
10218
|
}
|
|
9959
10219
|
function winCodexExeCandidates() {
|
|
9960
10220
|
const local = winLocalAppData();
|
|
9961
10221
|
const bases = WIN_APP_NAMES.flatMap((name) => [
|
|
9962
|
-
|
|
9963
|
-
|
|
9964
|
-
|
|
9965
|
-
|
|
9966
|
-
|
|
10222
|
+
join13(local, "Programs", name),
|
|
10223
|
+
join13(local, "Programs", `OpenAI ${name}`),
|
|
10224
|
+
join13(local, name),
|
|
10225
|
+
join13(local, `OpenAI ${name}`),
|
|
10226
|
+
join13(local, "OpenAI", name)
|
|
9967
10227
|
]);
|
|
9968
|
-
bases.push(
|
|
10228
|
+
bases.push(join13(local, "openai-codex-electron"), join13(local, "openai-chatgpt-electron"));
|
|
9969
10229
|
const out = [];
|
|
9970
10230
|
for (const base of bases) {
|
|
9971
10231
|
for (const name of WIN_APP_NAMES) {
|
|
9972
|
-
out.push(
|
|
10232
|
+
out.push(join13(base, `${name}.exe`));
|
|
9973
10233
|
}
|
|
9974
10234
|
try {
|
|
9975
|
-
if (
|
|
10235
|
+
if (existsSync12(base)) {
|
|
9976
10236
|
for (const dir of readdirSync(base)) {
|
|
9977
10237
|
if (dir.startsWith("app-")) {
|
|
9978
10238
|
for (const name of WIN_APP_NAMES) {
|
|
9979
|
-
out.push(
|
|
10239
|
+
out.push(join13(base, dir, `${name}.exe`));
|
|
9980
10240
|
}
|
|
9981
10241
|
}
|
|
9982
10242
|
}
|
|
@@ -9990,7 +10250,7 @@ function mdfindCodexApp() {
|
|
|
9990
10250
|
try {
|
|
9991
10251
|
const out = run(`mdfind "kMDItemCFBundleIdentifier == '${CODEX_BUNDLE_ID}'"`);
|
|
9992
10252
|
const first = out.split("\n").map((l) => l.trim()).find(Boolean);
|
|
9993
|
-
return first &&
|
|
10253
|
+
return first && existsSync12(first) ? first : null;
|
|
9994
10254
|
} catch {
|
|
9995
10255
|
return null;
|
|
9996
10256
|
}
|
|
@@ -9998,14 +10258,14 @@ function mdfindCodexApp() {
|
|
|
9998
10258
|
function findCodexApp() {
|
|
9999
10259
|
if (process.platform === "darwin") {
|
|
10000
10260
|
for (const path of darwinAppCandidates()) {
|
|
10001
|
-
if (
|
|
10261
|
+
if (existsSync12(path)) return path;
|
|
10002
10262
|
}
|
|
10003
10263
|
return mdfindCodexApp();
|
|
10004
10264
|
}
|
|
10005
10265
|
if (process.platform === "win32") {
|
|
10006
10266
|
for (const path of winCodexExeCandidates()) {
|
|
10007
10267
|
try {
|
|
10008
|
-
if (
|
|
10268
|
+
if (existsSync12(path) && statSync3(path).isFile()) return path;
|
|
10009
10269
|
} catch {
|
|
10010
10270
|
}
|
|
10011
10271
|
}
|
|
@@ -10151,9 +10411,9 @@ function codexAppInstallHint() {
|
|
|
10151
10411
|
|
|
10152
10412
|
// src/agents/claude/desktop-launch.ts
|
|
10153
10413
|
import { execSync as execSync4, spawn as spawn5 } from "child_process";
|
|
10154
|
-
import { existsSync as
|
|
10414
|
+
import { existsSync as existsSync13, readdirSync as readdirSync2, statSync as statSync4 } from "fs";
|
|
10155
10415
|
import { homedir as homedir9 } from "os";
|
|
10156
|
-
import { join as
|
|
10416
|
+
import { join as join14 } from "path";
|
|
10157
10417
|
import * as p7 from "@clack/prompts";
|
|
10158
10418
|
var CLAUDE_BUNDLE_ID = "com.anthropic.claudefordesktop";
|
|
10159
10419
|
function claudeAppSupported() {
|
|
@@ -10170,26 +10430,26 @@ function runPowerShell2(script) {
|
|
|
10170
10430
|
function darwinAppCandidates2() {
|
|
10171
10431
|
return [
|
|
10172
10432
|
"/Applications/Claude.app",
|
|
10173
|
-
|
|
10433
|
+
join14(homedir9(), "Applications", "Claude.app")
|
|
10174
10434
|
];
|
|
10175
10435
|
}
|
|
10176
10436
|
function winLocalAppData2() {
|
|
10177
|
-
return process.env.LOCALAPPDATA ??
|
|
10437
|
+
return process.env.LOCALAPPDATA ?? join14(homedir9(), "AppData", "Local");
|
|
10178
10438
|
}
|
|
10179
10439
|
function winClaudeExeCandidates() {
|
|
10180
10440
|
const local = winLocalAppData2();
|
|
10181
10441
|
const bases = [
|
|
10182
|
-
|
|
10183
|
-
|
|
10442
|
+
join14(local, "Programs", "Claude"),
|
|
10443
|
+
join14(local, "Claude")
|
|
10184
10444
|
];
|
|
10185
10445
|
const out = [];
|
|
10186
10446
|
for (const base of bases) {
|
|
10187
|
-
out.push(
|
|
10447
|
+
out.push(join14(base, "Claude.exe"));
|
|
10188
10448
|
try {
|
|
10189
|
-
if (
|
|
10449
|
+
if (existsSync13(base)) {
|
|
10190
10450
|
for (const name of readdirSync2(base)) {
|
|
10191
10451
|
if (name.startsWith("app-")) {
|
|
10192
|
-
out.push(
|
|
10452
|
+
out.push(join14(base, name, "Claude.exe"));
|
|
10193
10453
|
}
|
|
10194
10454
|
}
|
|
10195
10455
|
}
|
|
@@ -10202,7 +10462,7 @@ function mdfindClaudeApp() {
|
|
|
10202
10462
|
try {
|
|
10203
10463
|
const out = run2(`mdfind "kMDItemCFBundleIdentifier == '${CLAUDE_BUNDLE_ID}'"`);
|
|
10204
10464
|
const first = out.split("\n").map((l) => l.trim()).find(Boolean);
|
|
10205
|
-
return first &&
|
|
10465
|
+
return first && existsSync13(first) ? first : null;
|
|
10206
10466
|
} catch {
|
|
10207
10467
|
return null;
|
|
10208
10468
|
}
|
|
@@ -10210,14 +10470,14 @@ function mdfindClaudeApp() {
|
|
|
10210
10470
|
function findClaudeApp() {
|
|
10211
10471
|
if (process.platform === "darwin") {
|
|
10212
10472
|
for (const path of darwinAppCandidates2()) {
|
|
10213
|
-
if (
|
|
10473
|
+
if (existsSync13(path)) return path;
|
|
10214
10474
|
}
|
|
10215
10475
|
return mdfindClaudeApp();
|
|
10216
10476
|
}
|
|
10217
10477
|
if (process.platform === "win32") {
|
|
10218
10478
|
for (const path of winClaudeExeCandidates()) {
|
|
10219
10479
|
try {
|
|
10220
|
-
if (
|
|
10480
|
+
if (existsSync13(path) && statSync4(path).isFile()) return path;
|
|
10221
10481
|
} catch {
|
|
10222
10482
|
}
|
|
10223
10483
|
}
|
|
@@ -10489,6 +10749,7 @@ export {
|
|
|
10489
10749
|
encodeToolUseId,
|
|
10490
10750
|
serializeToolResultContent,
|
|
10491
10751
|
translateRequest,
|
|
10752
|
+
aggregateAnalytics,
|
|
10492
10753
|
aliasModelId,
|
|
10493
10754
|
startProxyCatalog,
|
|
10494
10755
|
startProxy,
|
|
@@ -10556,4 +10817,4 @@ export {
|
|
|
10556
10817
|
quitClaudeAppGracefully,
|
|
10557
10818
|
launchOrRestartClaudeApp
|
|
10558
10819
|
};
|
|
10559
|
-
//# sourceMappingURL=chunk-
|
|
10820
|
+
//# sourceMappingURL=chunk-E2MV3GDX.js.map
|