@codexhost/cli-win32-x64 0.2.1 → 0.2.2
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/README.md +2 -2
- package/app/codexhost-distribution.json +1 -1
- package/app/host-runtime.mjs +165 -70
- package/app/renderer-extension.js +298 -51
- package/bin/codexhost.exe +0 -0
- package/libexec/codexhost-shim.exe +0 -0
- package/libexec/codexhost-updater.exe +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Run Pi and Claude Code as first-class external harnesses inside Codex Desktop.
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npm install -g @codexhost/cli@0.2.
|
|
10
|
+
npm install -g @codexhost/cli@0.2.2
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
Do not install this package directly. npm selects it through the optional dependencies of `@codexhost/cli`.
|
|
@@ -32,7 +32,7 @@ The `codexhost` command launches the packaged Rust launcher with:
|
|
|
32
32
|
## Requirements
|
|
33
33
|
|
|
34
34
|
- Node.js 22 or 24 (Node 20 and older are not supported)
|
|
35
|
-
- Official Codex Desktop for macOS or
|
|
35
|
+
- Official ChatGPT/Codex Desktop for macOS, Windows, or Linux
|
|
36
36
|
- Pi on `PATH` when using the Pi agent
|
|
37
37
|
- Claude Code installed when using the Claude Code adapter
|
|
38
38
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"schemaVersion":1,"version":"0.2.
|
|
1
|
+
{"schemaVersion":1,"version":"0.2.2","distribution":"npm","target":"windows-x64"}
|
package/app/host-runtime.mjs
CHANGED
|
@@ -51911,6 +51911,7 @@ function isSyntheticGrokTurnKey(nativeTurnKey3) {
|
|
|
51911
51911
|
return taskCompletedTurnKeyPattern.test(nativeTurnKey3);
|
|
51912
51912
|
}
|
|
51913
51913
|
function mapGrokReplay(replay, harnessId, sessionId, knownTurnRefs = []) {
|
|
51914
|
+
const knownByNativeKey = new Map(knownTurnRefs.filter((ref) => ref.harnessId === harnessId && ref.nativeSessionId === sessionId).map((ref) => [ref.nativeTurnKey, ref]));
|
|
51914
51915
|
const turns = [];
|
|
51915
51916
|
let input = "";
|
|
51916
51917
|
let items = [];
|
|
@@ -51941,13 +51942,11 @@ function mapGrokReplay(replay, harnessId, sessionId, knownTurnRefs = []) {
|
|
|
51941
51942
|
const completeTurn = (outcome, terminalKey) => {
|
|
51942
51943
|
if (input.length === 0)
|
|
51943
51944
|
return;
|
|
51944
|
-
const
|
|
51945
|
-
if (
|
|
51946
|
-
throw new Error("Known Grok Turn identity does not belong to the Native Session");
|
|
51947
|
-
}
|
|
51948
|
-
const stableKey = known?.nativeTurnKey ?? terminalKey ?? nativeTurnKey3;
|
|
51949
|
-
if (!stableKey)
|
|
51945
|
+
const reconstructedKey = terminalKey ?? nativeTurnKey3;
|
|
51946
|
+
if (!reconstructedKey)
|
|
51950
51947
|
throw new Error("Grok Native history Turn has no stable identity");
|
|
51948
|
+
const known = knownByNativeKey.get(reconstructedKey);
|
|
51949
|
+
const stableKey = known?.nativeTurnKey ?? reconstructedKey;
|
|
51951
51950
|
completeReasoning();
|
|
51952
51951
|
completeAgent();
|
|
51953
51952
|
completeTools();
|
|
@@ -52033,9 +52032,6 @@ function mapGrokReplay(replay, harnessId, sessionId, knownTurnRefs = []) {
|
|
|
52033
52032
|
}
|
|
52034
52033
|
}
|
|
52035
52034
|
completeTurn({ status: "unknown", reason: "Grok Native history has no terminal signal" });
|
|
52036
|
-
if (knownTurnRefs.length > turns.length) {
|
|
52037
|
-
throw new Error("Grok Native history is missing persisted Turns");
|
|
52038
|
-
}
|
|
52039
52035
|
return { turns };
|
|
52040
52036
|
}
|
|
52041
52037
|
|
|
@@ -52297,16 +52293,75 @@ function usageFromSignals(value) {
|
|
|
52297
52293
|
return null;
|
|
52298
52294
|
}
|
|
52299
52295
|
}
|
|
52300
|
-
|
|
52301
|
-
|
|
52302
|
-
|
|
52296
|
+
var summedUsageFields = [
|
|
52297
|
+
"inputTokens",
|
|
52298
|
+
"cachedInputTokens",
|
|
52299
|
+
"cacheWriteInputTokens",
|
|
52300
|
+
"outputTokens",
|
|
52301
|
+
"reasoningOutputTokens",
|
|
52302
|
+
"totalTokens"
|
|
52303
|
+
];
|
|
52304
|
+
function nativeCostTicks(value) {
|
|
52305
|
+
if (!isRecord12(value))
|
|
52306
|
+
return void 0;
|
|
52307
|
+
const ticks = value.costUsdTicks;
|
|
52308
|
+
if (typeof ticks !== "number" || !Number.isSafeInteger(ticks) || ticks < 0)
|
|
52309
|
+
return void 0;
|
|
52310
|
+
return ticks;
|
|
52311
|
+
}
|
|
52312
|
+
function historyTurnKey(event, index) {
|
|
52313
|
+
const key = event.nativeTurnKey;
|
|
52314
|
+
if (typeof key === "string" && key.startsWith("task-completed-"))
|
|
52315
|
+
return null;
|
|
52316
|
+
return typeof key === "string" && key.length > 0 ? key : `anon-${index}`;
|
|
52317
|
+
}
|
|
52318
|
+
function sessionUsageFromHistory(events) {
|
|
52319
|
+
const latestByKey = /* @__PURE__ */ new Map();
|
|
52320
|
+
let lastCacheHitRatePercent;
|
|
52321
|
+
let index = 0;
|
|
52322
|
+
for (const event of events) {
|
|
52303
52323
|
if (event?.type !== "turn.completed")
|
|
52304
52324
|
continue;
|
|
52325
|
+
const key = historyTurnKey(event, index);
|
|
52326
|
+
index += 1;
|
|
52327
|
+
if (key === null)
|
|
52328
|
+
continue;
|
|
52305
52329
|
const usage = usageFromNative(event.usage);
|
|
52306
|
-
if (usage)
|
|
52307
|
-
|
|
52330
|
+
if (!usage)
|
|
52331
|
+
continue;
|
|
52332
|
+
const ticks2 = nativeCostTicks(event.usage);
|
|
52333
|
+
latestByKey.set(key, ticks2 === void 0 ? { usage } : { usage, ticks: ticks2 });
|
|
52334
|
+
if (usage.cacheHitRatePercent !== void 0) {
|
|
52335
|
+
lastCacheHitRatePercent = usage.cacheHitRatePercent;
|
|
52336
|
+
}
|
|
52337
|
+
}
|
|
52338
|
+
if (latestByKey.size === 0)
|
|
52339
|
+
return null;
|
|
52340
|
+
const totals = {};
|
|
52341
|
+
let ticks = 0;
|
|
52342
|
+
let hasTicks = false;
|
|
52343
|
+
for (const entry of latestByKey.values()) {
|
|
52344
|
+
for (const field of summedUsageFields) {
|
|
52345
|
+
const value = entry.usage[field];
|
|
52346
|
+
if (value === void 0)
|
|
52347
|
+
continue;
|
|
52348
|
+
totals[field] = (totals[field] ?? 0) + value;
|
|
52349
|
+
}
|
|
52350
|
+
if (entry.ticks === void 0)
|
|
52351
|
+
continue;
|
|
52352
|
+
ticks += entry.ticks;
|
|
52353
|
+
hasTicks = true;
|
|
52354
|
+
}
|
|
52355
|
+
const totalCostUsd = hasTicks ? optionalCostUsd(ticks) : void 0;
|
|
52356
|
+
try {
|
|
52357
|
+
return parseHostUsage({
|
|
52358
|
+
...totals,
|
|
52359
|
+
...totalCostUsd !== void 0 ? { totalCostUsd } : {},
|
|
52360
|
+
...lastCacheHitRatePercent !== void 0 ? { cacheHitRatePercent: lastCacheHitRatePercent } : {}
|
|
52361
|
+
});
|
|
52362
|
+
} catch {
|
|
52363
|
+
return null;
|
|
52308
52364
|
}
|
|
52309
|
-
return null;
|
|
52310
52365
|
}
|
|
52311
52366
|
function usageFromUpdate(update, metadata, contextWindowTokens) {
|
|
52312
52367
|
try {
|
|
@@ -52434,6 +52489,7 @@ var GrokHarnessSession = class {
|
|
|
52434
52489
|
#cwd;
|
|
52435
52490
|
#modelState;
|
|
52436
52491
|
#onClosed;
|
|
52492
|
+
#refreshCredits;
|
|
52437
52493
|
#randomUUID;
|
|
52438
52494
|
#snapshot;
|
|
52439
52495
|
#toolOutputLimit;
|
|
@@ -52449,6 +52505,7 @@ var GrokHarnessSession = class {
|
|
|
52449
52505
|
this.#transport = transport;
|
|
52450
52506
|
this.#modelState = modelState;
|
|
52451
52507
|
this.#onClosed = onClosed;
|
|
52508
|
+
this.#refreshCredits = options.refreshCredits;
|
|
52452
52509
|
this.#closeTimeoutMs = options.closeTimeoutMs;
|
|
52453
52510
|
this.#randomUUID = options.randomUUID;
|
|
52454
52511
|
this.#toolOutputLimit = options.toolOutputLimit;
|
|
@@ -52715,11 +52772,7 @@ var GrokHarnessSession = class {
|
|
|
52715
52772
|
this.#startTool(active, event);
|
|
52716
52773
|
else if (event.type === "tool.update")
|
|
52717
52774
|
this.#updateTool(active, event);
|
|
52718
|
-
else if (event.type === "turn.completed")
|
|
52719
|
-
const usage = usageFromNative(event.usage);
|
|
52720
|
-
if (usage)
|
|
52721
|
-
this.#publishUsage(usage, active.command.turnId);
|
|
52722
|
-
} else if (event.type === "usage")
|
|
52775
|
+
else if (event.type === "usage" || event.type === "turn.completed")
|
|
52723
52776
|
return;
|
|
52724
52777
|
}
|
|
52725
52778
|
#appendAgent(active, text, messageId) {
|
|
@@ -52856,7 +52909,8 @@ var GrokHarnessSession = class {
|
|
|
52856
52909
|
outcome = { status: "failed", error: normalizeError(error52, "protocolError") };
|
|
52857
52910
|
}
|
|
52858
52911
|
}
|
|
52859
|
-
this.#
|
|
52912
|
+
await this.#refreshCredits().catch(() => void 0);
|
|
52913
|
+
this.#finish(active, outcome, sessionUsageFromHistory(history) ?? (response ? usageFromPrompt(response) : null), nativeTurnRef2);
|
|
52860
52914
|
}
|
|
52861
52915
|
#finish(active, outcome, usage = null, nativeTurnRef2) {
|
|
52862
52916
|
if (this.#active !== active)
|
|
@@ -53086,13 +53140,14 @@ var GrokAdapter = class {
|
|
|
53086
53140
|
}
|
|
53087
53141
|
}
|
|
53088
53142
|
const history = await transport.getHistory();
|
|
53089
|
-
const initialUsage = input.kind === "resume" ? combineUsage(
|
|
53143
|
+
const initialUsage = input.kind === "resume" ? combineUsage(sessionUsageFromHistory(history), usageFromSignals(opened.signals)) : null;
|
|
53090
53144
|
const openedSession = new GrokHarnessSession(cwd, transport, opened, modelState, () => this.#sessions.delete(openedSession), {
|
|
53091
53145
|
closeTimeoutMs: this.#closeTimeoutMs,
|
|
53092
53146
|
history,
|
|
53093
53147
|
initialUsage,
|
|
53094
53148
|
...input.kind === "resume" && input.knownTurnRefs ? { knownTurnRefs: input.knownTurnRefs } : {},
|
|
53095
53149
|
randomUUID: this.#dependencies.randomUUID,
|
|
53150
|
+
refreshCredits: () => this.refreshCredits(),
|
|
53096
53151
|
toolOutputLimit: this.#toolOutputLimit
|
|
53097
53152
|
});
|
|
53098
53153
|
session = openedSession;
|
|
@@ -53558,27 +53613,28 @@ function pathCandidates(command, platform, environment) {
|
|
|
53558
53613
|
const extensions = platform === "win32" && targetPath.extname(command) === "" ? (environmentValue2(environment, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD").split(";").map((extension) => extension.trim()).filter(Boolean) : [""];
|
|
53559
53614
|
return (environmentValue2(environment, "PATH") ?? "").split(targetPath.delimiter).map((directory) => directory.trim().replace(/^"|"$/gu, "")).filter(Boolean).flatMap((directory) => extensions.map((extension) => targetPath.join(directory, command + extension)));
|
|
53560
53615
|
}
|
|
53561
|
-
function nvmCandidates2(homeDirectory, executableName) {
|
|
53562
|
-
const versionsDirectory =
|
|
53616
|
+
function nvmCandidates2(homeDirectory, executableName, targetPath) {
|
|
53617
|
+
const versionsDirectory = targetPath.join(homeDirectory, ".nvm", "versions", "node");
|
|
53563
53618
|
try {
|
|
53564
|
-
return readdirSync2(versionsDirectory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((left, right) => right.localeCompare(left, void 0, { numeric: true })).map((version2) =>
|
|
53619
|
+
return readdirSync2(versionsDirectory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((left, right) => right.localeCompare(left, void 0, { numeric: true })).map((version2) => targetPath.join(versionsDirectory, version2, "bin", executableName));
|
|
53565
53620
|
} catch {
|
|
53566
53621
|
return [];
|
|
53567
53622
|
}
|
|
53568
53623
|
}
|
|
53569
53624
|
function userInstallCandidates2(platform, environment, homeDirectory) {
|
|
53625
|
+
const targetPath = platform === "win32" ? path11.win32 : path11.posix;
|
|
53570
53626
|
if (platform === "win32") {
|
|
53571
|
-
const appData = environment.APPDATA ??
|
|
53627
|
+
const appData = environment.APPDATA ?? targetPath.join(homeDirectory, "AppData", "Roaming");
|
|
53572
53628
|
return [
|
|
53573
|
-
|
|
53574
|
-
|
|
53575
|
-
|
|
53629
|
+
targetPath.join(appData, "npm", "pi.cmd"),
|
|
53630
|
+
targetPath.join(homeDirectory, ".local", "bin", "pi.exe"),
|
|
53631
|
+
targetPath.join(homeDirectory, ".local", "bin", "pi.cmd")
|
|
53576
53632
|
];
|
|
53577
53633
|
}
|
|
53578
53634
|
return [
|
|
53579
|
-
|
|
53580
|
-
|
|
53581
|
-
...nvmCandidates2(homeDirectory, "pi"),
|
|
53635
|
+
targetPath.join(homeDirectory, ".npm-global", "bin", "pi"),
|
|
53636
|
+
targetPath.join(homeDirectory, ".local", "bin", "pi"),
|
|
53637
|
+
...nvmCandidates2(homeDirectory, "pi", targetPath),
|
|
53582
53638
|
"/opt/homebrew/bin/pi",
|
|
53583
53639
|
"/usr/local/bin/pi"
|
|
53584
53640
|
];
|
|
@@ -56244,6 +56300,18 @@ function isNodeExecutable(value) {
|
|
|
56244
56300
|
function lockOwnerIsLive(lock) {
|
|
56245
56301
|
if (typeof lock.pid !== "number")
|
|
56246
56302
|
return false;
|
|
56303
|
+
if (lock.pid === process.pid) {
|
|
56304
|
+
if (lock.executablePath && normalizeExecutablePath(lock.executablePath) !== normalizeExecutablePath(process.execPath)) {
|
|
56305
|
+
return false;
|
|
56306
|
+
}
|
|
56307
|
+
if (lock.processStartedAt) {
|
|
56308
|
+
const expected = Date.parse(lock.processStartedAt);
|
|
56309
|
+
const actual = Date.now() - process.uptime() * 1e3;
|
|
56310
|
+
if (Number.isFinite(expected) && Math.abs(actual - expected) > 5e3)
|
|
56311
|
+
return false;
|
|
56312
|
+
}
|
|
56313
|
+
return true;
|
|
56314
|
+
}
|
|
56247
56315
|
const identity = processIdentity(lock.pid);
|
|
56248
56316
|
if (!identity)
|
|
56249
56317
|
return false;
|
|
@@ -56423,27 +56491,29 @@ var MappingStore = class {
|
|
|
56423
56491
|
if (current.state !== "ready" || !current.nativeSessionRef) {
|
|
56424
56492
|
throw new MappingStoreError("MAPPING_CONFLICT", "Only a ready Thread can reconcile Snapshot mappings");
|
|
56425
56493
|
}
|
|
56426
|
-
const
|
|
56427
|
-
|
|
56428
|
-
|
|
56429
|
-
|
|
56430
|
-
const
|
|
56431
|
-
|
|
56432
|
-
const
|
|
56433
|
-
if (
|
|
56494
|
+
const byHost = new Map(current.turnMappings.map((mapping) => [mapping.hostTurnId, mapping]));
|
|
56495
|
+
const byNative = new Map(current.turnMappings.map((mapping) => [nativeTurnKey(mapping), mapping]));
|
|
56496
|
+
const seenHost = /* @__PURE__ */ new Set();
|
|
56497
|
+
const seenNative = /* @__PURE__ */ new Set();
|
|
56498
|
+
const ordered = mappings.map((update) => {
|
|
56499
|
+
const hostMatch = byHost.get(update.hostTurnId);
|
|
56500
|
+
const nativeMatch = byNative.get(nativeTurnKey(update));
|
|
56501
|
+
if (hostMatch && nativeMatch && hostMatch !== nativeMatch) {
|
|
56502
|
+
throw new MappingStoreError("MAPPING_CONFLICT", "Turn identity mapping conflicts");
|
|
56503
|
+
}
|
|
56504
|
+
if (hostMatch && !sameJson(hostMatch.nativeTurnRef, update.nativeTurnRef)) {
|
|
56505
|
+
throw new MappingStoreError("MAPPING_CONFLICT", "Host Turn maps to another Native Turn");
|
|
56506
|
+
}
|
|
56507
|
+
if (nativeMatch && nativeMatch.hostTurnId !== update.hostTurnId) {
|
|
56508
|
+
throw new MappingStoreError("MAPPING_CONFLICT", "Native Turn maps to another Host Turn");
|
|
56509
|
+
}
|
|
56510
|
+
if (seenHost.has(update.hostTurnId) || seenNative.has(nativeTurnKey(update))) {
|
|
56434
56511
|
throw new MappingStoreError("MAPPING_CONFLICT", "Snapshot reconciliation contains a duplicate Turn mapping");
|
|
56435
56512
|
}
|
|
56436
|
-
|
|
56513
|
+
seenHost.add(update.hostTurnId);
|
|
56514
|
+
seenNative.add(nativeTurnKey(update));
|
|
56515
|
+
return { ...update };
|
|
56437
56516
|
});
|
|
56438
|
-
const orderedIndexByHost = new Map(ordered.map(({ hostTurnId }, index) => [hostTurnId, index]));
|
|
56439
|
-
let previousIndex = -1;
|
|
56440
|
-
for (const existing of current.turnMappings) {
|
|
56441
|
-
const nextIndex = orderedIndexByHost.get(existing.hostTurnId);
|
|
56442
|
-
if (nextIndex === void 0 || nextIndex <= previousIndex) {
|
|
56443
|
-
throw new MappingStoreError("MAPPING_CONFLICT", "Snapshot reconciliation reordered an existing Turn mapping");
|
|
56444
|
-
}
|
|
56445
|
-
previousIndex = nextIndex;
|
|
56446
|
-
}
|
|
56447
56517
|
return sameJson(current.turnMappings, ordered) ? null : { ...current, turnMappings: ordered };
|
|
56448
56518
|
});
|
|
56449
56519
|
}
|
|
@@ -58454,25 +58524,14 @@ var ExternalThreadRepository = class {
|
|
|
58454
58524
|
...turn.checkpoint ? { nativeCheckpointRef: turn.checkpoint } : {}
|
|
58455
58525
|
};
|
|
58456
58526
|
return {
|
|
58457
|
-
existing,
|
|
58458
58527
|
snapshot: turn,
|
|
58459
58528
|
mapping: {
|
|
58460
58529
|
...mapping,
|
|
58530
|
+
nativeTurnRef: turn.nativeTurnRef,
|
|
58461
58531
|
...turn.checkpoint ? { nativeCheckpointRef: turn.checkpoint } : {}
|
|
58462
58532
|
}
|
|
58463
58533
|
};
|
|
58464
58534
|
});
|
|
58465
|
-
let existingIndex = 0;
|
|
58466
|
-
for (const { existing } of aligned) {
|
|
58467
|
-
if (!existing) continue;
|
|
58468
|
-
if (existing.hostTurnId !== record3.turnMappings[existingIndex]?.hostTurnId) {
|
|
58469
|
-
throw new Error("Persisted Turn mappings do not match the Native Snapshot order");
|
|
58470
|
-
}
|
|
58471
|
-
existingIndex += 1;
|
|
58472
|
-
}
|
|
58473
|
-
if (existingIndex !== record3.turnMappings.length) {
|
|
58474
|
-
throw new Error("Persisted Turn mappings do not match the Native Snapshot order");
|
|
58475
|
-
}
|
|
58476
58535
|
const orderedMappings = aligned.map(({ mapping }) => mapping);
|
|
58477
58536
|
const mappingsChanged = orderedMappings.length !== record3.turnMappings.length || orderedMappings.some((mapping, index) => {
|
|
58478
58537
|
const persisted = record3.turnMappings[index];
|
|
@@ -59795,6 +59854,7 @@ function officialEnvironment(source) {
|
|
|
59795
59854
|
"CODEXHOST_STOCK_CODEX_PATH",
|
|
59796
59855
|
"CODEXHOST_LAUNCHER_PID",
|
|
59797
59856
|
"CODEXHOST_LAUNCHER_EXECUTABLE",
|
|
59857
|
+
"CODEXHOST_RUNTIME_DESCRIPTOR_PATH",
|
|
59798
59858
|
"CODEXHOST_CONTROL_PORT",
|
|
59799
59859
|
"CODEXHOST_CONTROL_NONCE",
|
|
59800
59860
|
"CODEXHOST_NPM_NODE_PATH",
|
|
@@ -61681,6 +61741,7 @@ function parseUpdateStatus(value) {
|
|
|
61681
61741
|
var UPDATE_RUNTIME_ENV = Object.freeze({
|
|
61682
61742
|
launcherPid: "CODEXHOST_LAUNCHER_PID",
|
|
61683
61743
|
launcherExecutable: "CODEXHOST_LAUNCHER_EXECUTABLE",
|
|
61744
|
+
runtimeDescriptorPath: "CODEXHOST_RUNTIME_DESCRIPTOR_PATH",
|
|
61684
61745
|
controllerPort: "CODEXHOST_CONTROL_PORT",
|
|
61685
61746
|
controllerNonce: "CODEXHOST_CONTROL_NONCE",
|
|
61686
61747
|
npmNodePath: "CODEXHOST_NPM_NODE_PATH",
|
|
@@ -61700,7 +61761,7 @@ function parseDistributionMetadata(value) {
|
|
|
61700
61761
|
if (Object.keys(metadata).some((key) => !allowed2.includes(key))) {
|
|
61701
61762
|
throw new Error("distribution metadata contains unknown fields");
|
|
61702
61763
|
}
|
|
61703
|
-
if (metadata.schemaVersion !== 1 || metadata.distribution !== "npm" && metadata.distribution !== "installer" || !["macos-arm64", "macos-x64", "windows-x64", "windows-arm64"].includes(String(metadata.target)) || typeof metadata.version !== "string") {
|
|
61764
|
+
if (metadata.schemaVersion !== 1 || metadata.distribution !== "npm" && metadata.distribution !== "installer" || !["macos-arm64", "macos-x64", "windows-x64", "windows-arm64", "linux-x64"].includes(String(metadata.target)) || typeof metadata.version !== "string") {
|
|
61704
61765
|
throw new Error("distribution metadata is invalid");
|
|
61705
61766
|
}
|
|
61706
61767
|
return {
|
|
@@ -61731,6 +61792,8 @@ function expectedTarget(platform, architecture) {
|
|
|
61731
61792
|
return "windows-arm64";
|
|
61732
61793
|
if (platform === "win32" && architecture === "x64")
|
|
61733
61794
|
return "windows-x64";
|
|
61795
|
+
if (platform === "linux" && architecture === "x64")
|
|
61796
|
+
return "linux-x64";
|
|
61734
61797
|
throw new Error(`unsupported update host ${platform}/${architecture}`);
|
|
61735
61798
|
}
|
|
61736
61799
|
function defaultUpdateStateDirectory(platform = process.platform, environment = process.env) {
|
|
@@ -61765,6 +61828,7 @@ async function resolveInstalledUpdateContext(options) {
|
|
|
61765
61828
|
}
|
|
61766
61829
|
const launcherPid = positiveEnvironmentInteger(environment, UPDATE_RUNTIME_ENV.launcherPid);
|
|
61767
61830
|
const launcherExecutable = absoluteEnvironmentPath(environment, UPDATE_RUNTIME_ENV.launcherExecutable);
|
|
61831
|
+
const runtimeDescriptorPath = absoluteEnvironmentPath(environment, UPDATE_RUNTIME_ENV.runtimeDescriptorPath);
|
|
61768
61832
|
const stateDirectory = path15.normalize(options.stateDirectory ?? defaultUpdateStateDirectory(platform, environment));
|
|
61769
61833
|
const resourcesRoot = path15.dirname(appDirectory);
|
|
61770
61834
|
const installationRoot = platform === "darwin" ? path15.dirname(path15.dirname(resourcesRoot)) : resourcesRoot;
|
|
@@ -61773,6 +61837,7 @@ async function resolveInstalledUpdateContext(options) {
|
|
|
61773
61837
|
version: metadata.version,
|
|
61774
61838
|
launcherPid,
|
|
61775
61839
|
launcherExecutable,
|
|
61840
|
+
runtimeDescriptorPath,
|
|
61776
61841
|
updaterExecutable,
|
|
61777
61842
|
stateDirectory
|
|
61778
61843
|
};
|
|
@@ -62194,9 +62259,33 @@ async function verifyDownloadedArtifact(source, filePath, result) {
|
|
|
62194
62259
|
|
|
62195
62260
|
// packages/update-manager/dist/update-manager.js
|
|
62196
62261
|
var REQUEST_SCHEMA_VERSION = 1;
|
|
62262
|
+
var WINDOWS_RENAME_RETRY_DELAYS_MS = [10, 30, 70, 150, 300];
|
|
62197
62263
|
function errorMessage4(error52) {
|
|
62198
62264
|
return error52 instanceof Error ? error52.message : String(error52);
|
|
62199
62265
|
}
|
|
62266
|
+
function systemErrorCode2(error52) {
|
|
62267
|
+
return typeof error52 === "object" && error52 !== null && "code" in error52 ? String(error52.code) : null;
|
|
62268
|
+
}
|
|
62269
|
+
function delay4(milliseconds) {
|
|
62270
|
+
return new Promise((resolve2) => setTimeout(resolve2, milliseconds));
|
|
62271
|
+
}
|
|
62272
|
+
async function replaceStatusFile(temporaryPath, statusPath) {
|
|
62273
|
+
let retryIndex = 0;
|
|
62274
|
+
for (; ; ) {
|
|
62275
|
+
try {
|
|
62276
|
+
await rename2(temporaryPath, statusPath);
|
|
62277
|
+
return;
|
|
62278
|
+
} catch (error52) {
|
|
62279
|
+
const retryDelay = WINDOWS_RENAME_RETRY_DELAYS_MS[retryIndex];
|
|
62280
|
+
const code = systemErrorCode2(error52);
|
|
62281
|
+
if (process.platform !== "win32" || retryDelay === void 0 || code !== "EACCES" && code !== "EBUSY" && code !== "EPERM") {
|
|
62282
|
+
throw error52;
|
|
62283
|
+
}
|
|
62284
|
+
retryIndex += 1;
|
|
62285
|
+
await delay4(retryDelay);
|
|
62286
|
+
}
|
|
62287
|
+
}
|
|
62288
|
+
}
|
|
62200
62289
|
function requireAbsolutePath(value, label) {
|
|
62201
62290
|
if (!path17.isAbsolute(value))
|
|
62202
62291
|
throw new Error(`${label} must be an absolute path`);
|
|
@@ -62251,7 +62340,7 @@ function createBackgroundUpdateManager(dependencies = {}) {
|
|
|
62251
62340
|
mode: 384,
|
|
62252
62341
|
flag: "wx"
|
|
62253
62342
|
});
|
|
62254
|
-
await
|
|
62343
|
+
await replaceStatusFile(temporaryPath, statusPath);
|
|
62255
62344
|
} catch (error52) {
|
|
62256
62345
|
await rm4(temporaryPath, { force: true });
|
|
62257
62346
|
throw error52;
|
|
@@ -62299,6 +62388,7 @@ function createBackgroundUpdateManager(dependencies = {}) {
|
|
|
62299
62388
|
const version2 = requireSemanticVersion(options.version);
|
|
62300
62389
|
const launcherPid = requireLauncherPid(options.launcherPid);
|
|
62301
62390
|
const launcherExecutable = await requireRegularFile(options.launcherExecutable, "Launcher executable");
|
|
62391
|
+
const runtimeDescriptorPath = requireAbsolutePath(options.runtimeDescriptorPath, "runtime descriptor path");
|
|
62302
62392
|
const updaterExecutable = await requireRegularFile(options.updaterExecutable, "Updater executable");
|
|
62303
62393
|
const stateDirectory = requireAbsolutePath(options.stateDirectory, "update state directory");
|
|
62304
62394
|
await mkdir3(stateDirectory, { recursive: true, mode: 448 });
|
|
@@ -62317,6 +62407,7 @@ function createBackgroundUpdateManager(dependencies = {}) {
|
|
|
62317
62407
|
version: version2,
|
|
62318
62408
|
launcherPid,
|
|
62319
62409
|
launcherExecutable,
|
|
62410
|
+
runtimeDescriptorPath,
|
|
62320
62411
|
workDirectory,
|
|
62321
62412
|
helperPath,
|
|
62322
62413
|
requestPath,
|
|
@@ -62352,6 +62443,7 @@ function createBackgroundUpdateManager(dependencies = {}) {
|
|
|
62352
62443
|
version: common.version,
|
|
62353
62444
|
wait_pid: common.launcherPid,
|
|
62354
62445
|
wait_executable: common.launcherExecutable,
|
|
62446
|
+
runtime_descriptor_path: common.runtimeDescriptorPath,
|
|
62355
62447
|
status_path: common.statusPath,
|
|
62356
62448
|
installation
|
|
62357
62449
|
};
|
|
@@ -62469,9 +62561,11 @@ function createHostUpdateCoordinator(options) {
|
|
|
62469
62561
|
return publicStatus(discovered.status);
|
|
62470
62562
|
}
|
|
62471
62563
|
async function installable(context, release) {
|
|
62472
|
-
if (context.
|
|
62564
|
+
if (context.installation.kind === "npm") return true;
|
|
62565
|
+
const target = context.metadata.target;
|
|
62566
|
+
if (target === "linux-x64") return false;
|
|
62473
62567
|
try {
|
|
62474
|
-
selectInstallerReleaseArtifact(release,
|
|
62568
|
+
selectInstallerReleaseArtifact(release, target);
|
|
62475
62569
|
return true;
|
|
62476
62570
|
} catch {
|
|
62477
62571
|
return false;
|
|
@@ -62569,10 +62663,11 @@ function createHostUpdateCoordinator(options) {
|
|
|
62569
62663
|
onPrepared
|
|
62570
62664
|
});
|
|
62571
62665
|
} else {
|
|
62572
|
-
const
|
|
62573
|
-
|
|
62574
|
-
|
|
62575
|
-
|
|
62666
|
+
const target = context.metadata.target;
|
|
62667
|
+
if (target === "linux-x64") {
|
|
62668
|
+
throw new Error("Linux installer updates are unsupported");
|
|
62669
|
+
}
|
|
62670
|
+
const artifact = selectInstallerReleaseArtifact(release, target).source;
|
|
62576
62671
|
prepared2 = context.installation.kind === "windows-installer" ? await manager.prepareWindowsInstaller({
|
|
62577
62672
|
...context.installation.options,
|
|
62578
62673
|
version: release.version,
|
|
@@ -16429,30 +16429,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16429
16429
|
function formatRendererCreditsPercent(value) {
|
|
16430
16430
|
return `${decimal(value, 1)}%`;
|
|
16431
16431
|
}
|
|
16432
|
-
function rendererUsageTriggerMaxWidth(
|
|
16433
|
-
return
|
|
16434
|
-
}
|
|
16435
|
-
function formatRendererCreditsReset(value) {
|
|
16436
|
-
const date5 = new Date(value);
|
|
16437
|
-
if (Number.isNaN(date5.getTime())) return value;
|
|
16438
|
-
return date5.toLocaleString(void 0, {
|
|
16439
|
-
month: "long",
|
|
16440
|
-
day: "numeric",
|
|
16441
|
-
hour: "numeric",
|
|
16442
|
-
minute: "2-digit"
|
|
16443
|
-
});
|
|
16444
|
-
}
|
|
16445
|
-
function creditsPeriodLabel(periodType) {
|
|
16446
|
-
if (periodType === "weekly") return "Weekly limit";
|
|
16447
|
-
if (periodType === "monthly") return "Monthly limit";
|
|
16448
|
-
return "Account limit";
|
|
16449
|
-
}
|
|
16450
|
-
function productLabel(product) {
|
|
16451
|
-
if (product === "GrokBuild") return "Build";
|
|
16452
|
-
if (product === "GrokChat") return "Chat";
|
|
16453
|
-
if (product === "GrokImagine") return "Imagine";
|
|
16454
|
-
if (product === "GrokVoice") return "Voice";
|
|
16455
|
-
return product;
|
|
16432
|
+
function rendererUsageTriggerMaxWidth() {
|
|
16433
|
+
return "min(180px, 30vw)";
|
|
16456
16434
|
}
|
|
16457
16435
|
function addDetailRow(parent, label, value) {
|
|
16458
16436
|
const row = document.createElement("div");
|
|
@@ -16470,30 +16448,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16470
16448
|
row.append(labelElement, valueElement);
|
|
16471
16449
|
parent.append(row);
|
|
16472
16450
|
}
|
|
16473
|
-
function renderDetails(popover, usage
|
|
16451
|
+
function renderDetails(popover, usage) {
|
|
16474
16452
|
popover.replaceChildren();
|
|
16475
16453
|
const heading = document.createElement("div");
|
|
16476
16454
|
heading.textContent = "Usage";
|
|
16477
16455
|
heading.style.fontWeight = "600";
|
|
16478
16456
|
heading.style.marginBottom = "6px";
|
|
16479
16457
|
popover.append(heading);
|
|
16480
|
-
if (accountCredits) {
|
|
16481
|
-
addDetailRow(
|
|
16482
|
-
popover,
|
|
16483
|
-
creditsPeriodLabel(accountCredits.periodType),
|
|
16484
|
-
formatRendererCreditsPercent(accountCredits.usedPercent)
|
|
16485
|
-
);
|
|
16486
|
-
if (accountCredits.resetsAt) {
|
|
16487
|
-
addDetailRow(popover, "Resets", formatRendererCreditsReset(accountCredits.resetsAt));
|
|
16488
|
-
}
|
|
16489
|
-
for (const product of accountCredits.productUsage ?? []) {
|
|
16490
|
-
addDetailRow(
|
|
16491
|
-
popover,
|
|
16492
|
-
productLabel(product.product),
|
|
16493
|
-
formatRendererCreditsPercent(product.usagePercent)
|
|
16494
|
-
);
|
|
16495
|
-
}
|
|
16496
|
-
}
|
|
16497
16458
|
if (usage?.contextUsedTokens !== void 0 && usage.contextWindowTokens !== void 0) {
|
|
16498
16459
|
const contextPercent = usage.contextWindowTokens > 0 ? usage.contextUsedTokens / usage.contextWindowTokens * 100 : null;
|
|
16499
16460
|
addDetailRow(
|
|
@@ -16586,7 +16547,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16586
16547
|
trigger.style.display = "inline-flex";
|
|
16587
16548
|
trigger.style.alignItems = "center";
|
|
16588
16549
|
trigger.style.width = "fit-content";
|
|
16589
|
-
trigger.style.maxWidth = rendererUsageTriggerMaxWidth(
|
|
16550
|
+
trigger.style.maxWidth = rendererUsageTriggerMaxWidth();
|
|
16590
16551
|
trigger.style.height = "24px";
|
|
16591
16552
|
trigger.style.padding = "0 4px";
|
|
16592
16553
|
trigger.style.borderRadius = "9999px";
|
|
@@ -16689,33 +16650,281 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16689
16650
|
document.body.append(popover);
|
|
16690
16651
|
return control;
|
|
16691
16652
|
}
|
|
16692
|
-
function renderRendererUsageControl(control, usage
|
|
16653
|
+
function renderRendererUsageControl(control, usage) {
|
|
16693
16654
|
const cacheHitRatePercent = usage?.cacheHitRatePercent;
|
|
16694
16655
|
const outputTokensPerSecond = usage?.outputTokensPerSecond;
|
|
16695
16656
|
const totalCostUsd = usage?.totalCostUsd;
|
|
16696
16657
|
const hasCacheHitRate = cacheHitRatePercent !== void 0;
|
|
16697
16658
|
const hasOutputSpeed = outputTokensPerSecond !== void 0;
|
|
16698
16659
|
const hasCost = totalCostUsd !== void 0;
|
|
16699
|
-
const
|
|
16700
|
-
const visible = hasCacheHitRate || hasOutputSpeed || hasCost || hasCredits;
|
|
16660
|
+
const visible = hasCacheHitRate || hasOutputSpeed || hasCost;
|
|
16701
16661
|
control.root.style.display = visible ? "inline-flex" : "none";
|
|
16702
16662
|
if (!visible) {
|
|
16703
16663
|
closePopover(control);
|
|
16704
16664
|
return false;
|
|
16705
16665
|
}
|
|
16706
16666
|
const summary = [
|
|
16707
|
-
accountCredits ? `${creditsPeriodLabel(accountCredits.periodType)} ${formatRendererCreditsPercent(accountCredits.usedPercent)}` : null,
|
|
16708
16667
|
cacheHitRatePercent !== void 0 ? formatRendererCacheHitRate(cacheHitRatePercent) : null,
|
|
16709
16668
|
outputTokensPerSecond !== void 0 ? formatRendererTokenRate(outputTokensPerSecond) : null,
|
|
16710
16669
|
totalCostUsd !== void 0 ? formatRendererCost(totalCostUsd) : null
|
|
16711
16670
|
].filter((value) => value !== null);
|
|
16712
16671
|
const compactSummary = summary.join(" \xB7 ");
|
|
16713
16672
|
const accessibleSummary = `Thread Usage: ${compactSummary}`;
|
|
16714
|
-
control.trigger.style.maxWidth = rendererUsageTriggerMaxWidth(
|
|
16673
|
+
control.trigger.style.maxWidth = rendererUsageTriggerMaxWidth();
|
|
16715
16674
|
control.trigger.setAttribute("aria-label", accessibleSummary);
|
|
16716
16675
|
control.trigger.title = accessibleSummary;
|
|
16717
16676
|
control.label.textContent = compactSummary;
|
|
16718
|
-
renderDetails(control.popover, usage
|
|
16677
|
+
renderDetails(control.popover, usage);
|
|
16678
|
+
return true;
|
|
16679
|
+
}
|
|
16680
|
+
|
|
16681
|
+
// src/renderer-credits-control.ts
|
|
16682
|
+
function rendererCreditsTone(usedPercent) {
|
|
16683
|
+
if (usedPercent >= 90) return "hot";
|
|
16684
|
+
if (usedPercent >= 70) return "warn";
|
|
16685
|
+
return "ok";
|
|
16686
|
+
}
|
|
16687
|
+
function formatRendererCreditsReset(value) {
|
|
16688
|
+
const date5 = new Date(value);
|
|
16689
|
+
if (Number.isNaN(date5.getTime())) return value;
|
|
16690
|
+
return date5.toLocaleString(void 0, {
|
|
16691
|
+
month: "long",
|
|
16692
|
+
day: "numeric",
|
|
16693
|
+
hour: "numeric",
|
|
16694
|
+
minute: "2-digit"
|
|
16695
|
+
});
|
|
16696
|
+
}
|
|
16697
|
+
function creditsPeriodLabel(periodType) {
|
|
16698
|
+
if (periodType === "weekly") return "Weekly limit";
|
|
16699
|
+
if (periodType === "monthly") return "Monthly limit";
|
|
16700
|
+
return "Account limit";
|
|
16701
|
+
}
|
|
16702
|
+
function productLabel(product) {
|
|
16703
|
+
if (product === "GrokBuild") return "Build";
|
|
16704
|
+
if (product === "GrokChat") return "Chat";
|
|
16705
|
+
if (product === "GrokImagine") return "Imagine";
|
|
16706
|
+
if (product === "GrokVoice") return "Voice";
|
|
16707
|
+
return product;
|
|
16708
|
+
}
|
|
16709
|
+
function toneColor(tone) {
|
|
16710
|
+
if (tone === "hot") return "#c45c4a";
|
|
16711
|
+
if (tone === "warn") return "#c9a227";
|
|
16712
|
+
return "#3d9a64";
|
|
16713
|
+
}
|
|
16714
|
+
function addDetailRow2(parent, label, value) {
|
|
16715
|
+
const row = document.createElement("div");
|
|
16716
|
+
row.style.display = "grid";
|
|
16717
|
+
row.style.gridTemplateColumns = "minmax(0, 1fr) auto";
|
|
16718
|
+
row.style.gap = "20px";
|
|
16719
|
+
row.style.padding = "4px 0";
|
|
16720
|
+
const labelElement = document.createElement("span");
|
|
16721
|
+
labelElement.textContent = label;
|
|
16722
|
+
labelElement.style.color = "color-mix(in srgb, currentColor 68%, transparent)";
|
|
16723
|
+
const valueElement = document.createElement("span");
|
|
16724
|
+
valueElement.textContent = value;
|
|
16725
|
+
valueElement.style.fontVariantNumeric = "tabular-nums";
|
|
16726
|
+
valueElement.style.textAlign = "right";
|
|
16727
|
+
row.append(labelElement, valueElement);
|
|
16728
|
+
parent.append(row);
|
|
16729
|
+
}
|
|
16730
|
+
function renderDetails2(popover, credits) {
|
|
16731
|
+
popover.replaceChildren();
|
|
16732
|
+
const heading = document.createElement("div");
|
|
16733
|
+
heading.textContent = creditsPeriodLabel(credits.periodType);
|
|
16734
|
+
heading.style.fontWeight = "600";
|
|
16735
|
+
heading.style.marginBottom = "6px";
|
|
16736
|
+
popover.append(heading);
|
|
16737
|
+
addDetailRow2(popover, "Used", formatRendererCreditsPercent(credits.usedPercent));
|
|
16738
|
+
if (credits.resetsAt) {
|
|
16739
|
+
addDetailRow2(popover, "Resets", formatRendererCreditsReset(credits.resetsAt));
|
|
16740
|
+
}
|
|
16741
|
+
for (const product of credits.productUsage ?? []) {
|
|
16742
|
+
addDetailRow2(
|
|
16743
|
+
popover,
|
|
16744
|
+
productLabel(product.product),
|
|
16745
|
+
formatRendererCreditsPercent(product.usagePercent)
|
|
16746
|
+
);
|
|
16747
|
+
}
|
|
16748
|
+
}
|
|
16749
|
+
function popoverIsOpen2(popover) {
|
|
16750
|
+
try {
|
|
16751
|
+
return popover.matches(":popover-open");
|
|
16752
|
+
} catch {
|
|
16753
|
+
return !popover.hidden;
|
|
16754
|
+
}
|
|
16755
|
+
}
|
|
16756
|
+
function positionPopover2(control) {
|
|
16757
|
+
const triggerRect = control.trigger.getBoundingClientRect();
|
|
16758
|
+
const width = Math.min(280, Math.max(220, window.innerWidth - 24));
|
|
16759
|
+
const left = Math.max(12, Math.min(triggerRect.left, window.innerWidth - width - 12));
|
|
16760
|
+
control.popover.style.width = `${width}px`;
|
|
16761
|
+
control.popover.style.left = `${left}px`;
|
|
16762
|
+
control.popover.style.right = "auto";
|
|
16763
|
+
control.popover.style.top = "auto";
|
|
16764
|
+
control.popover.style.bottom = `${Math.max(12, window.innerHeight - triggerRect.top + 8)}px`;
|
|
16765
|
+
}
|
|
16766
|
+
function closePopover2(control) {
|
|
16767
|
+
if (popoverIsOpen2(control.popover) && typeof control.popover.hidePopover === "function") {
|
|
16768
|
+
control.popover.hidePopover();
|
|
16769
|
+
}
|
|
16770
|
+
control.popover.hidden = true;
|
|
16771
|
+
control.trigger.setAttribute("aria-expanded", "false");
|
|
16772
|
+
}
|
|
16773
|
+
function openPopover2(control) {
|
|
16774
|
+
positionPopover2(control);
|
|
16775
|
+
control.popover.hidden = false;
|
|
16776
|
+
if (typeof control.popover.showPopover === "function" && !popoverIsOpen2(control.popover)) {
|
|
16777
|
+
control.popover.showPopover();
|
|
16778
|
+
}
|
|
16779
|
+
control.trigger.setAttribute("aria-expanded", "true");
|
|
16780
|
+
}
|
|
16781
|
+
function togglePopover2(control) {
|
|
16782
|
+
if (control.trigger.getAttribute("aria-expanded") === "true") closePopover2(control);
|
|
16783
|
+
else openPopover2(control);
|
|
16784
|
+
}
|
|
16785
|
+
function mountRendererCreditsControl(composerId, nativeModelClassName) {
|
|
16786
|
+
const root = document.createElement("div");
|
|
16787
|
+
root.dataset.codexhostCreditsControl = composerId;
|
|
16788
|
+
root.className = "relative min-w-0";
|
|
16789
|
+
root.style.display = "none";
|
|
16790
|
+
const trigger = document.createElement("button");
|
|
16791
|
+
const syncNativeModelClassName = (className) => {
|
|
16792
|
+
trigger.className = className?.trim() || RENDERER_MODEL_TRIGGER_FALLBACK_CLASSES;
|
|
16793
|
+
};
|
|
16794
|
+
syncNativeModelClassName(nativeModelClassName);
|
|
16795
|
+
trigger.type = "button";
|
|
16796
|
+
trigger.setAttribute("aria-haspopup", "dialog");
|
|
16797
|
+
trigger.setAttribute("aria-expanded", "false");
|
|
16798
|
+
trigger.setAttribute("aria-label", "Account limit");
|
|
16799
|
+
trigger.title = "Account limit";
|
|
16800
|
+
trigger.style.display = "inline-flex";
|
|
16801
|
+
trigger.style.alignItems = "center";
|
|
16802
|
+
trigger.style.gap = "5px";
|
|
16803
|
+
trigger.style.width = "fit-content";
|
|
16804
|
+
trigger.style.maxWidth = "min(72px, 18vw)";
|
|
16805
|
+
trigger.style.height = "24px";
|
|
16806
|
+
trigger.style.padding = "0 6px";
|
|
16807
|
+
trigger.style.borderRadius = "9999px";
|
|
16808
|
+
trigger.style.fontSize = "12px";
|
|
16809
|
+
trigger.style.lineHeight = "16px";
|
|
16810
|
+
trigger.style.fontVariantNumeric = "tabular-nums";
|
|
16811
|
+
trigger.style.letterSpacing = "0";
|
|
16812
|
+
trigger.style.whiteSpace = "nowrap";
|
|
16813
|
+
trigger.style.cursor = "pointer";
|
|
16814
|
+
const dot = document.createElement("span");
|
|
16815
|
+
dot.dataset.codexhostCreditsDot = "";
|
|
16816
|
+
dot.setAttribute("aria-hidden", "true");
|
|
16817
|
+
dot.style.display = "inline-block";
|
|
16818
|
+
dot.style.width = "7px";
|
|
16819
|
+
dot.style.height = "7px";
|
|
16820
|
+
dot.style.borderRadius = "9999px";
|
|
16821
|
+
dot.style.flex = "0 0 auto";
|
|
16822
|
+
const label = document.createElement("span");
|
|
16823
|
+
label.dataset.codexhostCreditsLabel = "";
|
|
16824
|
+
label.style.display = "inline-block";
|
|
16825
|
+
label.style.maxWidth = "100%";
|
|
16826
|
+
label.style.overflow = "hidden";
|
|
16827
|
+
label.style.textOverflow = "ellipsis";
|
|
16828
|
+
label.style.whiteSpace = "nowrap";
|
|
16829
|
+
trigger.append(dot, label);
|
|
16830
|
+
const popover = document.createElement("div");
|
|
16831
|
+
popover.id = `${composerId}-credits-popover`;
|
|
16832
|
+
popover.setAttribute("role", "dialog");
|
|
16833
|
+
popover.setAttribute("aria-label", "Account limit details");
|
|
16834
|
+
popover.setAttribute("popover", "auto");
|
|
16835
|
+
popover.hidden = typeof popover.showPopover !== "function";
|
|
16836
|
+
popover.style.position = "fixed";
|
|
16837
|
+
popover.style.inset = "auto";
|
|
16838
|
+
popover.style.width = "240px";
|
|
16839
|
+
popover.style.maxWidth = "min(280px, calc(100vw - 24px))";
|
|
16840
|
+
popover.style.padding = "10px 12px";
|
|
16841
|
+
popover.style.border = "1px solid rgba(127, 127, 127, 0.35)";
|
|
16842
|
+
popover.style.borderRadius = "6px";
|
|
16843
|
+
popover.style.background = "Canvas";
|
|
16844
|
+
popover.style.color = "CanvasText";
|
|
16845
|
+
popover.style.boxShadow = "0 8px 24px rgba(0, 0, 0, 0.28)";
|
|
16846
|
+
popover.style.font = "13px/1.35 system-ui, sans-serif";
|
|
16847
|
+
popover.style.letterSpacing = "0";
|
|
16848
|
+
popover.style.zIndex = "2147483647";
|
|
16849
|
+
trigger.setAttribute("aria-controls", popover.id);
|
|
16850
|
+
let placementReference = null;
|
|
16851
|
+
const control = {
|
|
16852
|
+
root,
|
|
16853
|
+
trigger,
|
|
16854
|
+
popover,
|
|
16855
|
+
anchor: null,
|
|
16856
|
+
syncNativeModelClassName,
|
|
16857
|
+
dispose() {
|
|
16858
|
+
closePopover2(control);
|
|
16859
|
+
if (closeTimer !== null) window.clearTimeout(closeTimer);
|
|
16860
|
+
root.remove();
|
|
16861
|
+
popover.remove();
|
|
16862
|
+
placementReference = null;
|
|
16863
|
+
},
|
|
16864
|
+
place(anchor) {
|
|
16865
|
+
if (!anchor?.parentElement) return false;
|
|
16866
|
+
const parent = anchor.parentElement;
|
|
16867
|
+
const next = anchor.nextElementSibling;
|
|
16868
|
+
if (control.anchor === anchor && placementReference === anchor && root.parentElement === parent && root.previousElementSibling === anchor) {
|
|
16869
|
+
return true;
|
|
16870
|
+
}
|
|
16871
|
+
control.anchor = anchor;
|
|
16872
|
+
placementReference = anchor;
|
|
16873
|
+
if (next && next !== root) parent.insertBefore(root, next);
|
|
16874
|
+
else if (next !== root) parent.append(root);
|
|
16875
|
+
return true;
|
|
16876
|
+
}
|
|
16877
|
+
};
|
|
16878
|
+
let closeTimer = null;
|
|
16879
|
+
const cancelClose = () => {
|
|
16880
|
+
if (closeTimer === null) return;
|
|
16881
|
+
window.clearTimeout(closeTimer);
|
|
16882
|
+
closeTimer = null;
|
|
16883
|
+
};
|
|
16884
|
+
const scheduleClose = () => {
|
|
16885
|
+
cancelClose();
|
|
16886
|
+
closeTimer = window.setTimeout(() => {
|
|
16887
|
+
closeTimer = null;
|
|
16888
|
+
if (!trigger.matches(":hover") && !popover.matches(":hover")) closePopover2(control);
|
|
16889
|
+
}, 140);
|
|
16890
|
+
};
|
|
16891
|
+
trigger.addEventListener("click", () => togglePopover2(control));
|
|
16892
|
+
trigger.addEventListener("pointerenter", () => {
|
|
16893
|
+
cancelClose();
|
|
16894
|
+
openPopover2(control);
|
|
16895
|
+
});
|
|
16896
|
+
trigger.addEventListener("pointerleave", scheduleClose);
|
|
16897
|
+
trigger.addEventListener("focus", () => {
|
|
16898
|
+
cancelClose();
|
|
16899
|
+
openPopover2(control);
|
|
16900
|
+
});
|
|
16901
|
+
trigger.addEventListener("blur", scheduleClose);
|
|
16902
|
+
popover.addEventListener("pointerenter", cancelClose);
|
|
16903
|
+
popover.addEventListener("pointerleave", scheduleClose);
|
|
16904
|
+
popover.addEventListener("toggle", () => {
|
|
16905
|
+
trigger.setAttribute("aria-expanded", String(popoverIsOpen2(popover)));
|
|
16906
|
+
});
|
|
16907
|
+
root.append(trigger);
|
|
16908
|
+
document.body.append(popover);
|
|
16909
|
+
return control;
|
|
16910
|
+
}
|
|
16911
|
+
function renderRendererCreditsControl(control, accountCredits) {
|
|
16912
|
+
if (accountCredits === null) {
|
|
16913
|
+
control.root.style.display = "none";
|
|
16914
|
+
closePopover2(control);
|
|
16915
|
+
return false;
|
|
16916
|
+
}
|
|
16917
|
+
const percent = formatRendererCreditsPercent(accountCredits.usedPercent);
|
|
16918
|
+
const title = `${creditsPeriodLabel(accountCredits.periodType)} ${percent}`;
|
|
16919
|
+
const tone = rendererCreditsTone(accountCredits.usedPercent);
|
|
16920
|
+
const dot = control.trigger.querySelector("[data-codexhost-credits-dot]");
|
|
16921
|
+
const label = control.trigger.querySelector("[data-codexhost-credits-label]");
|
|
16922
|
+
if (dot) dot.style.background = toneColor(tone);
|
|
16923
|
+
if (label) label.textContent = percent;
|
|
16924
|
+
control.root.style.display = "inline-flex";
|
|
16925
|
+
control.trigger.setAttribute("aria-label", title);
|
|
16926
|
+
control.trigger.title = title;
|
|
16927
|
+
renderDetails2(control.popover, accountCredits);
|
|
16719
16928
|
return true;
|
|
16720
16929
|
}
|
|
16721
16930
|
|
|
@@ -16830,7 +17039,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16830
17039
|
}
|
|
16831
17040
|
var contextUsageDescriptionPattern = /(context|token|上下文|令牌)/iu;
|
|
16832
17041
|
function isNativeContextUsageControlCandidate(element) {
|
|
16833
|
-
if (element.hasAttribute("data-codexhost-usage-control"))
|
|
17042
|
+
if (element.hasAttribute("data-codexhost-usage-control") || element.hasAttribute("data-codexhost-credits-control")) {
|
|
17043
|
+
return false;
|
|
17044
|
+
}
|
|
16834
17045
|
const description = [
|
|
16835
17046
|
element.getAttribute("aria-label"),
|
|
16836
17047
|
element.getAttribute("title"),
|
|
@@ -16863,6 +17074,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16863
17074
|
const candidate = nativeModelControlForComposer(control.composer);
|
|
16864
17075
|
if (!candidate) {
|
|
16865
17076
|
control.usage.syncNativeModelClassName();
|
|
17077
|
+
control.credits.syncNativeModelClassName();
|
|
16866
17078
|
return;
|
|
16867
17079
|
}
|
|
16868
17080
|
if (candidate !== control.nativeModelControl?.element) {
|
|
@@ -16871,6 +17083,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16871
17083
|
syncRendererModelTriggerClass(control.modelPicker, candidate.className);
|
|
16872
17084
|
}
|
|
16873
17085
|
control.usage.syncNativeModelClassName(candidate.className);
|
|
17086
|
+
control.credits.syncNativeModelClassName(candidate.className);
|
|
16874
17087
|
}
|
|
16875
17088
|
function usagePlacementAnchor(control) {
|
|
16876
17089
|
const context = nativeContextUsageControlForComposer(control.composer);
|
|
@@ -16880,14 +17093,44 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16880
17093
|
const native = control.nativeModelControl?.element;
|
|
16881
17094
|
return native?.parentElement ? native : null;
|
|
16882
17095
|
}
|
|
17096
|
+
function firstMaterialChild(parent) {
|
|
17097
|
+
for (const child of parent.children) {
|
|
17098
|
+
if (typeof child.hasAttribute !== "function") continue;
|
|
17099
|
+
const element = child;
|
|
17100
|
+
if (element.hasAttribute("data-codexhost-credits-control")) continue;
|
|
17101
|
+
return element;
|
|
17102
|
+
}
|
|
17103
|
+
return null;
|
|
17104
|
+
}
|
|
17105
|
+
function creditsPlacementAnchor(composer, usageRoot) {
|
|
17106
|
+
let current = usageRoot;
|
|
17107
|
+
while (current && current !== composer) {
|
|
17108
|
+
const parent = current.parentElement;
|
|
17109
|
+
if (!parent) break;
|
|
17110
|
+
const first = firstMaterialChild(parent);
|
|
17111
|
+
if (first && first !== current && !first.contains(usageRoot)) return first;
|
|
17112
|
+
if (parent === composer) break;
|
|
17113
|
+
current = parent;
|
|
17114
|
+
}
|
|
17115
|
+
return null;
|
|
17116
|
+
}
|
|
16883
17117
|
function refreshUsagePlacement(control) {
|
|
16884
17118
|
const anchor = usagePlacementAnchor(control);
|
|
16885
17119
|
if (!anchor) {
|
|
16886
17120
|
if (control.usage.anchor) control.usage.root.remove();
|
|
16887
17121
|
control.usage.anchor = null;
|
|
17122
|
+
if (control.credits.anchor) control.credits.root.remove();
|
|
17123
|
+
control.credits.anchor = null;
|
|
16888
17124
|
return;
|
|
16889
17125
|
}
|
|
16890
17126
|
control.usage.place(anchor);
|
|
17127
|
+
const leading = creditsPlacementAnchor(control.composer, control.usage.root);
|
|
17128
|
+
if (!leading) {
|
|
17129
|
+
if (control.credits.anchor) control.credits.root.remove();
|
|
17130
|
+
control.credits.anchor = null;
|
|
17131
|
+
return;
|
|
17132
|
+
}
|
|
17133
|
+
control.credits.place(leading);
|
|
16891
17134
|
}
|
|
16892
17135
|
function refreshNativePermissionModeControl(control) {
|
|
16893
17136
|
const semanticCandidate = semanticNativePermissionModeControlForComposer(control.composer);
|
|
@@ -16942,6 +17185,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16942
17185
|
onSelectPermissionMode
|
|
16943
17186
|
);
|
|
16944
17187
|
const usage = mountRendererUsageControl(composerId, nativeModelControl?.element.className);
|
|
17188
|
+
const credits = mountRendererCreditsControl(composerId, nativeModelControl?.element.className);
|
|
16945
17189
|
const permissionParent = nativePermissionModeControl?.element.parentElement;
|
|
16946
17190
|
if (permissionParent && nativePermissionModeControl && nativePermissionModeControlVerified) {
|
|
16947
17191
|
permissionParent.insertBefore(permissionModePicker.root, nativePermissionModeControl.element);
|
|
@@ -16964,6 +17208,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16964
17208
|
nativeModelControl,
|
|
16965
17209
|
nativePermissionModeControl,
|
|
16966
17210
|
nativePermissionModeControlVerified,
|
|
17211
|
+
credits,
|
|
16967
17212
|
usage,
|
|
16968
17213
|
sendButton,
|
|
16969
17214
|
sendDisabledBeforeSwitch: null
|
|
@@ -17008,7 +17253,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17008
17253
|
permissionModeView,
|
|
17009
17254
|
permissionModeVisible
|
|
17010
17255
|
);
|
|
17011
|
-
renderRendererUsageControl(control.usage, usage
|
|
17256
|
+
renderRendererUsageControl(control.usage, usage);
|
|
17257
|
+
renderRendererCreditsControl(control.credits, accountCredits);
|
|
17012
17258
|
}
|
|
17013
17259
|
function disposeComposerAgentControl(control) {
|
|
17014
17260
|
if (control.sendDisabledBeforeSwitch !== null) {
|
|
@@ -17016,6 +17262,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17016
17262
|
}
|
|
17017
17263
|
restoreNativeControl(control.nativeModelControl);
|
|
17018
17264
|
restoreNativeControl(control.nativePermissionModeControl);
|
|
17265
|
+
control.credits.dispose();
|
|
17019
17266
|
control.usage.dispose();
|
|
17020
17267
|
control.permissionModePicker.dispose();
|
|
17021
17268
|
control.modelPicker.dispose();
|
package/bin/codexhost.exe
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|