@codexhost/cli-win32-arm64 0.13.1 → 0.13.3
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 +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/console-server.mjs +36 -3
- package/app/console-web.js +100 -78
- package/app/desktop-controller.mjs +36 -3
- package/app/host-runtime.mjs +551 -101
- package/app/plugins/antigravity/plugin.mjs +52 -7
- package/app/plugins/claude-code/plugin.mjs +219 -59
- package/app/plugins/codebuddy/plugin.mjs +110 -8
- package/app/plugins/codex-usage/plugin.mjs +54 -12
- package/app/plugins/cursor-cli/plugin.mjs +71 -10
- package/app/plugins/deepseek-harness/manifest.json +2 -2
- package/app/plugins/deepseek-harness/plugin.mjs +119 -10
- package/app/plugins/grok/plugin.mjs +64 -5
- package/app/plugins/hermes/plugin.mjs +247 -43
- package/app/plugins/kimi-code/plugin.mjs +64 -9
- package/app/plugins/kiro-cli/plugin.mjs +45 -3
- package/app/plugins/omp/plugin.mjs +46 -3
- package/app/plugins/opencode/plugin.mjs +52 -5
- package/app/plugins/pi/plugin.mjs +37 -3
- package/app/plugins/qoder/plugin.mjs +50 -3
- package/app/plugins/qoder-cn/plugin.mjs +50 -3
- package/app/plugins/workbuddy/plugin.mjs +227 -12
- package/app/plugins/zcode/plugin.mjs +49 -3
- package/app/renderer-extension.js +401 -401
- package/bin/codexhost.exe +0 -0
- package/libexec/codexhost-node-repl.exe +0 -0
- package/libexec/codexhost-shim.exe +0 -0
- package/libexec/codexhost-updater.exe +0 -0
- package/package.json +1 -1
package/app/host-runtime.mjs
CHANGED
|
@@ -4295,9 +4295,11 @@ async function runDelegationCli(input) {
|
|
|
4295
4295
|
"INVALID_ARGUMENT",
|
|
4296
4296
|
"--host conflicts with the Thread reference"
|
|
4297
4297
|
);
|
|
4298
|
+
const caller = command === "read" ? callerThreadId(environment) : void 0;
|
|
4298
4299
|
const body = {
|
|
4299
4300
|
...reference,
|
|
4300
4301
|
...hostId2 ? { hostId: hostId2 } : {},
|
|
4302
|
+
...caller ? { callerThreadId: normalizeThreadId(caller) } : {},
|
|
4301
4303
|
view,
|
|
4302
4304
|
...value(parsed2, "--cursor") ? { cursor: value(parsed2, "--cursor") } : {},
|
|
4303
4305
|
...value(parsed2, "--limit") ? { limit: positiveInteger(value(parsed2, "--limit"), "--limit", MAX_LIMIT) } : {},
|
|
@@ -4434,6 +4436,7 @@ import {
|
|
|
4434
4436
|
realpath,
|
|
4435
4437
|
stat,
|
|
4436
4438
|
readdir as readdir2,
|
|
4439
|
+
unlink,
|
|
4437
4440
|
writeFile as writeFile3
|
|
4438
4441
|
} from "node:fs/promises";
|
|
4439
4442
|
import { homedir } from "node:os";
|
|
@@ -19943,6 +19946,7 @@ config(en_default());
|
|
|
19943
19946
|
var REMOTE_THREAD_REPLY_MAX_BYTES = 16 * 1024 * 1024;
|
|
19944
19947
|
var REMOTE_THREAD_CONTROL_TIMEOUT_MS = 4e4;
|
|
19945
19948
|
var DELEGATION_READ_METHOD = "codexhost/thread/delegation-read";
|
|
19949
|
+
var THREAD_REFERENCE_SOURCE_HOST_PARAM = "codexhostSourceHostId";
|
|
19946
19950
|
var delegationReadParamsSchema = external_exports.strictObject({
|
|
19947
19951
|
threadId: external_exports.string().min(1).max(1024),
|
|
19948
19952
|
view: external_exports.enum(["result", "messages"]),
|
|
@@ -20023,6 +20027,15 @@ var harnessDisplaySetSchema = external_exports.strictObject({
|
|
|
20023
20027
|
initializeOnly: external_exports.boolean().optional()
|
|
20024
20028
|
});
|
|
20025
20029
|
|
|
20030
|
+
// packages/shared-contracts/dist/harness-presentation.js
|
|
20031
|
+
var localeSchema = external_exports.string().max(64).regex(/^[a-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/u);
|
|
20032
|
+
var displayText = (maximum) => external_exports.string().min(1).max(maximum).refine((text) => text.trim().length > 0);
|
|
20033
|
+
var harnessLocalizationsSchema = external_exports.record(localeSchema, external_exports.object({
|
|
20034
|
+
label: displayText(256).optional(),
|
|
20035
|
+
description: displayText(1024).optional()
|
|
20036
|
+
}).strict()).refine((entries) => Object.keys(entries).length <= 16, "Too many locales");
|
|
20037
|
+
var harnessLocalizedTextSchema = external_exports.record(localeSchema, displayText(4096)).refine((entries) => typeof entries.en === "string", "English fallback is required").refine((entries) => Object.keys(entries).length <= 16, "Too many locales");
|
|
20038
|
+
|
|
20026
20039
|
// packages/shared-contracts/dist/model-price-overrides.js
|
|
20027
20040
|
var MODEL_PRICE_OVERRIDES_GET_METHOD = "codexhost/usage/model-prices/get";
|
|
20028
20041
|
var MODEL_PRICE_OVERRIDES_SET_METHOD = "codexhost/usage/model-prices/set";
|
|
@@ -20372,8 +20385,24 @@ var threadUsageSnapshotSchema = external_exports.object({
|
|
|
20372
20385
|
}
|
|
20373
20386
|
});
|
|
20374
20387
|
var usagePercentSchema = external_exports.number().finite().min(0).max(100);
|
|
20388
|
+
var accountCreditsPeriodSchema = external_exports.enum([
|
|
20389
|
+
"weekly",
|
|
20390
|
+
"monthly",
|
|
20391
|
+
"five_hour",
|
|
20392
|
+
"seven_day",
|
|
20393
|
+
"unknown"
|
|
20394
|
+
]);
|
|
20395
|
+
var accountCreditsScopeSchema = external_exports.object({
|
|
20396
|
+
id: external_exports.string().min(1).max(256),
|
|
20397
|
+
label: external_exports.string().min(1).max(256),
|
|
20398
|
+
localizations: harnessLocalizationsSchema.optional()
|
|
20399
|
+
}).strict();
|
|
20375
20400
|
var accountCreditsProductUsageSchema = external_exports.object({
|
|
20376
20401
|
product: external_exports.string().min(1),
|
|
20402
|
+
/** Native period and scope, never inferred from the display name. */
|
|
20403
|
+
periodType: accountCreditsPeriodSchema.optional(),
|
|
20404
|
+
scope: accountCreditsScopeSchema.optional(),
|
|
20405
|
+
localizations: harnessLocalizationsSchema.optional(),
|
|
20377
20406
|
used: external_exports.number().finite().nonnegative().optional(),
|
|
20378
20407
|
// Zero is a real empty cap, not an absent field.
|
|
20379
20408
|
limit: external_exports.number().finite().nonnegative().optional(),
|
|
@@ -20393,9 +20422,11 @@ var accountCreditsSnapshotSchema = external_exports.object({
|
|
|
20393
20422
|
unit: external_exports.string().min(1).max(32).optional(),
|
|
20394
20423
|
/** Native label when the primary limit is scoped to a model or product group. */
|
|
20395
20424
|
label: external_exports.string().min(1).optional(),
|
|
20425
|
+
scope: accountCreditsScopeSchema.optional(),
|
|
20426
|
+
localizations: harnessLocalizationsSchema.optional(),
|
|
20396
20427
|
usedPercent: usagePercentSchema,
|
|
20397
20428
|
resetsAt: external_exports.string().min(1).optional(),
|
|
20398
|
-
periodType:
|
|
20429
|
+
periodType: accountCreditsPeriodSchema,
|
|
20399
20430
|
productUsage: external_exports.array(accountCreditsProductUsageSchema).min(1).optional(),
|
|
20400
20431
|
resetCredits: accountResetCreditsSchema.optional()
|
|
20401
20432
|
}).strict();
|
|
@@ -20406,7 +20437,9 @@ var threadUsageInspectionParamsSchema = external_exports.object({
|
|
|
20406
20437
|
var threadUsageInspectionSchema = external_exports.object({
|
|
20407
20438
|
threadId: hostThreadIdSchema,
|
|
20408
20439
|
usage: threadUsageSnapshotSchema.nullable(),
|
|
20409
|
-
accountCredits: accountCreditsSnapshotSchema.optional()
|
|
20440
|
+
accountCredits: accountCreditsSnapshotSchema.optional(),
|
|
20441
|
+
/** Whether this source can provide cached account quota independently of usage. */
|
|
20442
|
+
accountCreditsSupported: external_exports.boolean().optional()
|
|
20410
20443
|
}).strict();
|
|
20411
20444
|
|
|
20412
20445
|
// packages/shared-contracts/dist/harness-accounts.js
|
|
@@ -20533,7 +20566,8 @@ var harnessPermissionModeSchema = external_exports.object({
|
|
|
20533
20566
|
id: harnessPermissionModeIdSchema,
|
|
20534
20567
|
label: nonBlankTextSchema.max(HARNESS_PERMISSION_MODE_LABEL_MAX_LENGTH),
|
|
20535
20568
|
description: nonBlankTextSchema.max(HARNESS_PERMISSION_MODE_DESCRIPTION_MAX_LENGTH).optional(),
|
|
20536
|
-
dangerous: external_exports.boolean().optional()
|
|
20569
|
+
dangerous: external_exports.boolean().optional(),
|
|
20570
|
+
localizations: harnessLocalizationsSchema.optional()
|
|
20537
20571
|
}).strict();
|
|
20538
20572
|
var harnessPermissionModeCatalogSchema = external_exports.object({
|
|
20539
20573
|
modes: external_exports.array(harnessPermissionModeSchema).min(1).max(HARNESS_PERMISSION_MODE_CATALOG_MAX_LENGTH),
|
|
@@ -20957,6 +20991,8 @@ var harnessInstallationStateSchema = external_exports.object({
|
|
|
20957
20991
|
// Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
|
|
20958
20992
|
message: external_exports.string().max(2048).optional(),
|
|
20959
20993
|
messageCode: external_exports.string().min(1).max(128).optional(),
|
|
20994
|
+
/** Safe plugin-owned explanation, distinct from raw diagnostic message. */
|
|
20995
|
+
notice: harnessLocalizedTextSchema.optional(),
|
|
20960
20996
|
latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
|
|
20961
20997
|
}).strict();
|
|
20962
20998
|
|
|
@@ -21087,6 +21123,7 @@ var harnessCommandDescriptorSchema = external_exports.object({
|
|
|
21087
21123
|
invocation: commandInvocationSchema,
|
|
21088
21124
|
label: commandLabelSchema,
|
|
21089
21125
|
description: commandDescriptionSchema.optional(),
|
|
21126
|
+
localizations: harnessLocalizationsSchema.optional(),
|
|
21090
21127
|
argumentMode: external_exports.enum(["none", "text"]),
|
|
21091
21128
|
/**
|
|
21092
21129
|
* Native distinction reported by the Harness. Omitted when the Harness does
|
|
@@ -21467,14 +21504,40 @@ var RuntimeMaintenance = class {
|
|
|
21467
21504
|
options2.environment.CODEXHOST_DATA_DIR ?? path7.join(home, ".codexhost", "remote", "data"),
|
|
21468
21505
|
"remote-update.json"
|
|
21469
21506
|
);
|
|
21507
|
+
this.#cancelPath = path7.join(path7.dirname(this.#statusPath), "remote-update.cancel");
|
|
21470
21508
|
}
|
|
21471
21509
|
options;
|
|
21472
21510
|
#running;
|
|
21473
21511
|
#statusPath;
|
|
21512
|
+
#cancelPath;
|
|
21474
21513
|
#update = { phase: "idle", targetVersion: null, error: null };
|
|
21475
21514
|
#blocked = false;
|
|
21515
|
+
#watch = null;
|
|
21476
21516
|
#starting = null;
|
|
21477
21517
|
#startingVersion = null;
|
|
21518
|
+
get #startTimeoutMs() {
|
|
21519
|
+
return this.options.updaterStartTimeoutMs ?? UPDATER_START_TIMEOUT_MS;
|
|
21520
|
+
}
|
|
21521
|
+
#ensureWatching() {
|
|
21522
|
+
if (this.#watch) return;
|
|
21523
|
+
this.#watch = setInterval(() => {
|
|
21524
|
+
void this.status().catch(() => void 0).then(() => {
|
|
21525
|
+
if (!this.#blocked && this.#watch) {
|
|
21526
|
+
clearInterval(this.#watch);
|
|
21527
|
+
this.#watch = null;
|
|
21528
|
+
}
|
|
21529
|
+
});
|
|
21530
|
+
}, UPDATER_WATCH_INTERVAL_MS);
|
|
21531
|
+
this.#watch.unref();
|
|
21532
|
+
}
|
|
21533
|
+
async #recordStartFailure(version2, failure) {
|
|
21534
|
+
await writeFile3(this.#cancelPath, JSON.stringify({ targetVersion: version2 }), { mode: 384 });
|
|
21535
|
+
await writeFile3(
|
|
21536
|
+
this.#statusPath,
|
|
21537
|
+
JSON.stringify({ phase: "failed", targetVersion: version2, error: failure }),
|
|
21538
|
+
{ mode: 384 }
|
|
21539
|
+
);
|
|
21540
|
+
}
|
|
21478
21541
|
#sshPending = /* @__PURE__ */ new Set();
|
|
21479
21542
|
async setupSsh(input) {
|
|
21480
21543
|
if (this.options.remote) throw new Error("SSH installation must run from the local computer");
|
|
@@ -21535,7 +21598,7 @@ var RuntimeMaintenance = class {
|
|
|
21535
21598
|
installation(this.options.runtimePath, this.options.environment),
|
|
21536
21599
|
this.#resources()
|
|
21537
21600
|
]);
|
|
21538
|
-
if (this.#update.phase === "idle" || this.#blocked) {
|
|
21601
|
+
if (this.#update.phase === "idle" || this.#blocked || this.#update.phase === "failed") {
|
|
21539
21602
|
try {
|
|
21540
21603
|
const value2 = JSON.parse(await readFile5(this.#statusPath, "utf8"));
|
|
21541
21604
|
const parsed2 = runtimeStatusSchema.shape.update.parse(value2);
|
|
@@ -21551,15 +21614,22 @@ var RuntimeMaintenance = class {
|
|
|
21551
21614
|
}
|
|
21552
21615
|
} else {
|
|
21553
21616
|
const written = (await stat(this.#statusPath)).mtimeMs;
|
|
21554
|
-
alive = Date.now() - written <
|
|
21617
|
+
alive = Date.now() - written < this.#startTimeoutMs * 2;
|
|
21555
21618
|
}
|
|
21556
21619
|
if (!alive) {
|
|
21557
21620
|
parsed2.phase = "failed";
|
|
21558
21621
|
parsed2.error = "The previous remote update was interrupted; retry the update";
|
|
21559
21622
|
}
|
|
21560
21623
|
}
|
|
21561
|
-
if (this.#update === observedUpdate)
|
|
21562
|
-
|
|
21624
|
+
if (this.#update === observedUpdate) {
|
|
21625
|
+
this.#update = parsed2;
|
|
21626
|
+
if (["installing", "restarting"].includes(this.#update.phase)) {
|
|
21627
|
+
this.#blocked = true;
|
|
21628
|
+
this.#ensureWatching();
|
|
21629
|
+
} else if (["failed", "succeeded"].includes(this.#update.phase)) {
|
|
21630
|
+
this.#blocked = false;
|
|
21631
|
+
}
|
|
21632
|
+
}
|
|
21563
21633
|
} catch {
|
|
21564
21634
|
}
|
|
21565
21635
|
}
|
|
@@ -21631,6 +21701,7 @@ var RuntimeMaintenance = class {
|
|
|
21631
21701
|
await chmod2(helper, 448);
|
|
21632
21702
|
const request = path7.join(work, "request.json");
|
|
21633
21703
|
this.#update = { phase: "installing", targetVersion: version2, error: null };
|
|
21704
|
+
await unlink(this.#cancelPath).catch(() => void 0);
|
|
21634
21705
|
await writeFile3(this.#statusPath, JSON.stringify(this.#update), { mode: 384 });
|
|
21635
21706
|
await writeFile3(
|
|
21636
21707
|
request,
|
|
@@ -21649,35 +21720,38 @@ var RuntimeMaintenance = class {
|
|
|
21649
21720
|
);
|
|
21650
21721
|
const starter = spawn3(
|
|
21651
21722
|
"/bin/sh",
|
|
21652
|
-
["-c", '"$0" remote --request "$1" </dev/null >/dev/null 2>&1 &', helper, request],
|
|
21653
|
-
{ detached: true, stdio: "ignore", env: this.options.environment }
|
|
21723
|
+
["-c", '"$0" remote --request "$1" </dev/null >/dev/null 2>&1 & echo $!', helper, request],
|
|
21724
|
+
{ detached: true, stdio: ["ignore", "pipe", "ignore"], env: this.options.environment }
|
|
21654
21725
|
);
|
|
21726
|
+
let pidOutput = "";
|
|
21727
|
+
starter.stdout?.on("data", (chunk) => {
|
|
21728
|
+
pidOutput += typeof chunk === "string" ? chunk : chunk.toString("utf8");
|
|
21729
|
+
});
|
|
21655
21730
|
await new Promise((resolve, reject) => {
|
|
21656
21731
|
starter.once("error", reject);
|
|
21657
21732
|
starter.once(
|
|
21658
|
-
"
|
|
21733
|
+
"close",
|
|
21659
21734
|
(code) => code === 0 ? resolve() : reject(new Error("Remote updater could not be started"))
|
|
21660
21735
|
);
|
|
21661
21736
|
});
|
|
21662
|
-
const
|
|
21737
|
+
const helperPid = Number.parseInt(pidOutput.trim(), 10);
|
|
21738
|
+
if (!Number.isSafeInteger(helperPid) || helperPid <= 0) {
|
|
21739
|
+
throw new Error("Remote updater could not be started");
|
|
21740
|
+
}
|
|
21741
|
+
const deadline = Date.now() + this.#startTimeoutMs;
|
|
21663
21742
|
while (!await this.#helperReported()) {
|
|
21664
21743
|
if (Date.now() >= deadline) {
|
|
21744
|
+
try {
|
|
21745
|
+
process.kill(helperPid);
|
|
21746
|
+
} catch {
|
|
21747
|
+
}
|
|
21665
21748
|
const failure = "Remote updater did not start";
|
|
21666
|
-
await
|
|
21667
|
-
this.#statusPath,
|
|
21668
|
-
JSON.stringify({ phase: "failed", targetVersion: version2, error: failure }),
|
|
21669
|
-
{ mode: 384 }
|
|
21670
|
-
);
|
|
21749
|
+
await this.#recordStartFailure(version2, failure);
|
|
21671
21750
|
throw new Error(failure);
|
|
21672
21751
|
}
|
|
21673
21752
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
21674
21753
|
}
|
|
21675
|
-
|
|
21676
|
-
void this.status().catch(() => void 0).then(() => {
|
|
21677
|
-
if (!this.#blocked) clearInterval(watch);
|
|
21678
|
-
});
|
|
21679
|
-
}, UPDATER_WATCH_INTERVAL_MS);
|
|
21680
|
-
watch.unref();
|
|
21754
|
+
this.#ensureWatching();
|
|
21681
21755
|
}
|
|
21682
21756
|
async #helperReported() {
|
|
21683
21757
|
try {
|
|
@@ -21691,6 +21765,7 @@ var RuntimeMaintenance = class {
|
|
|
21691
21765
|
|
|
21692
21766
|
// packages/host-runtime/src/run-host-runtime.ts
|
|
21693
21767
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
21768
|
+
import { statSync } from "node:fs";
|
|
21694
21769
|
import path37 from "node:path";
|
|
21695
21770
|
import { homedir as homedir4 } from "node:os";
|
|
21696
21771
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
@@ -24964,6 +25039,16 @@ function rewriteDelegationMentionInput(input, skill) {
|
|
|
24964
25039
|
return rewritten;
|
|
24965
25040
|
}
|
|
24966
25041
|
|
|
25042
|
+
// packages/harness-adapter/dist/account-credits.js
|
|
25043
|
+
function parseHarnessAccountCredits(value2) {
|
|
25044
|
+
if (!value2 || typeof value2 !== "object" || Array.isArray(value2))
|
|
25045
|
+
return null;
|
|
25046
|
+
const publicValue = { ...value2 };
|
|
25047
|
+
delete publicValue.fetchedAt;
|
|
25048
|
+
const parsed2 = accountCreditsSnapshotSchema.safeParse(publicValue);
|
|
25049
|
+
return parsed2.success ? parsed2.data : null;
|
|
25050
|
+
}
|
|
25051
|
+
|
|
24967
25052
|
// packages/harness-adapter/dist/output-channel.js
|
|
24968
25053
|
var HarnessOutputChannel = class {
|
|
24969
25054
|
outputs;
|
|
@@ -27063,6 +27148,7 @@ function projectCodexRateLimitsToCredits(usage, resetCredits) {
|
|
|
27063
27148
|
const resetsAtUnix = hasFiveHour ? usage.planFiveHourResetsAtUnix : usage.planSevenDayResetsAtUnix;
|
|
27064
27149
|
const secondary = hasFiveHour && hasSevenDay && usage.planSevenDayUsedPercent !== void 0 ? {
|
|
27065
27150
|
product: "7-day window",
|
|
27151
|
+
periodType: "seven_day",
|
|
27066
27152
|
usagePercent: usage.planSevenDayUsedPercent,
|
|
27067
27153
|
...usage.planSevenDayResetsAtUnix !== void 0 ? { resetsAt: isoFromUnix(usage.planSevenDayResetsAtUnix) } : {}
|
|
27068
27154
|
} : void 0;
|
|
@@ -31745,6 +31831,16 @@ var ExternalThreadIdleRelease = class {
|
|
|
31745
31831
|
const state = this.#activity.get(thread);
|
|
31746
31832
|
if (state) state.outputFailed = true;
|
|
31747
31833
|
}
|
|
31834
|
+
/** After a successful Session revival, allow idle release again. */
|
|
31835
|
+
clearOutputFailed(thread) {
|
|
31836
|
+
const state = this.#activity.get(thread);
|
|
31837
|
+
if (state) {
|
|
31838
|
+
state.outputFailed = false;
|
|
31839
|
+
state.lastActivity = Date.now();
|
|
31840
|
+
} else {
|
|
31841
|
+
this.touch(thread);
|
|
31842
|
+
}
|
|
31843
|
+
}
|
|
31748
31844
|
failure(thread) {
|
|
31749
31845
|
return this.#activity.get(thread)?.closeFailed ? CLOSE_FAILURE : void 0;
|
|
31750
31846
|
}
|
|
@@ -31893,6 +31989,80 @@ var ExternalThreadIdleRelease = class {
|
|
|
31893
31989
|
}
|
|
31894
31990
|
};
|
|
31895
31991
|
|
|
31992
|
+
// packages/host-runtime/src/external-thread-lifecycle.ts
|
|
31993
|
+
var RELEASE_TIMEOUT_MS = 6e4;
|
|
31994
|
+
var ExternalSessionReleaseError = class extends Error {
|
|
31995
|
+
constructor(cause) {
|
|
31996
|
+
super(
|
|
31997
|
+
"External Session shutdown could not be confirmed. Retry to confirm release; recovery is blocked until the old Session closes and its output drains. If the Harness cannot retry shutdown, stop residual processes and restart Codex Desktop.",
|
|
31998
|
+
{ cause }
|
|
31999
|
+
);
|
|
32000
|
+
this.name = "ExternalSessionReleaseError";
|
|
32001
|
+
}
|
|
32002
|
+
};
|
|
32003
|
+
var ExternalThreadLifecycle = class {
|
|
32004
|
+
#pending = /* @__PURE__ */ new Map();
|
|
32005
|
+
#closing = /* @__PURE__ */ new WeakMap();
|
|
32006
|
+
#releasing = /* @__PURE__ */ new Map();
|
|
32007
|
+
busy(id2) {
|
|
32008
|
+
return this.#pending.has(id2) || this.#releasing.has(id2);
|
|
32009
|
+
}
|
|
32010
|
+
pending() {
|
|
32011
|
+
return [...this.#pending];
|
|
32012
|
+
}
|
|
32013
|
+
run(id2, operation) {
|
|
32014
|
+
const previous = this.#pending.get(id2) ?? Promise.resolve();
|
|
32015
|
+
const task = previous.then(async () => {
|
|
32016
|
+
const releasing = this.#releasing.get(id2);
|
|
32017
|
+
if (releasing) await this.release(id2, releasing.session, releasing.output);
|
|
32018
|
+
return operation();
|
|
32019
|
+
});
|
|
32020
|
+
const settled = task.then(
|
|
32021
|
+
() => void 0,
|
|
32022
|
+
() => void 0
|
|
32023
|
+
);
|
|
32024
|
+
this.#pending.set(id2, settled);
|
|
32025
|
+
void settled.then(() => {
|
|
32026
|
+
if (this.#pending.get(id2) === settled) this.#pending.delete(id2);
|
|
32027
|
+
});
|
|
32028
|
+
return task;
|
|
32029
|
+
}
|
|
32030
|
+
/** Call inside the Thread's lifecycle operation. A timeout never cancels the owned close. */
|
|
32031
|
+
async release(id2, session, output) {
|
|
32032
|
+
this.#releasing.set(id2, { session, output });
|
|
32033
|
+
let closing = this.#closing.get(session);
|
|
32034
|
+
if (!closing) {
|
|
32035
|
+
closing = Promise.resolve().then(() => session.close());
|
|
32036
|
+
this.#closing.set(session, closing);
|
|
32037
|
+
const attempt = closing;
|
|
32038
|
+
void closing.catch(() => {
|
|
32039
|
+
if (this.#closing.get(session) === attempt) this.#closing.delete(session);
|
|
32040
|
+
});
|
|
32041
|
+
}
|
|
32042
|
+
let timeout;
|
|
32043
|
+
try {
|
|
32044
|
+
await Promise.race([
|
|
32045
|
+
closing.then(() => output),
|
|
32046
|
+
new Promise((_, reject) => {
|
|
32047
|
+
timeout = setTimeout(
|
|
32048
|
+
() => reject(new Error("Session shutdown timed out")),
|
|
32049
|
+
RELEASE_TIMEOUT_MS
|
|
32050
|
+
);
|
|
32051
|
+
timeout.unref();
|
|
32052
|
+
})
|
|
32053
|
+
]);
|
|
32054
|
+
this.#releasing.delete(id2);
|
|
32055
|
+
} catch (error51) {
|
|
32056
|
+
throw new ExternalSessionReleaseError(error51);
|
|
32057
|
+
} finally {
|
|
32058
|
+
if (timeout) clearTimeout(timeout);
|
|
32059
|
+
}
|
|
32060
|
+
}
|
|
32061
|
+
async drain() {
|
|
32062
|
+
while (this.#pending.size) await Promise.all(this.#pending.values());
|
|
32063
|
+
}
|
|
32064
|
+
};
|
|
32065
|
+
|
|
31896
32066
|
// packages/host-runtime/src/usage-metering.ts
|
|
31897
32067
|
var TOKENS_PER_PRICE_UNIT = 1e6;
|
|
31898
32068
|
var UsageMeter = class {
|
|
@@ -32175,6 +32345,11 @@ var ExternalThreadOpenError = class extends Error {
|
|
|
32175
32345
|
function errorMessage3(error51) {
|
|
32176
32346
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
32177
32347
|
}
|
|
32348
|
+
function recoveryError(error51) {
|
|
32349
|
+
if (error51 instanceof ExternalThreadOpenError) return error51.rpcError;
|
|
32350
|
+
if (error51 instanceof ExternalSessionReleaseError) return { code: -32075, message: error51.message };
|
|
32351
|
+
return { code: -32076, message: "External Thread recovery failed; retry the request" };
|
|
32352
|
+
}
|
|
32178
32353
|
var ExternalThreadRuntime = class {
|
|
32179
32354
|
idleRelease;
|
|
32180
32355
|
#adapters;
|
|
@@ -32182,7 +32357,8 @@ var ExternalThreadRuntime = class {
|
|
|
32182
32357
|
#diagnose;
|
|
32183
32358
|
#environment;
|
|
32184
32359
|
#repository;
|
|
32185
|
-
#
|
|
32360
|
+
#lifecycle = new ExternalThreadLifecycle();
|
|
32361
|
+
#hasRunningDescendants;
|
|
32186
32362
|
#subagentRunning;
|
|
32187
32363
|
#threads = /* @__PURE__ */ new Map();
|
|
32188
32364
|
constructor(input) {
|
|
@@ -32192,12 +32368,13 @@ var ExternalThreadRuntime = class {
|
|
|
32192
32368
|
this.#consumeOutputs = input.consumeOutputs;
|
|
32193
32369
|
this.#diagnose = input.diagnose;
|
|
32194
32370
|
this.#subagentRunning = input.subagentRunning ?? (() => false);
|
|
32371
|
+
this.#hasRunningDescendants = input.hasRunningDescendants ?? (() => false);
|
|
32195
32372
|
this.idleRelease = new ExternalThreadIdleRelease({
|
|
32196
32373
|
threads: () => this.values(),
|
|
32197
32374
|
get: (id2) => this.get(id2),
|
|
32198
32375
|
remove: (id2) => this.remove(id2),
|
|
32199
32376
|
queue: input.idleRelease?.queue ?? new DesktopRequestQueue(),
|
|
32200
|
-
canRelease: input.idleRelease?.canRelease
|
|
32377
|
+
canRelease: (thread) => !thread.sessionUnavailable && !this.#lifecycle.busy(thread.id) && (input.idleRelease?.canRelease(thread) ?? false),
|
|
32201
32378
|
...input.idleRelease?.onClosed ? { onClosed: input.idleRelease.onClosed } : {},
|
|
32202
32379
|
diagnose: input.diagnose
|
|
32203
32380
|
});
|
|
@@ -32213,7 +32390,45 @@ var ExternalThreadRuntime = class {
|
|
|
32213
32390
|
}
|
|
32214
32391
|
clear() {
|
|
32215
32392
|
this.#threads.clear();
|
|
32216
|
-
|
|
32393
|
+
}
|
|
32394
|
+
drain() {
|
|
32395
|
+
return this.#lifecycle.drain();
|
|
32396
|
+
}
|
|
32397
|
+
#withLifecycle(threadId2, operation) {
|
|
32398
|
+
return this.#lifecycle.run(threadId2, async () => {
|
|
32399
|
+
await this.idleRelease.waitForClose(threadId2);
|
|
32400
|
+
return operation();
|
|
32401
|
+
});
|
|
32402
|
+
}
|
|
32403
|
+
markSessionUnavailable(thread) {
|
|
32404
|
+
thread.sessionUnavailable = true;
|
|
32405
|
+
}
|
|
32406
|
+
#idleForRestore(thread) {
|
|
32407
|
+
if (thread.running || thread.activeTurnId !== null) return false;
|
|
32408
|
+
if (thread.session.hasBackgroundWork?.()) return false;
|
|
32409
|
+
if (this.#hasRunningDescendants(thread.id)) return false;
|
|
32410
|
+
return true;
|
|
32411
|
+
}
|
|
32412
|
+
async #dropIdleSession(thread) {
|
|
32413
|
+
if (this.#threads.get(thread.id) !== thread) return;
|
|
32414
|
+
thread.sessionUnavailable = true;
|
|
32415
|
+
await this.#lifecycle.release(thread.id, thread.session, thread.outputTask);
|
|
32416
|
+
if (this.#threads.get(thread.id) !== thread) return;
|
|
32417
|
+
await this.#retireSubagents(thread);
|
|
32418
|
+
if (this.#threads.get(thread.id) === thread) this.#threads.delete(thread.id);
|
|
32419
|
+
}
|
|
32420
|
+
/** Called without awaiting from the output consumer: release itself drains that consumer. */
|
|
32421
|
+
async discardUnavailableIdle(thread) {
|
|
32422
|
+
const session = thread.session;
|
|
32423
|
+
try {
|
|
32424
|
+
await this.#withLifecycle(thread.id, async () => {
|
|
32425
|
+
if (this.#threads.get(thread.id) !== thread || thread.session !== session || !thread.sessionUnavailable || !this.#idleForRestore(thread))
|
|
32426
|
+
return;
|
|
32427
|
+
await this.#dropIdleSession(thread);
|
|
32428
|
+
});
|
|
32429
|
+
} catch (error51) {
|
|
32430
|
+
this.#diagnose(error51);
|
|
32431
|
+
}
|
|
32217
32432
|
}
|
|
32218
32433
|
register(input) {
|
|
32219
32434
|
const harnessId = input.record.harnessId;
|
|
@@ -32258,7 +32473,8 @@ var ExternalThreadRuntime = class {
|
|
|
32258
32473
|
ephemeralTurnIds: /* @__PURE__ */ new Set(),
|
|
32259
32474
|
persistenceError: null,
|
|
32260
32475
|
projectedTerminalTurnId: null,
|
|
32261
|
-
ignoredInteractionIds: /* @__PURE__ */ new Set()
|
|
32476
|
+
ignoredInteractionIds: /* @__PURE__ */ new Set(),
|
|
32477
|
+
sessionUnavailable: false
|
|
32262
32478
|
};
|
|
32263
32479
|
this.idleRelease.touch(externalThread);
|
|
32264
32480
|
externalThread.outputTask = this.#consumeOutputs(externalThread);
|
|
@@ -32285,11 +32501,12 @@ var ExternalThreadRuntime = class {
|
|
|
32285
32501
|
} catch (error51) {
|
|
32286
32502
|
this.#diagnose(error51);
|
|
32287
32503
|
}
|
|
32288
|
-
await this.#retireSubagents(current
|
|
32504
|
+
await this.#retireSubagents(current, true);
|
|
32289
32505
|
this.#threads.delete(current.id);
|
|
32290
32506
|
return this.register(input);
|
|
32291
32507
|
}
|
|
32292
|
-
async #retireSubagents(
|
|
32508
|
+
async #retireSubagents(parent, bestEffort = false) {
|
|
32509
|
+
const parentId = parent.id;
|
|
32293
32510
|
const ancestors = /* @__PURE__ */ new Map();
|
|
32294
32511
|
const descendant = async (record4) => {
|
|
32295
32512
|
const visited = /* @__PURE__ */ new Set();
|
|
@@ -32306,24 +32523,35 @@ var ExternalThreadRuntime = class {
|
|
|
32306
32523
|
}
|
|
32307
32524
|
return false;
|
|
32308
32525
|
};
|
|
32309
|
-
for (const [id2,
|
|
32310
|
-
if (await descendant(await this.#repository.find(id2)))
|
|
32311
|
-
await restoring.catch(this.#diagnose);
|
|
32312
|
-
}
|
|
32526
|
+
for (const [id2, pending] of this.#lifecycle.pending()) {
|
|
32527
|
+
if (id2 !== parentId && await descendant(await this.#repository.find(id2))) await pending;
|
|
32313
32528
|
}
|
|
32314
|
-
for (const child of this.#threads.values()) {
|
|
32529
|
+
for (const child of [...this.#threads.values()]) {
|
|
32315
32530
|
if (!await descendant(child.record)) continue;
|
|
32316
|
-
|
|
32317
|
-
|
|
32318
|
-
|
|
32319
|
-
|
|
32320
|
-
|
|
32321
|
-
|
|
32322
|
-
|
|
32531
|
+
const retire = async () => {
|
|
32532
|
+
if (this.#threads.get(parentId) !== parent || this.#threads.get(child.id) !== child) return;
|
|
32533
|
+
if (bestEffort) {
|
|
32534
|
+
this.#threads.delete(child.id);
|
|
32535
|
+
await child.session.close();
|
|
32536
|
+
await child.outputTask;
|
|
32537
|
+
} else {
|
|
32538
|
+
child.sessionUnavailable = true;
|
|
32539
|
+
await this.#lifecycle.release(child.id, child.session, child.outputTask);
|
|
32540
|
+
if (this.#threads.get(child.id) === child) this.#threads.delete(child.id);
|
|
32541
|
+
}
|
|
32542
|
+
};
|
|
32543
|
+
if (bestEffort) await retire().catch(this.#diagnose);
|
|
32544
|
+
else await this.#withLifecycle(child.id, retire);
|
|
32323
32545
|
}
|
|
32324
32546
|
}
|
|
32325
32547
|
async locate(threadId2) {
|
|
32326
|
-
|
|
32548
|
+
try {
|
|
32549
|
+
return await this.#withLifecycle(threadId2, () => this.#locate(threadId2));
|
|
32550
|
+
} catch (error51) {
|
|
32551
|
+
return { kind: "error", error: recoveryError(error51) };
|
|
32552
|
+
}
|
|
32553
|
+
}
|
|
32554
|
+
async #locate(threadId2) {
|
|
32327
32555
|
const loaded = this.#threads.get(threadId2);
|
|
32328
32556
|
if (loaded) {
|
|
32329
32557
|
const failure = this.idleRelease.failure(loaded);
|
|
@@ -32349,37 +32577,61 @@ var ExternalThreadRuntime = class {
|
|
|
32349
32577
|
return { kind: "external", record: record4, thread: null };
|
|
32350
32578
|
}
|
|
32351
32579
|
async resolve(threadId2) {
|
|
32352
|
-
|
|
32353
|
-
|
|
32354
|
-
|
|
32355
|
-
|
|
32356
|
-
|
|
32357
|
-
|
|
32358
|
-
|
|
32359
|
-
|
|
32360
|
-
|
|
32361
|
-
|
|
32362
|
-
|
|
32363
|
-
|
|
32364
|
-
|
|
32365
|
-
|
|
32366
|
-
|
|
32367
|
-
|
|
32580
|
+
try {
|
|
32581
|
+
return await this.#withLifecycle(threadId2, async () => {
|
|
32582
|
+
const location = await this.#locate(threadId2);
|
|
32583
|
+
if (location.kind !== "external") return location;
|
|
32584
|
+
if (location.thread) {
|
|
32585
|
+
if (location.thread.sessionUnavailable && this.#idleForRestore(location.thread)) {
|
|
32586
|
+
await this.#dropIdleSession(location.thread);
|
|
32587
|
+
const current = this.#threads.get(threadId2);
|
|
32588
|
+
if (current) return { kind: "external", thread: current, historyFresh: false };
|
|
32589
|
+
} else {
|
|
32590
|
+
this.idleRelease.touch(location.thread);
|
|
32591
|
+
return { kind: "external", thread: location.thread, historyFresh: false };
|
|
32592
|
+
}
|
|
32593
|
+
}
|
|
32594
|
+
return {
|
|
32595
|
+
kind: "external",
|
|
32596
|
+
thread: await this.#restore(location.record),
|
|
32597
|
+
historyFresh: true
|
|
32598
|
+
};
|
|
32368
32599
|
});
|
|
32369
|
-
|
|
32600
|
+
} catch (error51) {
|
|
32601
|
+
return { kind: "error", error: recoveryError(error51) };
|
|
32370
32602
|
}
|
|
32603
|
+
}
|
|
32604
|
+
async refresh(thread) {
|
|
32371
32605
|
try {
|
|
32372
|
-
return
|
|
32606
|
+
return await this.#withLifecycle(thread.id, () => this.#refresh(thread));
|
|
32373
32607
|
} catch (error51) {
|
|
32608
|
+
return recoveryError(error51);
|
|
32609
|
+
}
|
|
32610
|
+
}
|
|
32611
|
+
async #refresh(thread) {
|
|
32612
|
+
if (this.#threads.get(thread.id) !== thread) {
|
|
32374
32613
|
return {
|
|
32375
|
-
|
|
32376
|
-
|
|
32614
|
+
code: -32076,
|
|
32615
|
+
message: "External Session changed during recovery; retry the request"
|
|
32377
32616
|
};
|
|
32378
32617
|
}
|
|
32379
|
-
|
|
32380
|
-
|
|
32381
|
-
|
|
32382
|
-
|
|
32618
|
+
const failure = this.idleRelease.failure(thread);
|
|
32619
|
+
if (failure) return { code: -32075, message: failure };
|
|
32620
|
+
if (thread.sessionUnavailable && this.#idleForRestore(thread)) {
|
|
32621
|
+
const revived = await this.#reviveIdleSession(thread);
|
|
32622
|
+
if (revived) return revived;
|
|
32623
|
+
}
|
|
32624
|
+
let snapshot2 = await thread.session.readSnapshot();
|
|
32625
|
+
if (!snapshot2.ok) {
|
|
32626
|
+
if (snapshot2.error.code === "invalidState" && this.#idleForRestore(thread) && this.#threads.get(thread.id) === thread) {
|
|
32627
|
+
const revived = await this.#reviveIdleSession(thread);
|
|
32628
|
+
if (revived) return revived;
|
|
32629
|
+
snapshot2 = await thread.session.readSnapshot();
|
|
32630
|
+
if (!snapshot2.ok) return mapExternalThreadHarnessError(snapshot2.error, "read");
|
|
32631
|
+
} else {
|
|
32632
|
+
return mapExternalThreadHarnessError(snapshot2.error, "read");
|
|
32633
|
+
}
|
|
32634
|
+
}
|
|
32383
32635
|
try {
|
|
32384
32636
|
const aligned = await this.#repository.alignSnapshot(thread.record, snapshot2.value);
|
|
32385
32637
|
thread.record = aligned.record;
|
|
@@ -32396,6 +32648,122 @@ var ExternalThreadRuntime = class {
|
|
|
32396
32648
|
return { code: -32081, message: "External Thread history could not be persisted" };
|
|
32397
32649
|
}
|
|
32398
32650
|
}
|
|
32651
|
+
async #reviveIdleSession(thread) {
|
|
32652
|
+
thread.sessionUnavailable = true;
|
|
32653
|
+
const harnessId = thread.record.harnessId;
|
|
32654
|
+
const adapter = this.#adapters.get(harnessId);
|
|
32655
|
+
if (!adapter || !thread.record.nativeSessionRef) {
|
|
32656
|
+
await this.#dropIdleSession(thread);
|
|
32657
|
+
return { code: -32077, message: "External Harness is unavailable" };
|
|
32658
|
+
}
|
|
32659
|
+
await this.#lifecycle.release(thread.id, thread.session, thread.outputTask);
|
|
32660
|
+
await this.#retireSubagents(thread);
|
|
32661
|
+
if (this.#threads.get(thread.id) !== thread) {
|
|
32662
|
+
return { code: -32076, message: "External Thread recovery failed" };
|
|
32663
|
+
}
|
|
32664
|
+
const restoredSelection = decodeExternalTransportSelection(
|
|
32665
|
+
harnessId,
|
|
32666
|
+
thread.record.transportModelId
|
|
32667
|
+
);
|
|
32668
|
+
const opened = await adapter.open({
|
|
32669
|
+
kind: "resume",
|
|
32670
|
+
cwd: thread.record.cwd,
|
|
32671
|
+
environment: { ...this.#environment, [DELEGATION_THREAD_ID_ENV]: thread.record.hostThreadId },
|
|
32672
|
+
nativeRef: thread.record.nativeSessionRef,
|
|
32673
|
+
knownTurnRefs: thread.record.turnMappings.map(({ nativeTurnRef }) => nativeTurnRef),
|
|
32674
|
+
...restoredSelection?.model ? { model: restoredSelection.model } : {},
|
|
32675
|
+
...restoredSelection?.thinkingOptionId ? { thinkingOptionId: restoredSelection.thinkingOptionId } : {},
|
|
32676
|
+
...restoredSelection?.permissionModeId ? { permissionModeId: restoredSelection.permissionModeId } : {}
|
|
32677
|
+
});
|
|
32678
|
+
if (!opened.ok) {
|
|
32679
|
+
await this.#dropIdleSession(thread);
|
|
32680
|
+
return mapExternalThreadHarnessError(opened.error, "resume");
|
|
32681
|
+
}
|
|
32682
|
+
const session = opened.value;
|
|
32683
|
+
if (this.#threads.get(thread.id) !== thread) {
|
|
32684
|
+
await this.#lifecycle.release(thread.id, session, Promise.resolve());
|
|
32685
|
+
return { code: -32076, message: "External Thread recovery failed" };
|
|
32686
|
+
}
|
|
32687
|
+
try {
|
|
32688
|
+
const snapshot2 = await session.readSnapshot();
|
|
32689
|
+
if (!snapshot2.ok) {
|
|
32690
|
+
await this.#lifecycle.release(thread.id, session, Promise.resolve());
|
|
32691
|
+
await this.#dropIdleSession(thread);
|
|
32692
|
+
return mapExternalThreadHarnessError(snapshot2.error, "read");
|
|
32693
|
+
}
|
|
32694
|
+
let aligned = await this.#repository.alignSnapshot(thread.record, snapshot2.value);
|
|
32695
|
+
if (this.#threads.get(thread.id) !== thread) {
|
|
32696
|
+
await this.#lifecycle.release(thread.id, session, Promise.resolve());
|
|
32697
|
+
return { code: -32076, message: "External Thread recovery failed" };
|
|
32698
|
+
}
|
|
32699
|
+
const restoredState = snapshot2.value.state;
|
|
32700
|
+
const effectiveModel = restoredState ? restoredState.effectiveModel : restoredSelection?.model;
|
|
32701
|
+
const effectiveThinkingOptionId = restoredState ? restoredState.effectiveThinkingOptionId : restoredSelection?.thinkingOptionId;
|
|
32702
|
+
const effectivePermissionModeId = restoredState ? restoredState.effectivePermissionModeId : restoredSelection?.permissionModeId;
|
|
32703
|
+
let transportModelId = aligned.record.transportModelId;
|
|
32704
|
+
if (restoredState && effectiveModel) {
|
|
32705
|
+
const liveSelection = {
|
|
32706
|
+
model: effectiveModel,
|
|
32707
|
+
...effectiveThinkingOptionId ? { thinkingOptionId: effectiveThinkingOptionId } : {},
|
|
32708
|
+
...effectivePermissionModeId ? { permissionModeId: effectivePermissionModeId } : {}
|
|
32709
|
+
};
|
|
32710
|
+
transportModelId = encodeExternalTransportSelection(harnessId, liveSelection);
|
|
32711
|
+
if (transportModelId !== aligned.record.transportModelId) {
|
|
32712
|
+
try {
|
|
32713
|
+
aligned = {
|
|
32714
|
+
...aligned,
|
|
32715
|
+
record: await this.#repository.setTransportModelId(
|
|
32716
|
+
aligned.record.hostThreadId,
|
|
32717
|
+
transportModelId
|
|
32718
|
+
)
|
|
32719
|
+
};
|
|
32720
|
+
} catch (error51) {
|
|
32721
|
+
this.#diagnose(error51);
|
|
32722
|
+
}
|
|
32723
|
+
}
|
|
32724
|
+
}
|
|
32725
|
+
if (this.#threads.get(thread.id) !== thread) {
|
|
32726
|
+
await this.#lifecycle.release(thread.id, session, Promise.resolve());
|
|
32727
|
+
return { code: -32076, message: "External Thread recovery failed" };
|
|
32728
|
+
}
|
|
32729
|
+
const initialState = restoredState ?? session.initialState;
|
|
32730
|
+
const observerState = {
|
|
32731
|
+
...initialState,
|
|
32732
|
+
...effectiveModel ? { effectiveModel } : {},
|
|
32733
|
+
...effectiveThinkingOptionId ? { effectiveThinkingOptionId } : {},
|
|
32734
|
+
...effectivePermissionModeId ? { effectivePermissionModeId } : {}
|
|
32735
|
+
};
|
|
32736
|
+
thread.session = session;
|
|
32737
|
+
thread.record = aligned.record;
|
|
32738
|
+
thread.turns = aligned.turns;
|
|
32739
|
+
thread.historyHydrated = true;
|
|
32740
|
+
thread.sessionUnavailable = false;
|
|
32741
|
+
thread.persistenceError = null;
|
|
32742
|
+
thread.transportModelId = transportModelId;
|
|
32743
|
+
if (effectiveModel) thread.requestedModel = effectiveModel;
|
|
32744
|
+
if (effectiveThinkingOptionId) thread.requestedThinkingOptionId = effectiveThinkingOptionId;
|
|
32745
|
+
if (effectivePermissionModeId) thread.requestedPermissionModeId = effectivePermissionModeId;
|
|
32746
|
+
thread.stateObserver = new SessionStateObserver(observerState);
|
|
32747
|
+
thread.latestUsage = session.initialUsage;
|
|
32748
|
+
thread.usageMeter = new UsageMeter();
|
|
32749
|
+
thread.usageTurnId = null;
|
|
32750
|
+
thread.thread = externalThreadValue({
|
|
32751
|
+
record: aligned.record,
|
|
32752
|
+
turns: aligned.turns,
|
|
32753
|
+
sessionId: thread.sessionId,
|
|
32754
|
+
running: thread.running
|
|
32755
|
+
});
|
|
32756
|
+
thread.outputTask = this.#consumeOutputs(thread);
|
|
32757
|
+
this.idleRelease.clearOutputFailed(thread);
|
|
32758
|
+
return null;
|
|
32759
|
+
} catch (error51) {
|
|
32760
|
+
if (error51 instanceof ExternalSessionReleaseError) throw error51;
|
|
32761
|
+
await this.#lifecycle.release(thread.id, session, Promise.resolve());
|
|
32762
|
+
this.#diagnose(error51);
|
|
32763
|
+
await this.#dropIdleSession(thread);
|
|
32764
|
+
return { code: -32081, message: "External Thread history could not be persisted" };
|
|
32765
|
+
}
|
|
32766
|
+
}
|
|
32399
32767
|
async persistTerminalIdentity(thread, event) {
|
|
32400
32768
|
if (thread.persistenceError) return thread.persistenceError;
|
|
32401
32769
|
if (!event.nativeTurnRef) {
|
|
@@ -32534,7 +32902,8 @@ var ExternalThreadRuntime = class {
|
|
|
32534
32902
|
transportModelId
|
|
32535
32903
|
});
|
|
32536
32904
|
} catch (error51) {
|
|
32537
|
-
|
|
32905
|
+
if (error51 instanceof ExternalSessionReleaseError) throw error51;
|
|
32906
|
+
await this.#lifecycle.release(record4.hostThreadId, session, Promise.resolve());
|
|
32538
32907
|
throw error51;
|
|
32539
32908
|
}
|
|
32540
32909
|
}
|
|
@@ -35467,7 +35836,9 @@ function hasValidSessionUsage(value2) {
|
|
|
35467
35836
|
}
|
|
35468
35837
|
function isAdapter(value2) {
|
|
35469
35838
|
if (!value2 || typeof value2 !== "object") return false;
|
|
35470
|
-
return hasValidSessionUsage(value2) && ["inspect", "open", "close"].every((key) => typeof Reflect.get(value2, key) === "function")
|
|
35839
|
+
return hasValidSessionUsage(value2) && ["inspect", "open", "close"].every((key) => typeof Reflect.get(value2, key) === "function") && ["credits", "refreshCredits"].every(
|
|
35840
|
+
(key) => Reflect.get(value2, key) === void 0 || typeof Reflect.get(value2, key) === "function"
|
|
35841
|
+
);
|
|
35471
35842
|
}
|
|
35472
35843
|
function isUsageAdapter(value2) {
|
|
35473
35844
|
if (!value2 || typeof value2 !== "object" || typeof Reflect.get(value2, "close") !== "function")
|
|
@@ -37335,6 +37706,16 @@ async function moveThreadSection(input) {
|
|
|
37335
37706
|
}
|
|
37336
37707
|
}
|
|
37337
37708
|
|
|
37709
|
+
// packages/host-runtime/src/external-thread-official-defaults.ts
|
|
37710
|
+
var EMPTY_RESULTS = /* @__PURE__ */ new Map([
|
|
37711
|
+
["thread/attachment/list", () => ({ data: [], nextCursor: null })],
|
|
37712
|
+
["thread/queue/list", () => ({ data: [], nextCursor: null })],
|
|
37713
|
+
["thread/settings/update", () => ({})]
|
|
37714
|
+
]);
|
|
37715
|
+
function externalThreadEmptyOfficialResult(method) {
|
|
37716
|
+
return EMPTY_RESULTS.get(method)?.();
|
|
37717
|
+
}
|
|
37718
|
+
|
|
37338
37719
|
// packages/host-runtime/src/observed-session-usage.ts
|
|
37339
37720
|
var ObservedSessionUsage = class {
|
|
37340
37721
|
constructor(providers, prices, diagnose) {
|
|
@@ -37503,16 +37884,6 @@ function officialThreadBusy(thread) {
|
|
|
37503
37884
|
const latestTurn = turns.at(-1);
|
|
37504
37885
|
return isRecord18(latestTurn) && (latestTurn.status === "inProgress" || latestTurn.status === "running");
|
|
37505
37886
|
}
|
|
37506
|
-
function isCreditsAdapter(adapter) {
|
|
37507
|
-
return typeof adapter.credits === "function";
|
|
37508
|
-
}
|
|
37509
|
-
function projectAccountCredits(value2) {
|
|
37510
|
-
if (!isRecord18(value2)) return null;
|
|
37511
|
-
const rest = { ...value2 };
|
|
37512
|
-
delete rest.fetchedAt;
|
|
37513
|
-
const parsed2 = accountCreditsSnapshotSchema.safeParse(rest);
|
|
37514
|
-
return parsed2.success ? parsed2.data : null;
|
|
37515
|
-
}
|
|
37516
37887
|
function errorMessage4(error51) {
|
|
37517
37888
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
37518
37889
|
}
|
|
@@ -37684,6 +38055,7 @@ var AppServerHost = class {
|
|
|
37684
38055
|
#launchSettings;
|
|
37685
38056
|
#accountInspections = new HarnessAccountInspectionCache();
|
|
37686
38057
|
#externalRuntime;
|
|
38058
|
+
#executionHosts = /* @__PURE__ */ new WeakMap();
|
|
37687
38059
|
#externalPrewarms = new ExternalThreadPrewarms();
|
|
37688
38060
|
#externalSteering = new ExternalTurnSteering();
|
|
37689
38061
|
#liveCommandCache = new LiveCommandCatalogCache();
|
|
@@ -37818,6 +38190,7 @@ var AppServerHost = class {
|
|
|
37818
38190
|
consumeOutputs: (thread) => this.#consumeHarnessOutputs(thread),
|
|
37819
38191
|
diagnose: (error51) => this.#diagnose(error51),
|
|
37820
38192
|
subagentRunning: (threadId2) => this.#subagentThreadStatuses.get(threadId2) === "active",
|
|
38193
|
+
hasRunningDescendants: (threadId2) => this.#hasRunningSubagents(threadId2),
|
|
37821
38194
|
idleRelease: {
|
|
37822
38195
|
queue: this.#desktopRequests,
|
|
37823
38196
|
onClosed: async (thread) => {
|
|
@@ -37876,7 +38249,11 @@ var AppServerHost = class {
|
|
|
37876
38249
|
wait: (input) => this.#waitForPlugins().then(() => this.#delegationCoordinator.wait(input)),
|
|
37877
38250
|
list: (input) => this.#waitForPlugins().then(() => this.#delegationCoordinator.list(input)),
|
|
37878
38251
|
canHandleStart: (input) => this.#canHandleDelegationStart(input),
|
|
37879
|
-
ownsThread: (threadId2) => this.#ownsDelegationThread(threadId2)
|
|
38252
|
+
ownsThread: (threadId2) => this.#ownsDelegationThread(threadId2),
|
|
38253
|
+
executionHostId: (threadId2) => {
|
|
38254
|
+
const thread = this.#externalRuntime.get(threadId2);
|
|
38255
|
+
return thread ? this.#executionHosts.get(thread) : void 0;
|
|
38256
|
+
}
|
|
37880
38257
|
});
|
|
37881
38258
|
this.#unregisterDelegationApi = typeof unregisterDelegationApi === "function" ? unregisterDelegationApi : void 0;
|
|
37882
38259
|
}
|
|
@@ -38013,6 +38390,7 @@ var AppServerHost = class {
|
|
|
38013
38390
|
await Promise.allSettled(threads.map(({ session }) => session.close()));
|
|
38014
38391
|
await Promise.allSettled(threads.map(({ outputTask }) => outputTask));
|
|
38015
38392
|
await this.#closeAdapters();
|
|
38393
|
+
await this.#externalRuntime.drain();
|
|
38016
38394
|
for (const pending of [...this.#pendingDesktopApprovals.values()]) {
|
|
38017
38395
|
await this.#resolveDesktopApproval(pending.interaction.interactionId).catch(
|
|
38018
38396
|
() => void 0
|
|
@@ -38942,8 +39320,9 @@ var AppServerHost = class {
|
|
|
38942
39320
|
const location = await this.#locateExternalThread(request.params.threadId);
|
|
38943
39321
|
if (await this.#writeResolutionError(request, location)) return;
|
|
38944
39322
|
if (location.kind === "external") {
|
|
39323
|
+
const emptyResult = externalThreadEmptyOfficialResult(request.method);
|
|
38945
39324
|
await this.#writer.json(
|
|
38946
|
-
rpcError(request, -32076, `External Thread does not support ${request.method}`)
|
|
39325
|
+
emptyResult ? rpcEnvelope(request, { result: emptyResult }) : rpcError(request, -32076, `External Thread does not support ${request.method}`)
|
|
38947
39326
|
);
|
|
38948
39327
|
return;
|
|
38949
39328
|
}
|
|
@@ -39999,6 +40378,7 @@ var AppServerHost = class {
|
|
|
39999
40378
|
const result2 = threadUsageInspectionSchema.parse({
|
|
40000
40379
|
threadId: params.data.threadId,
|
|
40001
40380
|
usage: await this.#observedSessionUsage.read(params.data.threadId),
|
|
40381
|
+
accountCreditsSupported: true,
|
|
40002
40382
|
...accountCredits ? { accountCredits } : {}
|
|
40003
40383
|
});
|
|
40004
40384
|
await this.#writer.json(rpcEnvelope(request, { result: jsonValueSchema.parse(result2) }));
|
|
@@ -40006,11 +40386,17 @@ var AppServerHost = class {
|
|
|
40006
40386
|
}
|
|
40007
40387
|
if (params.data.refresh === "exact") void resolution.thread.session.refreshUsage?.();
|
|
40008
40388
|
const adapter = this.#externalAdapters.get(resolution.thread.harnessId);
|
|
40009
|
-
if (adapter &&
|
|
40010
|
-
|
|
40389
|
+
if (adapter?.credits && adapter.refreshCredits)
|
|
40390
|
+
void Promise.resolve().then(() => adapter.refreshCredits?.()).catch(() => void 0);
|
|
40391
|
+
let credits = null;
|
|
40392
|
+
try {
|
|
40393
|
+
credits = parseHarnessAccountCredits(adapter?.credits?.());
|
|
40394
|
+
} catch {
|
|
40395
|
+
}
|
|
40011
40396
|
const result = threadUsageInspectionSchema.parse({
|
|
40012
40397
|
threadId: params.data.threadId,
|
|
40013
40398
|
usage: await this.#threadUsage(resolution.thread),
|
|
40399
|
+
accountCreditsSupported: typeof adapter?.credits === "function",
|
|
40014
40400
|
...credits ? { accountCredits: credits } : {}
|
|
40015
40401
|
});
|
|
40016
40402
|
await this.#writer.json(rpcEnvelope(request, { result: jsonValueSchema.parse(result) }));
|
|
@@ -40206,7 +40592,7 @@ var AppServerHost = class {
|
|
|
40206
40592
|
this.#pendingExternalCommandRequests.delete(thread.id);
|
|
40207
40593
|
}
|
|
40208
40594
|
}
|
|
40209
|
-
async #beginExternalCommand(thread, descriptor, arguments_2, requestedTurnId) {
|
|
40595
|
+
async #beginExternalCommand(thread, descriptor, arguments_2, requestedTurnId, sourceHostId) {
|
|
40210
40596
|
const commands = thread.session.commands;
|
|
40211
40597
|
if (!commands) {
|
|
40212
40598
|
throw new ExternalCommandError(-32078, "External Harness does not expose commands");
|
|
@@ -40235,6 +40621,7 @@ var AppServerHost = class {
|
|
|
40235
40621
|
thread.ephemeralTurnIds.add(turnId);
|
|
40236
40622
|
if (descriptor.invocation === "/compact") this.#manualCompactionTurns.set(thread, turnId);
|
|
40237
40623
|
else this.#manualCompactionTurns.delete(thread);
|
|
40624
|
+
const restoreExecutionHost = this.#setExecutionHost(thread, sourceHostId);
|
|
40238
40625
|
try {
|
|
40239
40626
|
if (thread.unsubmittedPrewarm && await this.#externalRuntime.submitPrewarm(thread)) {
|
|
40240
40627
|
await this.#notifyExternalThreadStarted(thread.thread);
|
|
@@ -40247,6 +40634,7 @@ var AppServerHost = class {
|
|
|
40247
40634
|
if (!result.ok) throw new ExternalCommandError(-32073, result.error.message);
|
|
40248
40635
|
return { turnId: result.value.turnId, turn: projection.projector.pendingTurn(), gate };
|
|
40249
40636
|
} catch (error51) {
|
|
40637
|
+
restoreExecutionHost();
|
|
40250
40638
|
thread.running = false;
|
|
40251
40639
|
thread.activeTurnId = null;
|
|
40252
40640
|
thread.projectedTurns.delete(turnId);
|
|
@@ -41026,7 +41414,8 @@ var AppServerHost = class {
|
|
|
41026
41414
|
thread,
|
|
41027
41415
|
text,
|
|
41028
41416
|
void 0,
|
|
41029
|
-
typeof params.clientUserMessageId === "string" ? params.clientUserMessageId : void 0
|
|
41417
|
+
typeof params.clientUserMessageId === "string" ? params.clientUserMessageId : void 0,
|
|
41418
|
+
params[THREAD_REFERENCE_SOURCE_HOST_PARAM]
|
|
41030
41419
|
);
|
|
41031
41420
|
try {
|
|
41032
41421
|
await this.#writer.json(rpcEnvelope(request, { result: { turn: started.turn } }));
|
|
@@ -41052,7 +41441,8 @@ var AppServerHost = class {
|
|
|
41052
41441
|
thread,
|
|
41053
41442
|
text,
|
|
41054
41443
|
assertActive,
|
|
41055
|
-
typeof requestObject(request).clientUserMessageId === "string" ? requestObject(request).clientUserMessageId : void 0
|
|
41444
|
+
typeof requestObject(request).clientUserMessageId === "string" ? requestObject(request).clientUserMessageId : void 0,
|
|
41445
|
+
requestObject(request)[THREAD_REFERENCE_SOURCE_HOST_PARAM]
|
|
41056
41446
|
)
|
|
41057
41447
|
);
|
|
41058
41448
|
try {
|
|
@@ -41073,12 +41463,12 @@ var AppServerHost = class {
|
|
|
41073
41463
|
}
|
|
41074
41464
|
}
|
|
41075
41465
|
/** Keep command restoration and dispatch identical for start and steer submissions. */
|
|
41076
|
-
async #beginExternalInputTurn(thread, inputText, assertActive, clientUserMessageId) {
|
|
41466
|
+
async #beginExternalInputTurn(thread, inputText, assertActive, clientUserMessageId, sourceHostId) {
|
|
41077
41467
|
const text = restoreHarnessCommandMentions(inputText);
|
|
41078
41468
|
const commands = thread.session.commands;
|
|
41079
41469
|
if (!commands || !isExternalCommandCandidate(text)) {
|
|
41080
41470
|
assertActive?.();
|
|
41081
|
-
return this.#beginExternalTurn(thread, text, clientUserMessageId);
|
|
41471
|
+
return this.#beginExternalTurn(thread, text, clientUserMessageId, sourceHostId);
|
|
41082
41472
|
}
|
|
41083
41473
|
this.#pendingExternalCommandRequests.add(thread.id);
|
|
41084
41474
|
try {
|
|
@@ -41089,9 +41479,15 @@ var AppServerHost = class {
|
|
|
41089
41479
|
assertActive?.();
|
|
41090
41480
|
if (!command) {
|
|
41091
41481
|
this.#pendingExternalCommandRequests.delete(thread.id);
|
|
41092
|
-
return await this.#beginExternalTurn(thread, text, clientUserMessageId);
|
|
41482
|
+
return await this.#beginExternalTurn(thread, text, clientUserMessageId, sourceHostId);
|
|
41093
41483
|
}
|
|
41094
|
-
return await this.#beginExternalCommand(
|
|
41484
|
+
return await this.#beginExternalCommand(
|
|
41485
|
+
thread,
|
|
41486
|
+
command.descriptor,
|
|
41487
|
+
command.arguments,
|
|
41488
|
+
void 0,
|
|
41489
|
+
sourceHostId
|
|
41490
|
+
);
|
|
41095
41491
|
} catch (error51) {
|
|
41096
41492
|
if (error51 instanceof ExternalCommandError || error51 instanceof ExternalSteerError) throw error51;
|
|
41097
41493
|
this.#diagnose(error51);
|
|
@@ -41103,7 +41499,20 @@ var AppServerHost = class {
|
|
|
41103
41499
|
this.#pendingExternalCommandRequests.delete(thread.id);
|
|
41104
41500
|
}
|
|
41105
41501
|
}
|
|
41106
|
-
|
|
41502
|
+
/** Apply context before native execution; a rejected start restores the prior identity. */
|
|
41503
|
+
#setExecutionHost(thread, sourceHostId) {
|
|
41504
|
+
const previousHostId = this.#executionHosts.get(thread);
|
|
41505
|
+
if (typeof sourceHostId === "string" && sourceHostId.length > 0 && sourceHostId.length <= 1024 && !/[\u0000-\u0020\u007f]/u.test(sourceHostId)) {
|
|
41506
|
+
this.#executionHosts.set(thread, sourceHostId);
|
|
41507
|
+
} else {
|
|
41508
|
+
this.#executionHosts.delete(thread);
|
|
41509
|
+
}
|
|
41510
|
+
return () => {
|
|
41511
|
+
if (previousHostId === void 0) this.#executionHosts.delete(thread);
|
|
41512
|
+
else this.#executionHosts.set(thread, previousHostId);
|
|
41513
|
+
};
|
|
41514
|
+
}
|
|
41515
|
+
async #beginExternalTurn(thread, text, clientUserMessageId, sourceHostId) {
|
|
41107
41516
|
if (this.#closeRequested || this.#externalRuntime.get(thread.id) !== thread) {
|
|
41108
41517
|
throw new ExternalSteerError(-32073, "External Thread is no longer available");
|
|
41109
41518
|
}
|
|
@@ -41130,6 +41539,7 @@ var AppServerHost = class {
|
|
|
41130
41539
|
thread.projectedTerminalTurnId = null;
|
|
41131
41540
|
thread.projectedTurns.set(turnId, projection);
|
|
41132
41541
|
thread.responseGates.set(turnId, gate);
|
|
41542
|
+
const restoreExecutionHost = this.#setExecutionHost(thread, sourceHostId);
|
|
41133
41543
|
try {
|
|
41134
41544
|
if (thread.unsubmittedPrewarm && await this.#externalRuntime.submitPrewarm(thread)) {
|
|
41135
41545
|
await this.#notifyExternalThreadStarted(thread.thread);
|
|
@@ -41142,6 +41552,7 @@ var AppServerHost = class {
|
|
|
41142
41552
|
if (!result.ok) throw new ExternalSteerError(-32073, result.error.message);
|
|
41143
41553
|
return { turnId, turn: projection.projector.pendingTurn(), gate };
|
|
41144
41554
|
} catch (error51) {
|
|
41555
|
+
restoreExecutionHost();
|
|
41145
41556
|
thread.running = false;
|
|
41146
41557
|
thread.activeTurnId = null;
|
|
41147
41558
|
thread.projectedTurns.delete(turnId);
|
|
@@ -41370,7 +41781,11 @@ var AppServerHost = class {
|
|
|
41370
41781
|
if (event.type === "session.faulted") {
|
|
41371
41782
|
this.#externalSteering.fault(thread.id, new Error(event.error.message));
|
|
41372
41783
|
thread.stateObserver.fault(new Error(event.error.message));
|
|
41784
|
+
this.#externalRuntime.markSessionUnavailable(thread);
|
|
41373
41785
|
this.#diagnose(`${thread.harnessId} Harness Session faulted: ${event.error.message}`);
|
|
41786
|
+
if (!thread.running && !thread.activeTurnId && !this.#hasRunningSubagents(thread.id) && !thread.session.hasBackgroundWork?.()) {
|
|
41787
|
+
void this.#externalRuntime.discardUnavailableIdle(thread);
|
|
41788
|
+
}
|
|
41374
41789
|
return;
|
|
41375
41790
|
}
|
|
41376
41791
|
if (event.type === "turn.autonomous.started") {
|
|
@@ -41499,6 +41914,11 @@ var AppServerHost = class {
|
|
|
41499
41914
|
return { ...subagent, subagentId: record4.hostThreadId };
|
|
41500
41915
|
}
|
|
41501
41916
|
async #refreshOpenSubagentThread(threadId2, terminal3 = true) {
|
|
41917
|
+
await this.#desktopRequests.run(threadId2, async () => {
|
|
41918
|
+
await this.#refreshOpenSubagentThreadBody(threadId2, terminal3);
|
|
41919
|
+
});
|
|
41920
|
+
}
|
|
41921
|
+
async #refreshOpenSubagentThreadBody(threadId2, terminal3) {
|
|
41502
41922
|
const child = this.#externalRuntime.get(threadId2);
|
|
41503
41923
|
if (!child) return;
|
|
41504
41924
|
const previousItems = new Map(
|
|
@@ -43523,15 +43943,28 @@ var DelegationControlRegistry = class {
|
|
|
43523
43943
|
return (await this.#registrationForThread(input.threadId)).cancel(input);
|
|
43524
43944
|
}
|
|
43525
43945
|
async read(input) {
|
|
43526
|
-
|
|
43527
|
-
|
|
43946
|
+
const { callerThreadId: callerThreadId2, ...read } = input;
|
|
43947
|
+
if (read.hostId !== void 0 && read.hostId !== "local") {
|
|
43948
|
+
if (typeof callerThreadId2 === "string" && callerThreadId2) {
|
|
43949
|
+
const callers = await this.#matching(
|
|
43950
|
+
(registration) => registration.executionHostId?.(callerThreadId2) === read.hostId && registration.ownsThread(callerThreadId2)
|
|
43951
|
+
);
|
|
43952
|
+
if (callers.length > 1)
|
|
43953
|
+
only(callers, "Calling Thread has ambiguous execution Host context");
|
|
43954
|
+
if (callers.length === 1) {
|
|
43955
|
+
const { hostId: hostId2, ...local } = read;
|
|
43956
|
+
const snapshot2 = await (await this.#registrationForThread(local.threadId)).read(local);
|
|
43957
|
+
return { ...snapshot2, hostId: hostId2 };
|
|
43958
|
+
}
|
|
43959
|
+
}
|
|
43960
|
+
if (!read.hostId || !this.#remoteRead)
|
|
43528
43961
|
throw new DelegationControlError(
|
|
43529
43962
|
"RUNTIME_UNREACHABLE",
|
|
43530
43963
|
"Remote Thread reading is unavailable"
|
|
43531
43964
|
);
|
|
43532
|
-
return this.#remoteRead(
|
|
43965
|
+
return this.#remoteRead(read);
|
|
43533
43966
|
}
|
|
43534
|
-
return (await this.#registrationForThread(
|
|
43967
|
+
return (await this.#registrationForThread(read.threadId)).read(read);
|
|
43535
43968
|
}
|
|
43536
43969
|
async wait(input) {
|
|
43537
43970
|
if (input.hostId !== void 0 && input.hostId !== "local")
|
|
@@ -45555,9 +45988,21 @@ function requiredRuntimeConfiguration(environment) {
|
|
|
45555
45988
|
if (!stockCodexPath) throw new Error(`${STOCK_CODEX_PATH_ENV} is required`);
|
|
45556
45989
|
return { stockCodexPath };
|
|
45557
45990
|
}
|
|
45558
|
-
function delegationCliEnvironment(environment) {
|
|
45559
|
-
|
|
45560
|
-
|
|
45991
|
+
function delegationCliEnvironment(environment, hostRuntimePath) {
|
|
45992
|
+
let packagedCli;
|
|
45993
|
+
if (hostRuntimePath && path37.isAbsolute(hostRuntimePath)) {
|
|
45994
|
+
const candidate = path37.resolve(
|
|
45995
|
+
path37.dirname(hostRuntimePath),
|
|
45996
|
+
"../bin",
|
|
45997
|
+
process.platform === "win32" ? "codexhost.exe" : "codexhost"
|
|
45998
|
+
);
|
|
45999
|
+
try {
|
|
46000
|
+
if (statSync(candidate).isFile()) packagedCli = candidate;
|
|
46001
|
+
} catch {
|
|
46002
|
+
}
|
|
46003
|
+
}
|
|
46004
|
+
const cliPath = environment[DELEGATION_CLI_PATH_ENV] ?? environment[UPDATE_RUNTIME_ENV.launcherExecutable] ?? packagedCli;
|
|
46005
|
+
const nodePath2 = environment[DELEGATION_CLI_NODE_PATH_ENV] ?? environment[UPDATE_RUNTIME_ENV.npmNodePath] ?? (packagedCli && cliPath === packagedCli ? process.execPath : void 0);
|
|
45561
46006
|
return {
|
|
45562
46007
|
...cliPath ? { [DELEGATION_CLI_PATH_ENV]: cliPath } : {},
|
|
45563
46008
|
...nodePath2 && path37.isAbsolute(nodePath2) ? { [DELEGATION_CLI_NODE_PATH_ENV]: nodePath2 } : {}
|
|
@@ -45575,7 +46020,7 @@ async function prepareDelegationRuntime(input) {
|
|
|
45575
46020
|
const server = await startDelegationControlServer({ token, api: registry2, watchApi: registry2 });
|
|
45576
46021
|
const environment = {
|
|
45577
46022
|
...input.environment,
|
|
45578
|
-
...delegationCliEnvironment(input.environment),
|
|
46023
|
+
...delegationCliEnvironment(input.environment, input.hostRuntimePath),
|
|
45579
46024
|
[DELEGATION_RUNTIME_ENDPOINT_ENV]: server.endpoint,
|
|
45580
46025
|
[DELEGATION_RUNTIME_TOKEN_ENV]: token
|
|
45581
46026
|
};
|
|
@@ -45650,6 +46095,7 @@ async function runHostRuntime(input) {
|
|
|
45650
46095
|
const environment = remoteControlPlan?.environment ?? input.environment;
|
|
45651
46096
|
return prepareDelegationRuntime({
|
|
45652
46097
|
environment,
|
|
46098
|
+
...hostRuntimePath ? { hostRuntimePath } : {},
|
|
45653
46099
|
createHost: async (delegationEnvironment, onDelegationApi, registry2) => {
|
|
45654
46100
|
const official = await prepareLocalCodex({
|
|
45655
46101
|
stockCodexPath,
|
|
@@ -45758,6 +46204,7 @@ async function runHostRuntime(input) {
|
|
|
45758
46204
|
if (!listenUrl) throw new Error("Remote app-server listener URL is unavailable");
|
|
45759
46205
|
return prepareDelegationRuntime({
|
|
45760
46206
|
environment: input.environment,
|
|
46207
|
+
...hostRuntimePath ? { hostRuntimePath } : {},
|
|
45761
46208
|
createHost: async (delegationEnvironment, _onDelegationApi, registry2) => {
|
|
45762
46209
|
const socketPath = remoteAppServerSocketPath(delegationEnvironment, listenUrl);
|
|
45763
46210
|
const officialPlan = createRemoteOfficialAppServerPlan(input.arguments, socketPath);
|
|
@@ -47463,8 +47910,11 @@ async function startHarnessBrokerServer(input) {
|
|
|
47463
47910
|
retireWhenIdle = false;
|
|
47464
47911
|
if (request.method === "adapter.credits") {
|
|
47465
47912
|
harnessAccountListParamsSchema.parse(request.params);
|
|
47466
|
-
const
|
|
47467
|
-
|
|
47913
|
+
const value2 = input.adapter.credits?.();
|
|
47914
|
+
const credits = parseHarnessAccountCredits(value2);
|
|
47915
|
+
if (value2 != null && !credits)
|
|
47916
|
+
throw new Error("Invalid account credits snapshot");
|
|
47917
|
+
return credits;
|
|
47468
47918
|
}
|
|
47469
47919
|
if (request.method === "adapter.inspectAccount") {
|
|
47470
47920
|
harnessAccountListParamsSchema.parse(request.params);
|
|
@@ -47991,7 +48441,7 @@ import {
|
|
|
47991
48441
|
readdirSync,
|
|
47992
48442
|
renameSync,
|
|
47993
48443
|
rmSync,
|
|
47994
|
-
statSync,
|
|
48444
|
+
statSync as statSync2,
|
|
47995
48445
|
writeFileSync
|
|
47996
48446
|
} from "node:fs";
|
|
47997
48447
|
import os12 from "node:os";
|
|
@@ -48021,7 +48471,7 @@ function pruneRuntimeLogs(input) {
|
|
|
48021
48471
|
if (!Number.isSafeInteger(pid)) continue;
|
|
48022
48472
|
try {
|
|
48023
48473
|
const filePath = path42.join(input.directory, entry.name);
|
|
48024
|
-
const stats =
|
|
48474
|
+
const stats = statSync2(filePath);
|
|
48025
48475
|
files.push({
|
|
48026
48476
|
filePath,
|
|
48027
48477
|
pid,
|