@codexhost/cli-darwin-x64 0.6.0 → 0.6.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 +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/desktop-controller.mjs +2 -1
- package/app/host-runtime.mjs +628 -260
- package/app/plugins/antigravity/plugin.mjs +15 -8
- package/app/plugins/claude-code/plugin.mjs +661 -219
- package/app/plugins/deepseek-harness/plugin.mjs +7277 -10029
- package/app/plugins/enabled.json +2 -1
- package/app/plugins/grok/plugin.mjs +932 -75
- package/app/plugins/kiro-cli/assets/icon.svg +5 -0
- package/app/plugins/kiro-cli/manifest.json +12 -0
- package/app/plugins/kiro-cli/plugin.mjs +23339 -0
- package/app/plugins/omp/plugin.mjs +11 -1
- package/app/plugins/opencode/plugin.mjs +297 -143
- package/app/plugins/pi/plugin.mjs +1489 -1300
- package/app/renderer-extension.js +715 -377
- package/bin/codexhost +0 -0
- package/libexec/codexhost-shim +0 -0
- package/libexec/codexhost-updater +0 -0
- package/package.json +1 -1
package/app/host-runtime.mjs
CHANGED
|
@@ -3709,6 +3709,92 @@ var require_websocket_server = __commonJS({
|
|
|
3709
3709
|
}
|
|
3710
3710
|
});
|
|
3711
3711
|
|
|
3712
|
+
// packages/host-runtime/src/delegation-cli-help.ts
|
|
3713
|
+
var COMMAND_HELP = {
|
|
3714
|
+
"harness list": `codexhost harness list [--format json|compact]
|
|
3715
|
+
List Harnesses available in the active Runtime.`,
|
|
3716
|
+
"harness inspect": `codexhost harness inspect <harness> [--cwd <path>] [--refresh true|false] [--format json|compact]
|
|
3717
|
+
Read available Models, native defaults, Thinking options, and configuration capabilities.
|
|
3718
|
+
Use the returned Model and Thinking IDs for explicit selections.`,
|
|
3719
|
+
"delegate start": `codexhost delegate start --harness <id> --task <text> [--cwd <path>] [--model <opaque-ref>] [--thinking <option-id>] [--parent-thread <thread>] [--request-id <id>] [--format json|compact]
|
|
3720
|
+
Create an independent child Thread, submit the task, and return immediately.
|
|
3721
|
+
Omit --model and --thinking to use the Harness native defaults.
|
|
3722
|
+
--cwd overrides the child workspace. Otherwise use the resolved parent Thread workspace, then the Host Runtime process cwd.
|
|
3723
|
+
--parent-thread overrides caller inference. PARENT_THREAD_AMBIGUOUS requires an explicit parent.
|
|
3724
|
+
Reuse --request-id for an idempotent retry. Identical recent parent/target/task/configuration requests are also deduplicated briefly.
|
|
3725
|
+
The response confirms cwd and parent. Use its Thread reference with thread read, wait, send, or cancel.`,
|
|
3726
|
+
"thread send": `codexhost thread send <thread> --message <text> [--format json|compact]
|
|
3727
|
+
Start a new Turn in an idle writable Thread and return immediately.
|
|
3728
|
+
THREAD_BUSY means the current Turn is still active: wait or cancel before sending. Messages are not queued.`,
|
|
3729
|
+
"thread cancel": `codexhost thread cancel <thread> [--format json|compact]
|
|
3730
|
+
Request cancellation of the active Turn while preserving the Thread and history.
|
|
3731
|
+
cancelled=true (compact: cancelRequested=true) means the cancellation request was accepted. Read or wait to confirm the terminal state. An idle Thread returns false.`,
|
|
3732
|
+
"thread read": `codexhost thread read <thread> [--view result|messages] [--cursor <cursor>] [--limit <n>] [--format json|compact]
|
|
3733
|
+
Read immediately without starting a Turn. The default result view reports the latest Turn's status and result.
|
|
3734
|
+
The messages view pages visible user/Agent messages, oldest first. Default limit 25, maximum 100; --cursor and --limit require --view messages.
|
|
3735
|
+
hasMore describes remaining messages now. Save nextCursor for later incremental reads even when hasMore=false.
|
|
3736
|
+
Compact messages output contains only the message page and status; compact result output includes the latest nonempty progress while running.
|
|
3737
|
+
Full JSON retains the complete snapshot. Tool calls/output, file activity, and reasoning are not included in either format.`,
|
|
3738
|
+
"thread wait": `codexhost thread wait <thread> [--timeout-ms <n>] [--view result|messages] [--cursor <cursor>] [--limit <n>] [--format json|compact]
|
|
3739
|
+
Wait until the Thread is terminal or the timeout expires (default 30000 ms), then return the same snapshot as thread read plus timedOut.
|
|
3740
|
+
timedOut=true is a running checkpoint: the child keeps running. The response already includes the result when available; another read is unnecessary unless more information is needed.
|
|
3741
|
+
Message pagination uses --view messages, default limit 25, maximum 100. hasMore is for current pages; nextCursor also supports future incremental reads.`,
|
|
3742
|
+
"thread list": `codexhost thread list [--cwd <path>] [--parent <thread>] [--limit <n>] [--cursor <cursor>] [--sort created-asc|created-desc|updated-asc|updated-desc|recency-asc|recency-desc] [--format json|compact]
|
|
3743
|
+
Find existing Threads by workspace, or use --parent to list a Thread's delegated children.
|
|
3744
|
+
Workspace listing defaults to the caller process cwd. Default limit 25 (maximum 100), sorted created-desc.
|
|
3745
|
+
--parent uses Delegation relationships. A null nextCursor ends the list.
|
|
3746
|
+
Compact output keeps task links, Harness, status, title, and workspace.`
|
|
3747
|
+
};
|
|
3748
|
+
var COMMON_HELP = `Thread references accept a bare ID or codex://threads/<id>.
|
|
3749
|
+
--format json is the compatible full JSON output (default); --format compact returns concise JSON using task links instead of internal IDs.
|
|
3750
|
+
Success is written to stdout; errors {"error":{"code":"...","message":"...","details":{...}}} go to stderr with exit code 1. Exit code 0 means the command succeeded, not that the delegated task succeeded.
|
|
3751
|
+
read/wait are non-consuming. Native Codex callers need local Runtime access; RUNTIME_UNREACHABLE requires the Host-provided environment and a sandbox that permits that connection.`;
|
|
3752
|
+
var DELEGATION_HELP = `usage:
|
|
3753
|
+
codexhost harness list
|
|
3754
|
+
codexhost harness inspect <harness>
|
|
3755
|
+
codexhost delegate start --harness <id> --task <text>
|
|
3756
|
+
codexhost thread send <thread> --message <text>
|
|
3757
|
+
codexhost thread cancel <thread>
|
|
3758
|
+
codexhost thread read <thread>
|
|
3759
|
+
codexhost thread wait <thread>
|
|
3760
|
+
codexhost thread list
|
|
3761
|
+
|
|
3762
|
+
Use <command> --help for its options. Use harness list to discover targets.
|
|
3763
|
+
${COMMON_HELP}
|
|
3764
|
+
`;
|
|
3765
|
+
function hasHelpOption(arguments_2) {
|
|
3766
|
+
for (let index = 0; index < arguments_2.length; index += 1) {
|
|
3767
|
+
const argument = arguments_2[index];
|
|
3768
|
+
if (argument === "--help" || argument === "-h") return true;
|
|
3769
|
+
if (argument?.startsWith("--")) index += 1;
|
|
3770
|
+
}
|
|
3771
|
+
return false;
|
|
3772
|
+
}
|
|
3773
|
+
function delegationCliHelp(arguments_2) {
|
|
3774
|
+
const [group, command, ...rest] = arguments_2;
|
|
3775
|
+
if (!group || group === "--help" || group === "-h") return DELEGATION_HELP;
|
|
3776
|
+
if (!command || command === "--help" || command === "-h" || command === "help") {
|
|
3777
|
+
if (group === "delegate") return DELEGATION_HELP;
|
|
3778
|
+
if (group === "harness" || group === "thread") {
|
|
3779
|
+
const usages = Object.entries(COMMAND_HELP).filter(([name]) => name.startsWith(`${group} `)).map(([, help]) => help.split("\n")[0]);
|
|
3780
|
+
return `${usages.join("\n")}
|
|
3781
|
+
|
|
3782
|
+
${COMMON_HELP}
|
|
3783
|
+
`;
|
|
3784
|
+
}
|
|
3785
|
+
}
|
|
3786
|
+
if (hasHelpOption(rest)) {
|
|
3787
|
+
const name = `${group} ${command}`;
|
|
3788
|
+
if (Object.hasOwn(COMMAND_HELP, name)) {
|
|
3789
|
+
return `${COMMAND_HELP[name]}
|
|
3790
|
+
|
|
3791
|
+
${COMMON_HELP}
|
|
3792
|
+
`;
|
|
3793
|
+
}
|
|
3794
|
+
}
|
|
3795
|
+
return void 0;
|
|
3796
|
+
}
|
|
3797
|
+
|
|
3712
3798
|
// packages/host-runtime/src/delegation-types.ts
|
|
3713
3799
|
var DELEGATION_RUNTIME_ENDPOINT_ENV = "CODEXHOST_RUNTIME_ENDPOINT";
|
|
3714
3800
|
var DELEGATION_RUNTIME_TOKEN_ENV = "CODEXHOST_RUNTIME_TOKEN";
|
|
@@ -3725,6 +3811,114 @@ var DelegationControlError = class extends Error {
|
|
|
3725
3811
|
details;
|
|
3726
3812
|
};
|
|
3727
3813
|
|
|
3814
|
+
// packages/host-runtime/src/delegation-cli-output.ts
|
|
3815
|
+
function threadLink(threadId3) {
|
|
3816
|
+
return `codex://threads/${threadId3}`;
|
|
3817
|
+
}
|
|
3818
|
+
function inspectOutput({ harnessId, inspection }) {
|
|
3819
|
+
if (inspection.status !== "ready") return { harnessId, ...inspection };
|
|
3820
|
+
const { catalog } = inspection;
|
|
3821
|
+
return {
|
|
3822
|
+
harnessId,
|
|
3823
|
+
status: inspection.status,
|
|
3824
|
+
models: catalog.models.map(({ ref, label, supportedThinkingOptionIds }) => ({
|
|
3825
|
+
id: ref.id,
|
|
3826
|
+
label,
|
|
3827
|
+
...supportedThinkingOptionIds ? { thinking: supportedThinkingOptionIds } : {}
|
|
3828
|
+
})),
|
|
3829
|
+
...catalog.defaultModel ? { defaultModel: catalog.defaultModel.id } : {},
|
|
3830
|
+
thinkingOptions: catalog.thinkingOptions,
|
|
3831
|
+
...catalog.defaultThinkingOptionId ? { defaultThinkingOptionId: catalog.defaultThinkingOptionId } : {},
|
|
3832
|
+
capabilities: inspection.capabilities
|
|
3833
|
+
};
|
|
3834
|
+
}
|
|
3835
|
+
function snapshotOutput(snapshot, view) {
|
|
3836
|
+
const common = {
|
|
3837
|
+
thread: threadLink(snapshot.threadId),
|
|
3838
|
+
harnessId: snapshot.harnessId,
|
|
3839
|
+
status: snapshot.status,
|
|
3840
|
+
...snapshot.timedOut !== void 0 ? { timedOut: snapshot.timedOut } : {}
|
|
3841
|
+
};
|
|
3842
|
+
if (view === "messages") {
|
|
3843
|
+
if (typeof snapshot.hasMore !== "boolean") {
|
|
3844
|
+
throw new DelegationControlError(
|
|
3845
|
+
"INTERNAL_ERROR",
|
|
3846
|
+
"Compact message pagination requires an updated Host Runtime; use --format json with this Runtime."
|
|
3847
|
+
);
|
|
3848
|
+
}
|
|
3849
|
+
return {
|
|
3850
|
+
...common,
|
|
3851
|
+
messages: (snapshot.messages ?? []).map(({ role, phase, text }) => ({
|
|
3852
|
+
role,
|
|
3853
|
+
...phase ? { phase } : {},
|
|
3854
|
+
text
|
|
3855
|
+
})),
|
|
3856
|
+
hasMore: snapshot.hasMore,
|
|
3857
|
+
nextCursor: snapshot.nextCursor,
|
|
3858
|
+
...snapshot.result.message ? { error: snapshot.result.message } : {}
|
|
3859
|
+
};
|
|
3860
|
+
}
|
|
3861
|
+
const progress = snapshot.progress.filter(({ text }) => text.trim()).at(-1)?.text;
|
|
3862
|
+
return {
|
|
3863
|
+
...common,
|
|
3864
|
+
result: snapshot.result,
|
|
3865
|
+
...snapshot.status === "running" && progress ? { progress } : {}
|
|
3866
|
+
};
|
|
3867
|
+
}
|
|
3868
|
+
function compactDelegationOutput(command, body, view = "result") {
|
|
3869
|
+
switch (command) {
|
|
3870
|
+
case "harness list":
|
|
3871
|
+
return body;
|
|
3872
|
+
case "harness inspect":
|
|
3873
|
+
return inspectOutput(body);
|
|
3874
|
+
case "delegate start": {
|
|
3875
|
+
const result = body;
|
|
3876
|
+
const effective = result.configuration?.effective;
|
|
3877
|
+
return {
|
|
3878
|
+
thread: result.deepLink,
|
|
3879
|
+
harnessId: result.harnessId,
|
|
3880
|
+
status: result.status,
|
|
3881
|
+
...result.cwd ? { cwd: result.cwd } : {},
|
|
3882
|
+
...result.parentThreadId ? { parent: threadLink(result.parentThreadId) } : {},
|
|
3883
|
+
...effective?.resolvedModelLabel ? { model: effective.resolvedModelLabel } : {},
|
|
3884
|
+
...effective?.effectiveThinkingOptionId ? { thinking: effective.effectiveThinkingOptionId } : {}
|
|
3885
|
+
};
|
|
3886
|
+
}
|
|
3887
|
+
case "thread send": {
|
|
3888
|
+
const result = body;
|
|
3889
|
+
return {
|
|
3890
|
+
thread: threadLink(result.threadId),
|
|
3891
|
+
harnessId: result.harnessId,
|
|
3892
|
+
status: result.status
|
|
3893
|
+
};
|
|
3894
|
+
}
|
|
3895
|
+
case "thread cancel": {
|
|
3896
|
+
const result = body;
|
|
3897
|
+
return {
|
|
3898
|
+
thread: threadLink(result.threadId),
|
|
3899
|
+
harnessId: result.harnessId,
|
|
3900
|
+
cancelRequested: result.cancelled
|
|
3901
|
+
};
|
|
3902
|
+
}
|
|
3903
|
+
case "thread read":
|
|
3904
|
+
case "thread wait":
|
|
3905
|
+
return snapshotOutput(body, view);
|
|
3906
|
+
case "thread list": {
|
|
3907
|
+
const result = body;
|
|
3908
|
+
return {
|
|
3909
|
+
threads: result.threads.map(({ deepLink, harnessId, status, title, cwd }) => ({
|
|
3910
|
+
thread: deepLink,
|
|
3911
|
+
harnessId,
|
|
3912
|
+
status,
|
|
3913
|
+
...title ? { title } : {},
|
|
3914
|
+
...cwd ? { cwd } : {}
|
|
3915
|
+
})),
|
|
3916
|
+
nextCursor: result.nextCursor
|
|
3917
|
+
};
|
|
3918
|
+
}
|
|
3919
|
+
}
|
|
3920
|
+
}
|
|
3921
|
+
|
|
3728
3922
|
// packages/host-runtime/src/delegation-cli.ts
|
|
3729
3923
|
var DEFAULT_WAIT_TIMEOUT_MS = 3e4;
|
|
3730
3924
|
var DEFAULT_LIMIT = 25;
|
|
@@ -3771,44 +3965,12 @@ function value(parsed, name) {
|
|
|
3771
3965
|
return parsed.options.get(name);
|
|
3772
3966
|
}
|
|
3773
3967
|
function rejectUnknown(parsed, allowed) {
|
|
3774
|
-
const known = new Set(allowed);
|
|
3968
|
+
const known = /* @__PURE__ */ new Set([...allowed, "--format"]);
|
|
3775
3969
|
for (const name of parsed.options.keys()) {
|
|
3776
3970
|
if (!known.has(name))
|
|
3777
3971
|
throw new DelegationControlError("INVALID_ARGUMENT", `Unknown option '${name}'`);
|
|
3778
3972
|
}
|
|
3779
3973
|
}
|
|
3780
|
-
var DELEGATION_HELP = `usage:
|
|
3781
|
-
codexhost harness inspect <harness> [--cwd <path>] [--refresh true|false]
|
|
3782
|
-
codexhost delegate start --harness <id> --task <text> [--model <opaque-ref>] [--thinking <option-id>] [--parent-thread <thread>] [--request-id <id>]
|
|
3783
|
-
codexhost thread send <thread> --message <text>
|
|
3784
|
-
codexhost thread cancel <thread>
|
|
3785
|
-
codexhost thread read <thread> [--view result|messages] [--cursor <cursor>] [--limit <n>]
|
|
3786
|
-
codexhost thread wait <thread> [--timeout-ms <n>] [--view result|messages] [--cursor <cursor>] [--limit <n>]
|
|
3787
|
-
codexhost thread list [--cwd <path>] [--parent <thread>] [--limit <n>] [--cursor <cursor>] [--sort created-asc|created-desc|updated-asc|updated-desc|recency-asc|recency-desc]
|
|
3788
|
-
|
|
3789
|
-
Thread identifiers accept a bare ID or codex://threads/<id>. Output is JSON by default.
|
|
3790
|
-
harness inspect returns the target Model catalog, default Model, Thinking options, and configuration capabilities without creating a Thread. Use opaque IDs exactly as returned.
|
|
3791
|
-
delegate start requires --harness and --task, creates and submits the child Thread, then returns immediately. --model and --thinking select values returned by harness inspect. Omit either option to preserve that target's current default behavior. --parent-thread overrides caller inference. Reuse --request-id for idempotent retries; without it, identical recent parent/target/task/configuration requests are deduplicated briefly.
|
|
3792
|
-
Successful start fields: delegationId, threadId, turnId, harnessId, deepLink, status, next.read, next.wait.
|
|
3793
|
-
thread send starts a new Turn in an idle writable Thread and returns immediately. It fails with THREAD_BUSY instead of queueing or starting a concurrent Turn.
|
|
3794
|
-
thread cancel requests cancellation of the current Turn while preserving the Thread. An idle Thread returns cancelled=false.
|
|
3795
|
-
thread read is non-blocking. Its default result view returns threadId, harnessId, status, latest turn, visible progress, result.availability/result.text, and nextCursor.
|
|
3796
|
-
thread read --view messages additionally returns paginated user/Agent-visible messages. The default page is 25 and --limit is capped at 100; --cursor and --limit require the messages view. Tool calls, tool output, file activity, reasoning summaries, hidden reasoning, and private Harness transcripts are never returned.
|
|
3797
|
-
thread wait defaults to 30000 ms and waits only until the Thread reaches a terminal state or the bounded timeout expires. A timeout is a successful running checkpoint with timedOut=true; the child keeps running.
|
|
3798
|
-
thread list defaults to the caller cwd, limit 25, created-desc; limit is capped at 100. --parent uses Delegation lineage, not Codex Subagent relationships.
|
|
3799
|
-
read and wait are non-consuming: they do not start a Turn, send input, wake an Agent, mark messages read, or inject a result into the parent Session.
|
|
3800
|
-
Native Codex as caller requires a session sandbox that permits local Runtime connections; otherwise RUNTIME_UNREACHABLE is returned. Native Codex as a target uses brokered official requests and is unaffected.
|
|
3801
|
-
|
|
3802
|
-
Errors are JSON: {"error":{"code":"...","message":"...","details":{...}}}.
|
|
3803
|
-
INVALID_ARGUMENT: fix the named argument or incompatible option combination.
|
|
3804
|
-
HARNESS_NOT_FOUND: choose a Harness ID listed in error.details.validHarnessIds.
|
|
3805
|
-
THREAD_NOT_FOUND: verify the bare ID or codex:// deep link.
|
|
3806
|
-
THREAD_BUSY: wait for or cancel the active Turn before sending another message.
|
|
3807
|
-
PARENT_THREAD_AMBIGUOUS: pass --parent-thread explicitly.
|
|
3808
|
-
RUNTIME_UNREACHABLE: run inside the Host-provided environment and, for native Codex, allow local Runtime connections; codexhost never falls back to PATH or another Runtime.
|
|
3809
|
-
DELEGATION_FAILED: the target Session or initial task delivery failed and no successful child was published.
|
|
3810
|
-
INTERNAL_ERROR: retry after checking the Host Runtime diagnostics.
|
|
3811
|
-
`;
|
|
3812
3974
|
async function requestRuntime(input) {
|
|
3813
3975
|
const endpoint = input.environment[DELEGATION_RUNTIME_ENDPOINT_ENV];
|
|
3814
3976
|
const token = input.environment[DELEGATION_RUNTIME_TOKEN_ENV];
|
|
@@ -3854,12 +4016,37 @@ async function runDelegationCli(input) {
|
|
|
3854
4016
|
const environment = input.environment ?? process.env;
|
|
3855
4017
|
try {
|
|
3856
4018
|
const [group, command, ...rest] = input.arguments;
|
|
3857
|
-
|
|
3858
|
-
|
|
4019
|
+
const help = delegationCliHelp(input.arguments);
|
|
4020
|
+
if (help !== void 0) {
|
|
4021
|
+
output.write(help);
|
|
4022
|
+
return 0;
|
|
4023
|
+
}
|
|
4024
|
+
const parsed = options(rest);
|
|
4025
|
+
const format = value(parsed, "--format") ?? "json";
|
|
4026
|
+
if (format !== "json" && format !== "compact") {
|
|
4027
|
+
throw new DelegationControlError("INVALID_ARGUMENT", "--format must be json or compact");
|
|
4028
|
+
}
|
|
4029
|
+
const writeResult = (name, body, view = "result") => writeJson(output, format === "json" ? body : compactDelegationOutput(name, body, view));
|
|
4030
|
+
if (group === "harness" && command === "list") {
|
|
4031
|
+
rejectUnknown(parsed, []);
|
|
4032
|
+
if (parsed.positionals.length > 0) {
|
|
4033
|
+
throw new DelegationControlError(
|
|
4034
|
+
"INVALID_ARGUMENT",
|
|
4035
|
+
"harness list accepts no positional arguments"
|
|
4036
|
+
);
|
|
4037
|
+
}
|
|
4038
|
+
writeResult(
|
|
4039
|
+
"harness list",
|
|
4040
|
+
await requestRuntime({
|
|
4041
|
+
environment,
|
|
4042
|
+
path: "/v1/harness/list",
|
|
4043
|
+
body: {},
|
|
4044
|
+
...input.fetchImpl ? { fetchImpl: input.fetchImpl } : {}
|
|
4045
|
+
})
|
|
4046
|
+
);
|
|
3859
4047
|
return 0;
|
|
3860
4048
|
}
|
|
3861
4049
|
if (group === "harness" && command === "inspect") {
|
|
3862
|
-
const parsed = options(rest);
|
|
3863
4050
|
rejectUnknown(parsed, ["--cwd", "--refresh"]);
|
|
3864
4051
|
if (parsed.positionals.length !== 1) {
|
|
3865
4052
|
throw new DelegationControlError(
|
|
@@ -3875,8 +4062,8 @@ async function runDelegationCli(input) {
|
|
|
3875
4062
|
if (refresh !== void 0 && refresh !== "true" && refresh !== "false") {
|
|
3876
4063
|
throw new DelegationControlError("INVALID_ARGUMENT", "--refresh must be true or false");
|
|
3877
4064
|
}
|
|
3878
|
-
|
|
3879
|
-
|
|
4065
|
+
writeResult(
|
|
4066
|
+
"harness inspect",
|
|
3880
4067
|
await requestRuntime({
|
|
3881
4068
|
environment,
|
|
3882
4069
|
path: "/v1/harness/inspect",
|
|
@@ -3891,10 +4078,10 @@ async function runDelegationCli(input) {
|
|
|
3891
4078
|
return 0;
|
|
3892
4079
|
}
|
|
3893
4080
|
if (group === "delegate" && command === "start") {
|
|
3894
|
-
const parsed = options(rest);
|
|
3895
4081
|
rejectUnknown(parsed, [
|
|
3896
4082
|
"--harness",
|
|
3897
4083
|
"--task",
|
|
4084
|
+
"--cwd",
|
|
3898
4085
|
"--model",
|
|
3899
4086
|
"--thinking",
|
|
3900
4087
|
"--parent-thread",
|
|
@@ -3910,15 +4097,15 @@ async function runDelegationCli(input) {
|
|
|
3910
4097
|
if (!harnessId || !task)
|
|
3911
4098
|
throw new DelegationControlError("INVALID_ARGUMENT", "--harness and --task are required");
|
|
3912
4099
|
const parentThread = value(parsed, "--parent-thread") ?? environment[DELEGATION_THREAD_ID_ENV];
|
|
3913
|
-
|
|
3914
|
-
|
|
4100
|
+
writeResult(
|
|
4101
|
+
"delegate start",
|
|
3915
4102
|
await requestRuntime({
|
|
3916
4103
|
environment,
|
|
3917
4104
|
path: "/v1/delegate/start",
|
|
3918
4105
|
body: {
|
|
3919
4106
|
harnessId,
|
|
3920
4107
|
task,
|
|
3921
|
-
cwd:
|
|
4108
|
+
...value(parsed, "--cwd") ? { cwd: value(parsed, "--cwd") } : {},
|
|
3922
4109
|
...value(parsed, "--model") ? { model: { id: value(parsed, "--model") } } : {},
|
|
3923
4110
|
...value(parsed, "--thinking") ? { thinkingOptionId: value(parsed, "--thinking") } : {},
|
|
3924
4111
|
...parentThread ? { parentThreadId: normalizeThreadId(parentThread) } : {},
|
|
@@ -3930,7 +4117,6 @@ async function runDelegationCli(input) {
|
|
|
3930
4117
|
return 0;
|
|
3931
4118
|
}
|
|
3932
4119
|
if (group === "thread" && command === "send") {
|
|
3933
|
-
const parsed = options(rest);
|
|
3934
4120
|
rejectUnknown(parsed, ["--message"]);
|
|
3935
4121
|
if (parsed.positionals.length !== 1) {
|
|
3936
4122
|
throw new DelegationControlError(
|
|
@@ -3946,8 +4132,8 @@ async function runDelegationCli(input) {
|
|
|
3946
4132
|
"Thread identifier and --message are required"
|
|
3947
4133
|
);
|
|
3948
4134
|
}
|
|
3949
|
-
|
|
3950
|
-
|
|
4135
|
+
writeResult(
|
|
4136
|
+
"thread send",
|
|
3951
4137
|
await requestRuntime({
|
|
3952
4138
|
environment,
|
|
3953
4139
|
path: "/v1/thread/send",
|
|
@@ -3958,7 +4144,6 @@ async function runDelegationCli(input) {
|
|
|
3958
4144
|
return 0;
|
|
3959
4145
|
}
|
|
3960
4146
|
if (group === "thread" && command === "cancel") {
|
|
3961
|
-
const parsed = options(rest);
|
|
3962
4147
|
rejectUnknown(parsed, []);
|
|
3963
4148
|
if (parsed.positionals.length !== 1) {
|
|
3964
4149
|
throw new DelegationControlError(
|
|
@@ -3970,8 +4155,8 @@ async function runDelegationCli(input) {
|
|
|
3970
4155
|
if (!threadId3) {
|
|
3971
4156
|
throw new DelegationControlError("INVALID_ARGUMENT", "Thread identifier is required");
|
|
3972
4157
|
}
|
|
3973
|
-
|
|
3974
|
-
|
|
4158
|
+
writeResult(
|
|
4159
|
+
"thread cancel",
|
|
3975
4160
|
await requestRuntime({
|
|
3976
4161
|
environment,
|
|
3977
4162
|
path: "/v1/thread/cancel",
|
|
@@ -3982,7 +4167,6 @@ async function runDelegationCli(input) {
|
|
|
3982
4167
|
return 0;
|
|
3983
4168
|
}
|
|
3984
4169
|
if (group === "thread" && (command === "read" || command === "wait")) {
|
|
3985
|
-
const parsed = options(rest);
|
|
3986
4170
|
rejectUnknown(parsed, ["--view", "--cursor", "--limit", "--timeout-ms"]);
|
|
3987
4171
|
if (parsed.positionals.length !== 1)
|
|
3988
4172
|
throw new DelegationControlError(
|
|
@@ -4014,19 +4198,19 @@ async function runDelegationCli(input) {
|
|
|
4014
4198
|
timeoutMs: value(parsed, "--timeout-ms") ? positiveInteger(value(parsed, "--timeout-ms"), "--timeout-ms") : DEFAULT_WAIT_TIMEOUT_MS
|
|
4015
4199
|
} : {}
|
|
4016
4200
|
};
|
|
4017
|
-
|
|
4018
|
-
|
|
4201
|
+
writeResult(
|
|
4202
|
+
command === "read" ? "thread read" : "thread wait",
|
|
4019
4203
|
await requestRuntime({
|
|
4020
4204
|
environment,
|
|
4021
4205
|
path: command === "read" ? "/v1/thread/read" : "/v1/thread/wait",
|
|
4022
4206
|
body,
|
|
4023
4207
|
...input.fetchImpl ? { fetchImpl: input.fetchImpl } : {}
|
|
4024
|
-
})
|
|
4208
|
+
}),
|
|
4209
|
+
view
|
|
4025
4210
|
);
|
|
4026
4211
|
return 0;
|
|
4027
4212
|
}
|
|
4028
4213
|
if (group === "thread" && command === "list") {
|
|
4029
|
-
const parsed = options(rest);
|
|
4030
4214
|
rejectUnknown(parsed, ["--cwd", "--parent", "--limit", "--cursor", "--sort"]);
|
|
4031
4215
|
if (parsed.positionals.length > 0)
|
|
4032
4216
|
throw new DelegationControlError(
|
|
@@ -4044,8 +4228,8 @@ async function runDelegationCli(input) {
|
|
|
4044
4228
|
])).has(sort))
|
|
4045
4229
|
throw new DelegationControlError("INVALID_ARGUMENT", "--sort is invalid");
|
|
4046
4230
|
const parentThread = value(parsed, "--parent");
|
|
4047
|
-
|
|
4048
|
-
|
|
4231
|
+
writeResult(
|
|
4232
|
+
"thread list",
|
|
4049
4233
|
await requestRuntime({
|
|
4050
4234
|
environment,
|
|
4051
4235
|
path: "/v1/thread/list",
|
|
@@ -4083,7 +4267,8 @@ async function runDelegationCli(input) {
|
|
|
4083
4267
|
|
|
4084
4268
|
// packages/host-runtime/src/run-host-runtime.ts
|
|
4085
4269
|
import { randomBytes } from "node:crypto";
|
|
4086
|
-
import
|
|
4270
|
+
import path20 from "node:path";
|
|
4271
|
+
import { homedir } from "node:os";
|
|
4087
4272
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
4088
4273
|
|
|
4089
4274
|
// packages/update-manager/dist/distribution.js
|
|
@@ -5701,10 +5886,10 @@ function mergeDefs(...defs) {
|
|
|
5701
5886
|
function cloneDef(schema) {
|
|
5702
5887
|
return mergeDefs(schema._zod.def);
|
|
5703
5888
|
}
|
|
5704
|
-
function getElementAtPath(obj,
|
|
5705
|
-
if (!
|
|
5889
|
+
function getElementAtPath(obj, path25) {
|
|
5890
|
+
if (!path25)
|
|
5706
5891
|
return obj;
|
|
5707
|
-
return
|
|
5892
|
+
return path25.reduce((acc, key) => acc?.[key], obj);
|
|
5708
5893
|
}
|
|
5709
5894
|
function promiseAllObject(promisesObj) {
|
|
5710
5895
|
const keys = Object.keys(promisesObj);
|
|
@@ -6113,11 +6298,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
6113
6298
|
}
|
|
6114
6299
|
return false;
|
|
6115
6300
|
}
|
|
6116
|
-
function prefixIssues(
|
|
6301
|
+
function prefixIssues(path25, issues) {
|
|
6117
6302
|
return issues.map((iss) => {
|
|
6118
6303
|
var _a3;
|
|
6119
6304
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
6120
|
-
iss.path.unshift(
|
|
6305
|
+
iss.path.unshift(path25);
|
|
6121
6306
|
return iss;
|
|
6122
6307
|
});
|
|
6123
6308
|
}
|
|
@@ -6264,16 +6449,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
6264
6449
|
}
|
|
6265
6450
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
6266
6451
|
const fieldErrors = { _errors: [] };
|
|
6267
|
-
const processError = (error52,
|
|
6452
|
+
const processError = (error52, path25 = []) => {
|
|
6268
6453
|
for (const issue2 of error52.issues) {
|
|
6269
6454
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
6270
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
6455
|
+
issue2.errors.map((issues) => processError({ issues }, [...path25, ...issue2.path]));
|
|
6271
6456
|
} else if (issue2.code === "invalid_key") {
|
|
6272
|
-
processError({ issues: issue2.issues }, [...
|
|
6457
|
+
processError({ issues: issue2.issues }, [...path25, ...issue2.path]);
|
|
6273
6458
|
} else if (issue2.code === "invalid_element") {
|
|
6274
|
-
processError({ issues: issue2.issues }, [...
|
|
6459
|
+
processError({ issues: issue2.issues }, [...path25, ...issue2.path]);
|
|
6275
6460
|
} else {
|
|
6276
|
-
const fullpath = [...
|
|
6461
|
+
const fullpath = [...path25, ...issue2.path];
|
|
6277
6462
|
if (fullpath.length === 0) {
|
|
6278
6463
|
fieldErrors._errors.push(mapper(issue2));
|
|
6279
6464
|
} else {
|
|
@@ -6300,17 +6485,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
6300
6485
|
}
|
|
6301
6486
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
6302
6487
|
const result = { errors: [] };
|
|
6303
|
-
const processError = (error52,
|
|
6488
|
+
const processError = (error52, path25 = []) => {
|
|
6304
6489
|
var _a3, _b;
|
|
6305
6490
|
for (const issue2 of error52.issues) {
|
|
6306
6491
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
6307
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
6492
|
+
issue2.errors.map((issues) => processError({ issues }, [...path25, ...issue2.path]));
|
|
6308
6493
|
} else if (issue2.code === "invalid_key") {
|
|
6309
|
-
processError({ issues: issue2.issues }, [...
|
|
6494
|
+
processError({ issues: issue2.issues }, [...path25, ...issue2.path]);
|
|
6310
6495
|
} else if (issue2.code === "invalid_element") {
|
|
6311
|
-
processError({ issues: issue2.issues }, [...
|
|
6496
|
+
processError({ issues: issue2.issues }, [...path25, ...issue2.path]);
|
|
6312
6497
|
} else {
|
|
6313
|
-
const fullpath = [...
|
|
6498
|
+
const fullpath = [...path25, ...issue2.path];
|
|
6314
6499
|
if (fullpath.length === 0) {
|
|
6315
6500
|
result.errors.push(mapper(issue2));
|
|
6316
6501
|
continue;
|
|
@@ -6342,8 +6527,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
6342
6527
|
}
|
|
6343
6528
|
function toDotPath(_path) {
|
|
6344
6529
|
const segs = [];
|
|
6345
|
-
const
|
|
6346
|
-
for (const seg of
|
|
6530
|
+
const path25 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
6531
|
+
for (const seg of path25) {
|
|
6347
6532
|
if (typeof seg === "number")
|
|
6348
6533
|
segs.push(`[${seg}]`);
|
|
6349
6534
|
else if (typeof seg === "symbol")
|
|
@@ -19035,13 +19220,13 @@ function resolveRef(ref, ctx) {
|
|
|
19035
19220
|
if (!ref.startsWith("#")) {
|
|
19036
19221
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
19037
19222
|
}
|
|
19038
|
-
const
|
|
19039
|
-
if (
|
|
19223
|
+
const path25 = ref.slice(1).split("/").filter(Boolean);
|
|
19224
|
+
if (path25.length === 0) {
|
|
19040
19225
|
return ctx.rootSchema;
|
|
19041
19226
|
}
|
|
19042
19227
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
19043
|
-
if (
|
|
19044
|
-
const key =
|
|
19228
|
+
if (path25[0] === defsKey) {
|
|
19229
|
+
const key = path25[1];
|
|
19045
19230
|
if (!key || !ctx.defs[key]) {
|
|
19046
19231
|
throw new Error(`Reference not found: ${ref}`);
|
|
19047
19232
|
}
|
|
@@ -19475,6 +19660,8 @@ var threadUsageSnapshotSchema = external_exports.object({
|
|
|
19475
19660
|
reasoningOutputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
19476
19661
|
totalTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
19477
19662
|
totalCostUsd: finiteNonNegativeNumberSchema.optional(),
|
|
19663
|
+
totalCredits: finiteNonNegativeNumberSchema.optional(),
|
|
19664
|
+
contextUsagePercent: finiteNonNegativeNumberSchema.optional(),
|
|
19478
19665
|
cacheHitRatePercent: cacheHitRatePercentSchema.optional(),
|
|
19479
19666
|
contextWindowTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
19480
19667
|
contextUsedTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
@@ -20386,7 +20573,9 @@ var usageFields = /* @__PURE__ */ new Set([
|
|
|
20386
20573
|
...tokenFields,
|
|
20387
20574
|
...safeIntegerFields,
|
|
20388
20575
|
...percentFields,
|
|
20389
|
-
"totalCostUsd"
|
|
20576
|
+
"totalCostUsd",
|
|
20577
|
+
"totalCredits",
|
|
20578
|
+
"contextUsagePercent"
|
|
20390
20579
|
]);
|
|
20391
20580
|
function isRecord(value2) {
|
|
20392
20581
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
@@ -20402,6 +20591,12 @@ function parseHostUsage(value2) {
|
|
|
20402
20591
|
throw new Error(`Harness Usage contains unknown field '${key}'`);
|
|
20403
20592
|
}
|
|
20404
20593
|
}
|
|
20594
|
+
for (const field of ["totalCredits", "contextUsagePercent"]) {
|
|
20595
|
+
const candidate = value2[field];
|
|
20596
|
+
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0)) {
|
|
20597
|
+
throw new Error(`Harness Usage '${field}' must be a finite non-negative number`);
|
|
20598
|
+
}
|
|
20599
|
+
}
|
|
20405
20600
|
for (const field of tokenFields) {
|
|
20406
20601
|
const candidate = value2[field];
|
|
20407
20602
|
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
|
|
@@ -20726,7 +20921,7 @@ var MappingStore = class {
|
|
|
20726
20921
|
]);
|
|
20727
20922
|
await this.#acquireLock();
|
|
20728
20923
|
try {
|
|
20729
|
-
await this.#
|
|
20924
|
+
await this.#cleanupResidue();
|
|
20730
20925
|
const names = (await readdir2(this.#threadsDirectory)).filter((name) => name.endsWith(".json"));
|
|
20731
20926
|
for (const name of names) {
|
|
20732
20927
|
const primary = path4.join(this.#threadsDirectory, name);
|
|
@@ -21150,14 +21345,17 @@ var MappingStore = class {
|
|
|
21150
21345
|
}
|
|
21151
21346
|
return parsed.data;
|
|
21152
21347
|
}
|
|
21153
|
-
async #
|
|
21154
|
-
const [threadNames, delegationNames] = await Promise.all([
|
|
21348
|
+
async #cleanupResidue() {
|
|
21349
|
+
const [threadNames, delegationNames, rootNames] = await Promise.all([
|
|
21155
21350
|
readdir2(this.#threadsDirectory),
|
|
21156
|
-
readdir2(this.#delegationsDirectory)
|
|
21351
|
+
readdir2(this.#delegationsDirectory),
|
|
21352
|
+
readdir2(this.#directory)
|
|
21157
21353
|
]);
|
|
21158
21354
|
await Promise.all([
|
|
21159
21355
|
...threadNames.filter((name) => name.includes(".tmp-")).map((name) => rm3(path4.join(this.#threadsDirectory, name), { force: true })),
|
|
21160
|
-
...delegationNames.filter((name) => name.includes(".tmp-")).map((name) => rm3(path4.join(this.#delegationsDirectory, name), { force: true }))
|
|
21356
|
+
...delegationNames.filter((name) => name.includes(".tmp-")).map((name) => rm3(path4.join(this.#delegationsDirectory, name), { force: true })),
|
|
21357
|
+
// Renamed aside by #acquireLock; nothing reads them back, and they accumulate one per run.
|
|
21358
|
+
...rootNames.filter((name) => name.startsWith(`${path4.basename(this.#lockPath)}.stale-`)).map((name) => rm3(path4.join(this.#directory, name), { force: true }))
|
|
21161
21359
|
]);
|
|
21162
21360
|
}
|
|
21163
21361
|
async #acquireLock() {
|
|
@@ -21349,6 +21547,9 @@ function projectCodexApprovalRequest(input) {
|
|
|
21349
21547
|
throw new Error("Host Approval subject is unsupported");
|
|
21350
21548
|
}
|
|
21351
21549
|
validateActions(interaction);
|
|
21550
|
+
if (new Set(interaction.actions.map(({ effect }) => effect)).size !== interaction.actions.length) {
|
|
21551
|
+
return projectApprovalChoices(input);
|
|
21552
|
+
}
|
|
21352
21553
|
const allow = requiredActionForEffect(interaction, "allowOnce");
|
|
21353
21554
|
const allowForSession = optionalActionForEffect(interaction, "allowForSession");
|
|
21354
21555
|
const allowAlways = optionalActionForEffect(interaction, "allowAlways");
|
|
@@ -21414,6 +21615,63 @@ function projectCodexApprovalRequest(input) {
|
|
|
21414
21615
|
}
|
|
21415
21616
|
};
|
|
21416
21617
|
}
|
|
21618
|
+
function projectApprovalChoices(input) {
|
|
21619
|
+
const { interaction } = input;
|
|
21620
|
+
const allow = actionsForEffect(interaction, "allowOnce")[0];
|
|
21621
|
+
const deny = actionsForEffect(interaction, "deny")[0];
|
|
21622
|
+
if (!allow || !deny)
|
|
21623
|
+
throw new Error("Host Approval must declare allowOnce and deny actions");
|
|
21624
|
+
const denyResponse = { type: "approval", actionId: deny.id };
|
|
21625
|
+
return {
|
|
21626
|
+
request: {
|
|
21627
|
+
method: "mcpServer/elicitation/request",
|
|
21628
|
+
params: {
|
|
21629
|
+
serverName: boundedText(input.serverName, "server name", SERVER_NAME_MAX_LENGTH),
|
|
21630
|
+
threadId: input.threadId,
|
|
21631
|
+
turnId: interaction.turnId,
|
|
21632
|
+
mode: "form",
|
|
21633
|
+
message: [
|
|
21634
|
+
clampedText(interaction.title, "title", TITLE_MAX_LENGTH),
|
|
21635
|
+
...interaction.description ? [interaction.description] : []
|
|
21636
|
+
].join("\n\n"),
|
|
21637
|
+
requestedSchema: {
|
|
21638
|
+
type: "object",
|
|
21639
|
+
properties: {
|
|
21640
|
+
actionId: {
|
|
21641
|
+
type: "string",
|
|
21642
|
+
title: "Approval",
|
|
21643
|
+
oneOf: interaction.actions.map(({ id: id2, label }) => ({ const: id2, title: label })),
|
|
21644
|
+
default: allow.id
|
|
21645
|
+
}
|
|
21646
|
+
},
|
|
21647
|
+
required: ["actionId"]
|
|
21648
|
+
}
|
|
21649
|
+
}
|
|
21650
|
+
},
|
|
21651
|
+
denyResponse,
|
|
21652
|
+
parseResponse(result) {
|
|
21653
|
+
if (!isRecord2(result) || typeof result.action !== "string")
|
|
21654
|
+
throw responseError("missing action");
|
|
21655
|
+
if (Object.keys(result).some((key) => !["action", "content", "_meta"].includes(key))) {
|
|
21656
|
+
throw responseError("contains unreviewed fields");
|
|
21657
|
+
}
|
|
21658
|
+
if (result._meta !== void 0 && result._meta !== null) {
|
|
21659
|
+
throw responseError("contains unexpected persist metadata");
|
|
21660
|
+
}
|
|
21661
|
+
if (result.action === "decline" || result.action === "cancel") {
|
|
21662
|
+
if (result.content !== void 0 && result.content !== null) {
|
|
21663
|
+
throw responseError("contains fields incompatible with denial");
|
|
21664
|
+
}
|
|
21665
|
+
return denyResponse;
|
|
21666
|
+
}
|
|
21667
|
+
const content = result.content;
|
|
21668
|
+
if (result.action !== "accept" || !isRecord2(content) || Object.keys(content).length !== 1 || !interaction.actions.some(({ id: id2 }) => id2 === content.actionId)) {
|
|
21669
|
+
throw responseError("contains an undeclared approval choice");
|
|
21670
|
+
}
|
|
21671
|
+
return { type: "approval", actionId: content.actionId };
|
|
21672
|
+
}
|
|
21673
|
+
};
|
|
21674
|
+
}
|
|
21417
21675
|
|
|
21418
21676
|
// packages/protocol-core/dist/codex-question.js
|
|
21419
21677
|
function isRecord3(value2) {
|
|
@@ -21957,8 +22215,8 @@ function projectFileChangeKind(kind) {
|
|
|
21957
22215
|
return { type: kind };
|
|
21958
22216
|
}
|
|
21959
22217
|
function projectFileChanges(changes) {
|
|
21960
|
-
return changes.map(({ path:
|
|
21961
|
-
path:
|
|
22218
|
+
return changes.map(({ path: path25, kind, unifiedDiff }) => ({
|
|
22219
|
+
path: path25,
|
|
21962
22220
|
kind: projectFileChangeKind(kind),
|
|
21963
22221
|
diff: unifiedDiff
|
|
21964
22222
|
}));
|
|
@@ -22116,7 +22374,7 @@ function projectItem(item, outcome, defaultCwd, includeCommandOutput = true, sen
|
|
|
22116
22374
|
id: item.itemId,
|
|
22117
22375
|
type: "agentMessage",
|
|
22118
22376
|
text: item.text,
|
|
22119
|
-
phase: null,
|
|
22377
|
+
phase: item.phase ?? null,
|
|
22120
22378
|
memoryCitation: null
|
|
22121
22379
|
};
|
|
22122
22380
|
case "reasoning":
|
|
@@ -22179,7 +22437,9 @@ function projectItem(item, outcome, defaultCwd, includeCommandOutput = true, sen
|
|
|
22179
22437
|
changes: projectFileChanges(item.changes),
|
|
22180
22438
|
status: itemStatus(outcome)
|
|
22181
22439
|
};
|
|
22182
|
-
case "subagentDelegation":
|
|
22440
|
+
case "subagentDelegation": {
|
|
22441
|
+
const primary = item.subagents[0];
|
|
22442
|
+
const sameConfiguration = item.subagents.every((subagent) => subagent.model === primary?.model && subagent.reasoningEffort === primary?.reasoningEffort);
|
|
22183
22443
|
return {
|
|
22184
22444
|
id: item.itemId,
|
|
22185
22445
|
type: "collabAgentToolCall",
|
|
@@ -22188,13 +22448,14 @@ function projectItem(item, outcome, defaultCwd, includeCommandOutput = true, sen
|
|
|
22188
22448
|
senderThreadId: senderThreadId ?? "",
|
|
22189
22449
|
receiverThreadIds: item.subagents.map(({ subagentId }) => subagentId),
|
|
22190
22450
|
prompt: item.prompt ?? null,
|
|
22191
|
-
model: null,
|
|
22192
|
-
reasoningEffort: null,
|
|
22451
|
+
model: sameConfiguration ? primary?.model ?? null : null,
|
|
22452
|
+
reasoningEffort: sameConfiguration ? primary?.reasoningEffort ?? null : null,
|
|
22193
22453
|
agentsStates: Object.fromEntries(item.subagents.map(({ subagentId, status, resultSummary }) => [
|
|
22194
22454
|
subagentId,
|
|
22195
22455
|
{ status: collabAgentStatus(status), message: resultSummary ?? null }
|
|
22196
22456
|
]))
|
|
22197
22457
|
};
|
|
22458
|
+
}
|
|
22198
22459
|
}
|
|
22199
22460
|
}
|
|
22200
22461
|
function reasoningPreviewItemId(itemId) {
|
|
@@ -22238,6 +22499,9 @@ function historicalStatus(outcome) {
|
|
|
22238
22499
|
}
|
|
22239
22500
|
function projectHistoricalTurn(input) {
|
|
22240
22501
|
const { turnId, cwd, snapshot } = input;
|
|
22502
|
+
const startedAtMs = snapshot.startedAtMs;
|
|
22503
|
+
const completedAtMs = snapshot.completedAtMs;
|
|
22504
|
+
const hasTiming = startedAtMs !== void 0 && completedAtMs !== void 0 && Number.isFinite(startedAtMs) && Number.isFinite(completedAtMs) && startedAtMs >= 0 && completedAtMs >= startedAtMs;
|
|
22241
22505
|
const error51 = snapshot.outcome.status === "failed" ? {
|
|
22242
22506
|
message: snapshot.outcome.error.message,
|
|
22243
22507
|
codexErrorInfo: "other",
|
|
@@ -22273,9 +22537,9 @@ function projectHistoricalTurn(input) {
|
|
|
22273
22537
|
})
|
|
22274
22538
|
],
|
|
22275
22539
|
error: error51,
|
|
22276
|
-
startedAt: null,
|
|
22277
|
-
completedAt: null,
|
|
22278
|
-
durationMs: null,
|
|
22540
|
+
startedAt: hasTiming ? Math.floor(startedAtMs / 1e3) : null,
|
|
22541
|
+
completedAt: hasTiming ? Math.floor(completedAtMs / 1e3) : null,
|
|
22542
|
+
durationMs: hasTiming ? completedAtMs - startedAtMs : null,
|
|
22279
22543
|
itemsView: "full"
|
|
22280
22544
|
};
|
|
22281
22545
|
}
|
|
@@ -22901,13 +23165,13 @@ function decodeThreadForkRequest(request) {
|
|
|
22901
23165
|
if (runtimeWorkspaceRoots !== void 0 && runtimeWorkspaceRoots !== null && (!Array.isArray(runtimeWorkspaceRoots) || runtimeWorkspaceRoots.some((root) => typeof root !== "string" || root.length === 0))) {
|
|
22902
23166
|
throw new Error("thread/fork params.runtimeWorkspaceRoots must be text paths or null");
|
|
22903
23167
|
}
|
|
22904
|
-
const
|
|
23168
|
+
const path25 = optionalText(params, "path", { allowEmpty: true });
|
|
22905
23169
|
const ephemeral = optionalBoolean(params, "ephemeral");
|
|
22906
23170
|
return {
|
|
22907
23171
|
threadId: threadId3,
|
|
22908
23172
|
...lastTurnText ? { lastTurnId: hostTurnIdSchema.parse(lastTurnText) } : {},
|
|
22909
23173
|
...beforeTurnText ? { beforeTurnId: hostTurnIdSchema.parse(beforeTurnText) } : {},
|
|
22910
|
-
...
|
|
23174
|
+
...path25 ? { path: path25 } : {},
|
|
22911
23175
|
...optionalField(params, "model"),
|
|
22912
23176
|
...optionalField(params, "modelProvider"),
|
|
22913
23177
|
...optionalField(params, "cwd"),
|
|
@@ -24862,6 +25126,7 @@ async function executeCurrentLastTurnRollback(input) {
|
|
|
24862
25126
|
error: { code: -32079, message: "External Native Session is unavailable" }
|
|
24863
25127
|
};
|
|
24864
25128
|
}
|
|
25129
|
+
const configuration = currentConfiguration(current);
|
|
24865
25130
|
let opened;
|
|
24866
25131
|
try {
|
|
24867
25132
|
opened = await adapter.open({
|
|
@@ -24871,7 +25136,10 @@ async function executeCurrentLastTurnRollback(input) {
|
|
|
24871
25136
|
...input.environment ?? process.env,
|
|
24872
25137
|
[DELEGATION_THREAD_ID_ENV]: current.id
|
|
24873
25138
|
},
|
|
24874
|
-
sourceRef: currentNativeRef
|
|
25139
|
+
sourceRef: currentNativeRef,
|
|
25140
|
+
...configuration.effectiveModel ? { model: configuration.effectiveModel } : {},
|
|
25141
|
+
...configuration.effectiveThinkingOptionId ? { thinkingOptionId: configuration.effectiveThinkingOptionId } : {},
|
|
25142
|
+
...configuration.effectivePermissionModeId ? { permissionModeId: configuration.effectivePermissionModeId } : {}
|
|
24875
25143
|
});
|
|
24876
25144
|
} catch {
|
|
24877
25145
|
return { ok: false, error: { code: -32076, message: "External Thread rollback failed" } };
|
|
@@ -24888,7 +25156,6 @@ async function executeCurrentLastTurnRollback(input) {
|
|
|
24888
25156
|
error: { code: -32076, message: "External rollback did not return a valid Session" }
|
|
24889
25157
|
};
|
|
24890
25158
|
}
|
|
24891
|
-
const configuration = currentConfiguration(current);
|
|
24892
25159
|
const configurationError = await restoreCurrentConfiguration(session, configuration);
|
|
24893
25160
|
if (configurationError) {
|
|
24894
25161
|
await session.close().catch(() => void 0);
|
|
@@ -25460,6 +25727,8 @@ var ExternalThreadRuntime = class {
|
|
|
25460
25727
|
environment: { ...this.#environment, [DELEGATION_THREAD_ID_ENV]: record3.hostThreadId },
|
|
25461
25728
|
nativeRef: record3.nativeSessionRef,
|
|
25462
25729
|
knownTurnRefs: record3.turnMappings.map(({ nativeTurnRef }) => nativeTurnRef),
|
|
25730
|
+
...restoredSelection?.model ? { model: restoredSelection.model } : {},
|
|
25731
|
+
...restoredSelection?.thinkingOptionId ? { thinkingOptionId: restoredSelection.thinkingOptionId } : {},
|
|
25463
25732
|
...harnessId === "grok" && restoredSelection?.permissionModeId ? { permissionModeId: restoredSelection.permissionModeId } : {}
|
|
25464
25733
|
});
|
|
25465
25734
|
if (!opened.ok) {
|
|
@@ -25816,15 +26085,21 @@ function projectDelegationThreadSnapshot(input) {
|
|
|
25816
26085
|
const latestTurnStatus = latestTurn ? turnStatus2(latestTurn.status) : null;
|
|
25817
26086
|
const status = input.running ? "running" : latestTurnStatus === "failed" || latestTurnStatus === "interrupted" ? latestTurnStatus : threadStatus(input.thread.status, input.running);
|
|
25818
26087
|
const latestTurnMessages = latestTurnId ? visible.filter((message) => message.turnId === latestTurnId && message.role === "agent") : [];
|
|
25819
|
-
const final = latestTurnMessages.filter((message) => message.phase === "final").at(-1);
|
|
25820
|
-
const progress = latestTurnMessages.filter((message) => message.phase !== "final").map(({ id: id2, turnId, text }) => ({ id: id2, turnId, text }));
|
|
26088
|
+
const final = latestTurnMessages.filter((message) => message.phase === "final" && message.text.trim()).at(-1);
|
|
26089
|
+
const progress = latestTurnMessages.filter((message) => message.phase !== "final" && message.text.trim()).map(({ id: id2, turnId, text }) => ({ id: id2, turnId, text }));
|
|
25821
26090
|
const result = input.running ? { availability: "pending" } : final ? { availability: "available", text: final.text } : {
|
|
25822
26091
|
availability: "unavailable",
|
|
25823
26092
|
...isRecord8(latestTurn?.error) && typeof latestTurn.error.message === "string" ? { message: latestTurn.error.message } : {}
|
|
25824
26093
|
};
|
|
25825
26094
|
const offset = options2.view === "messages" ? decodeCursor(input.threadId, options2.cursor) : visible.length;
|
|
25826
|
-
const page = options2.view === "messages" ?
|
|
25827
|
-
|
|
26095
|
+
const page = options2.view === "messages" ? [] : void 0;
|
|
26096
|
+
let nextOffset = offset;
|
|
26097
|
+
if (page) {
|
|
26098
|
+
while (nextOffset < visible.length && page.length < options2.limit) {
|
|
26099
|
+
const message = visible[nextOffset++];
|
|
26100
|
+
if (message?.text.trim()) page.push(message);
|
|
26101
|
+
}
|
|
26102
|
+
}
|
|
25828
26103
|
return {
|
|
25829
26104
|
threadId: input.threadId,
|
|
25830
26105
|
harnessId: input.harnessId,
|
|
@@ -25832,7 +26107,10 @@ function projectDelegationThreadSnapshot(input) {
|
|
|
25832
26107
|
turn: latestTurnId && latestTurnStatus ? { turnId: latestTurnId, status: latestTurnStatus } : null,
|
|
25833
26108
|
progress,
|
|
25834
26109
|
result,
|
|
25835
|
-
...page ? {
|
|
26110
|
+
...page ? {
|
|
26111
|
+
messages: page,
|
|
26112
|
+
hasMore: visible.slice(nextOffset).some((message) => message.text.trim())
|
|
26113
|
+
} : {},
|
|
25836
26114
|
nextCursor: encodeCursor(input.threadId, nextOffset)
|
|
25837
26115
|
};
|
|
25838
26116
|
}
|
|
@@ -25864,11 +26142,11 @@ function statusFromThread(thread) {
|
|
|
25864
26142
|
return last ? "completed" : "creating";
|
|
25865
26143
|
}
|
|
25866
26144
|
function validateStart(input) {
|
|
25867
|
-
if (!input.task
|
|
26145
|
+
if (typeof input.task !== "string" || !input.task.trim())
|
|
25868
26146
|
throw new DelegationControlError("INVALID_ARGUMENT", "Task must not be empty");
|
|
25869
|
-
if (!input.cwd
|
|
26147
|
+
if (input.cwd !== void 0 && (typeof input.cwd !== "string" || !input.cwd.trim()))
|
|
25870
26148
|
throw new DelegationControlError("INVALID_ARGUMENT", "cwd must not be empty");
|
|
25871
|
-
if (input.requestId !== void 0 && !input.requestId.trim()) {
|
|
26149
|
+
if (input.requestId !== void 0 && (typeof input.requestId !== "string" || !input.requestId.trim())) {
|
|
25872
26150
|
throw new DelegationControlError("INVALID_ARGUMENT", "Request ID must not be empty");
|
|
25873
26151
|
}
|
|
25874
26152
|
}
|
|
@@ -25886,6 +26164,7 @@ var HarnessDelegationCoordinator = class {
|
|
|
25886
26164
|
#cancelOfficial;
|
|
25887
26165
|
#startOfficial;
|
|
25888
26166
|
#listOfficial;
|
|
26167
|
+
#officialThreadCwd;
|
|
25889
26168
|
#activeOfficialParents;
|
|
25890
26169
|
constructor(input) {
|
|
25891
26170
|
this.#adapters = input.adapters;
|
|
@@ -25901,8 +26180,12 @@ var HarnessDelegationCoordinator = class {
|
|
|
25901
26180
|
this.#cancelOfficial = input.cancelOfficial;
|
|
25902
26181
|
this.#startOfficial = input.startOfficial;
|
|
25903
26182
|
this.#listOfficial = input.listOfficial;
|
|
26183
|
+
this.#officialThreadCwd = input.officialThreadCwd;
|
|
25904
26184
|
this.#activeOfficialParents = input.activeOfficialParents;
|
|
25905
26185
|
}
|
|
26186
|
+
async listHarnesses() {
|
|
26187
|
+
return { harnesses: ["codex", ...this.#adapters.keys()] };
|
|
26188
|
+
}
|
|
25906
26189
|
async inspect(input) {
|
|
25907
26190
|
if (input.harnessId === "codex") return this.#inspectOfficial(input);
|
|
25908
26191
|
const adapter = this.#adapters.get(input.harnessId);
|
|
@@ -25924,7 +26207,13 @@ var HarnessDelegationCoordinator = class {
|
|
|
25924
26207
|
async start(input) {
|
|
25925
26208
|
validateStart(input);
|
|
25926
26209
|
const parentThreadId = await this.#resolveParent(input.parentThreadId);
|
|
25927
|
-
|
|
26210
|
+
const parent = await this.#parentMetadata(parentThreadId);
|
|
26211
|
+
const selectedCwd = input.cwd ?? parent.cwd ?? process.cwd();
|
|
26212
|
+
if (input.harnessId === "codex") {
|
|
26213
|
+
const result = await this.#startOfficial({ ...input, parentThreadId, cwd: selectedCwd });
|
|
26214
|
+
return { ...result, parentThreadId, cwd: result.cwd ?? selectedCwd };
|
|
26215
|
+
}
|
|
26216
|
+
const startInput = { ...input, parentThreadId, cwd: path6.resolve(selectedCwd) };
|
|
25928
26217
|
if (!this.#adapters.has(input.harnessId)) {
|
|
25929
26218
|
throw new DelegationControlError(
|
|
25930
26219
|
"HARNESS_NOT_FOUND",
|
|
@@ -25933,7 +26222,7 @@ var HarnessDelegationCoordinator = class {
|
|
|
25933
26222
|
);
|
|
25934
26223
|
}
|
|
25935
26224
|
const targetHarnessId = input.harnessId;
|
|
25936
|
-
const digest2 = taskDigest(
|
|
26225
|
+
const digest2 = taskDigest(startInput);
|
|
25937
26226
|
const duplicate = input.requestId ? await this.#repository.findDelegationByRequest(input.requestId) : await this.#repository.findRecentDelegation({
|
|
25938
26227
|
parentHostThreadId: hostThreadIdSchema.parse(parentThreadId),
|
|
25939
26228
|
targetHarnessId: harnessIdSchema.parse(targetHarnessId),
|
|
@@ -25960,11 +26249,10 @@ var HarnessDelegationCoordinator = class {
|
|
|
25960
26249
|
if (input.model || input.thinkingOptionId) {
|
|
25961
26250
|
const inspected = await this.inspect({
|
|
25962
26251
|
harnessId: targetHarnessId,
|
|
25963
|
-
cwd:
|
|
26252
|
+
cwd: startInput.cwd
|
|
25964
26253
|
});
|
|
25965
26254
|
this.#validateConfiguration(inspected.inspection, input.model, input.thinkingOptionId);
|
|
25966
26255
|
}
|
|
25967
|
-
const parent = await this.#parentMetadata(parentThreadId);
|
|
25968
26256
|
const delegationId = hostThreadIdSchema.parse(randomUUID4());
|
|
25969
26257
|
const childThreadId = hostThreadIdSchema.parse(randomUUID4());
|
|
25970
26258
|
const turnId = hostTurnIdSchema.parse(randomUUID4());
|
|
@@ -25974,7 +26262,7 @@ var HarnessDelegationCoordinator = class {
|
|
|
25974
26262
|
hostThreadId: childThreadId,
|
|
25975
26263
|
createRequestId,
|
|
25976
26264
|
harnessId: harnessIdSchema.parse(targetHarnessId),
|
|
25977
|
-
cwd:
|
|
26265
|
+
cwd: startInput.cwd,
|
|
25978
26266
|
title: input.task.trim().slice(0, 120),
|
|
25979
26267
|
transportModelId: input.model || input.thinkingOptionId ? encodeExternalTransportSelection(targetHarnessId, {
|
|
25980
26268
|
...input.model ? { model: input.model } : {},
|
|
@@ -26045,17 +26333,21 @@ var HarnessDelegationCoordinator = class {
|
|
|
26045
26333
|
}
|
|
26046
26334
|
await this.#repository.setDelegationStatus(delegationId, "running");
|
|
26047
26335
|
await this.#notifyThreadStarted(thread.thread);
|
|
26048
|
-
return
|
|
26049
|
-
|
|
26050
|
-
|
|
26051
|
-
|
|
26052
|
-
|
|
26053
|
-
|
|
26054
|
-
|
|
26055
|
-
|
|
26056
|
-
|
|
26057
|
-
|
|
26058
|
-
|
|
26336
|
+
return {
|
|
26337
|
+
...this.#result(delegationId, childThreadId, turnId, targetHarnessId, "running", {
|
|
26338
|
+
requested: {
|
|
26339
|
+
...input.model ? { model: input.model } : {},
|
|
26340
|
+
...input.thinkingOptionId ? { thinkingOptionId: input.thinkingOptionId } : {}
|
|
26341
|
+
},
|
|
26342
|
+
effective: {
|
|
26343
|
+
...thread.stateObserver.state.effectiveModel ? { effectiveModel: thread.stateObserver.state.effectiveModel } : {},
|
|
26344
|
+
...thread.stateObserver.state.resolvedModelLabel ? { resolvedModelLabel: thread.stateObserver.state.resolvedModelLabel } : {},
|
|
26345
|
+
...thread.stateObserver.state.effectiveThinkingOptionId ? { effectiveThinkingOptionId: thread.stateObserver.state.effectiveThinkingOptionId } : {}
|
|
26346
|
+
}
|
|
26347
|
+
}),
|
|
26348
|
+
cwd: record3.cwd,
|
|
26349
|
+
parentThreadId
|
|
26350
|
+
};
|
|
26059
26351
|
} catch (error51) {
|
|
26060
26352
|
if (session) await session.close().catch(() => void 0);
|
|
26061
26353
|
this.#externalRuntime.remove(childThreadId);
|
|
@@ -26284,18 +26576,24 @@ var HarnessDelegationCoordinator = class {
|
|
|
26284
26576
|
}
|
|
26285
26577
|
async #parentMetadata(parentThreadId) {
|
|
26286
26578
|
const record3 = await this.#repository.find(parentThreadId);
|
|
26287
|
-
return { harnessId: record3
|
|
26579
|
+
if (record3) return { harnessId: record3.harnessId, cwd: record3.cwd };
|
|
26580
|
+
const cwd = await this.#officialThreadCwd(parentThreadId).catch(() => void 0);
|
|
26581
|
+
return { harnessId: "codex", ...cwd ? { cwd } : {} };
|
|
26288
26582
|
}
|
|
26289
26583
|
async #existingResult(delegation) {
|
|
26290
26584
|
const record3 = await this.#repository.find(delegation.childHostThreadId);
|
|
26291
26585
|
const turnId = record3?.turnMappings.at(-1)?.hostTurnId ?? "pending";
|
|
26292
|
-
return
|
|
26293
|
-
|
|
26294
|
-
|
|
26295
|
-
|
|
26296
|
-
|
|
26297
|
-
|
|
26298
|
-
|
|
26586
|
+
return {
|
|
26587
|
+
...this.#result(
|
|
26588
|
+
delegation.delegationId,
|
|
26589
|
+
delegation.childHostThreadId,
|
|
26590
|
+
turnId,
|
|
26591
|
+
delegation.targetHarnessId,
|
|
26592
|
+
delegation.status
|
|
26593
|
+
),
|
|
26594
|
+
...record3 ? { cwd: record3.cwd } : {},
|
|
26595
|
+
parentThreadId: delegation.parentHostThreadId
|
|
26596
|
+
};
|
|
26299
26597
|
}
|
|
26300
26598
|
#turnResult(threadId3, turnId, harnessId) {
|
|
26301
26599
|
return {
|
|
@@ -27355,25 +27653,25 @@ function resolveExternalSessionTreeIds(records) {
|
|
|
27355
27653
|
const resolve = (start) => {
|
|
27356
27654
|
const cached2 = resolved.get(start.hostThreadId);
|
|
27357
27655
|
if (cached2) return cached2;
|
|
27358
|
-
const
|
|
27656
|
+
const path25 = [];
|
|
27359
27657
|
const visited = /* @__PURE__ */ new Set();
|
|
27360
27658
|
let current = start;
|
|
27361
27659
|
while (true) {
|
|
27362
27660
|
const known = resolved.get(current.hostThreadId);
|
|
27363
27661
|
if (known) {
|
|
27364
|
-
for (const record3 of
|
|
27662
|
+
for (const record3 of path25) resolved.set(record3.hostThreadId, known);
|
|
27365
27663
|
return known;
|
|
27366
27664
|
}
|
|
27367
27665
|
if (visited.has(current.hostThreadId)) {
|
|
27368
27666
|
throw new Error("External Thread Fork tree contains a cycle");
|
|
27369
27667
|
}
|
|
27370
27668
|
visited.add(current.hostThreadId);
|
|
27371
|
-
|
|
27669
|
+
path25.push(current);
|
|
27372
27670
|
const sourceId = current.forkSource?.hostThreadId;
|
|
27373
27671
|
const source = sourceId ? byId.get(sourceId) : void 0;
|
|
27374
27672
|
if (!source) {
|
|
27375
27673
|
const root = current.hostThreadId;
|
|
27376
|
-
for (const record3 of
|
|
27674
|
+
for (const record3 of path25) resolved.set(record3.hostThreadId, root);
|
|
27377
27675
|
return root;
|
|
27378
27676
|
}
|
|
27379
27677
|
current = source;
|
|
@@ -27914,6 +28212,8 @@ function approvalServerName(harnessId) {
|
|
|
27914
28212
|
return "Oh My Pi";
|
|
27915
28213
|
case "antigravity":
|
|
27916
28214
|
return "Antigravity CLI";
|
|
28215
|
+
case "kiro-cli":
|
|
28216
|
+
return "Kiro CLI";
|
|
27917
28217
|
default:
|
|
27918
28218
|
return harnessId;
|
|
27919
28219
|
}
|
|
@@ -28115,9 +28415,11 @@ var AppServerHost = class {
|
|
|
28115
28415
|
cancelOfficial: (input) => this.#cancelOfficialDelegationThread(input),
|
|
28116
28416
|
startOfficial: (input) => this.#startOfficialDelegation(input),
|
|
28117
28417
|
listOfficial: (input) => this.#listDelegationThreads(input),
|
|
28418
|
+
officialThreadCwd: (threadId3) => this.#readOfficialThreadCwd(threadId3),
|
|
28118
28419
|
activeOfficialParents: () => [...this.#activeOfficialTurns.keys()]
|
|
28119
28420
|
});
|
|
28120
28421
|
const unregisterDelegationApi = options2.onDelegationApi?.({
|
|
28422
|
+
listHarnesses: () => this.#delegationCoordinator.listHarnesses(),
|
|
28121
28423
|
inspect: (input) => this.#delegationCoordinator.inspect(input),
|
|
28122
28424
|
start: (input) => this.#delegationCoordinator.start(input),
|
|
28123
28425
|
send: (input) => this.#delegationCoordinator.send(input),
|
|
@@ -29141,6 +29443,13 @@ var AppServerHost = class {
|
|
|
29141
29443
|
]);
|
|
29142
29444
|
return thread !== null || childDelegation !== null || delegation !== null;
|
|
29143
29445
|
}
|
|
29446
|
+
async #readOfficialThreadCwd(threadId3) {
|
|
29447
|
+
const response = await this.#requestOfficial("thread/read", { threadId: threadId3 });
|
|
29448
|
+
if (isRecord12(response.error)) return void 0;
|
|
29449
|
+
const result = isRecord12(response.result) ? response.result : null;
|
|
29450
|
+
const thread = result && isRecord12(result.thread) ? result.thread : null;
|
|
29451
|
+
return thread && typeof thread.cwd === "string" && thread.cwd.trim() ? thread.cwd : void 0;
|
|
29452
|
+
}
|
|
29144
29453
|
async #inspectOfficialDelegationTarget(input) {
|
|
29145
29454
|
const response = await this.#requestOfficial("model/list", {});
|
|
29146
29455
|
if (isRecord12(response.error)) {
|
|
@@ -29333,6 +29642,7 @@ var AppServerHost = class {
|
|
|
29333
29642
|
harnessId: "codex",
|
|
29334
29643
|
deepLink: `codex://threads/${threadId3}`,
|
|
29335
29644
|
status: pendingTerminal ?? "running",
|
|
29645
|
+
cwd: thread && typeof thread.cwd === "string" ? thread.cwd : input.cwd,
|
|
29336
29646
|
...requestedModel || input.thinkingOptionId ? {
|
|
29337
29647
|
configuration: {
|
|
29338
29648
|
requested: {
|
|
@@ -31523,6 +31833,40 @@ var AppServerHost = class {
|
|
|
31523
31833
|
}
|
|
31524
31834
|
};
|
|
31525
31835
|
|
|
31836
|
+
// packages/host-runtime/src/codex-runtime/account-official-listeners.ts
|
|
31837
|
+
import path12 from "node:path";
|
|
31838
|
+
var AccountOfficialListeners = class {
|
|
31839
|
+
constructor(createListener) {
|
|
31840
|
+
this.createListener = createListener;
|
|
31841
|
+
}
|
|
31842
|
+
createListener;
|
|
31843
|
+
#listeners = /* @__PURE__ */ new Map();
|
|
31844
|
+
#starting = /* @__PURE__ */ new Map();
|
|
31845
|
+
#closed = false;
|
|
31846
|
+
async endpoint(account) {
|
|
31847
|
+
if (this.#closed) throw new Error("Account official listeners are closed");
|
|
31848
|
+
const key = path12.resolve(account.codexHome);
|
|
31849
|
+
const existing = this.#starting.get(key);
|
|
31850
|
+
if (existing) return existing;
|
|
31851
|
+
const listener = this.createListener(account);
|
|
31852
|
+
this.#listeners.set(key, listener);
|
|
31853
|
+
const starting = listener.listen().catch(async (error51) => {
|
|
31854
|
+
await listener.close();
|
|
31855
|
+
this.#listeners.delete(key);
|
|
31856
|
+
this.#starting.delete(key);
|
|
31857
|
+
throw error51;
|
|
31858
|
+
});
|
|
31859
|
+
this.#starting.set(key, starting);
|
|
31860
|
+
return starting;
|
|
31861
|
+
}
|
|
31862
|
+
async close() {
|
|
31863
|
+
this.#closed = true;
|
|
31864
|
+
await Promise.all([...this.#listeners.values()].map((listener) => listener.close()));
|
|
31865
|
+
this.#listeners.clear();
|
|
31866
|
+
this.#starting.clear();
|
|
31867
|
+
}
|
|
31868
|
+
};
|
|
31869
|
+
|
|
31526
31870
|
// packages/host-runtime/src/delegation-control-registry.ts
|
|
31527
31871
|
function only(values, message) {
|
|
31528
31872
|
const value2 = values.length === 1 ? values[0] : void 0;
|
|
@@ -31549,6 +31893,12 @@ var DelegationControlRegistry = class {
|
|
|
31549
31893
|
"Harness inspection requires exactly one active Host Runtime session"
|
|
31550
31894
|
).inspect(input);
|
|
31551
31895
|
}
|
|
31896
|
+
async listHarnesses() {
|
|
31897
|
+
return only(
|
|
31898
|
+
[...this.#registrations],
|
|
31899
|
+
"Harness discovery requires exactly one active Host Runtime session"
|
|
31900
|
+
).listHarnesses();
|
|
31901
|
+
}
|
|
31552
31902
|
async start(input) {
|
|
31553
31903
|
return (await this.#registrationForStart(input)).start(input);
|
|
31554
31904
|
}
|
|
@@ -31591,9 +31941,28 @@ var DelegationControlRegistry = class {
|
|
|
31591
31941
|
);
|
|
31592
31942
|
}
|
|
31593
31943
|
async #registrationForThread(threadId3) {
|
|
31594
|
-
|
|
31595
|
-
|
|
31596
|
-
|
|
31944
|
+
const registrations = [...this.#registrations];
|
|
31945
|
+
const matches = await this.#matching((registration) => registration.ownsThread(threadId3));
|
|
31946
|
+
if (matches.length === 1) return matches[0];
|
|
31947
|
+
if (matches.length > 1) {
|
|
31948
|
+
throw new DelegationControlError(
|
|
31949
|
+
"PARENT_THREAD_AMBIGUOUS",
|
|
31950
|
+
"Thread is not owned by exactly one active Host Runtime session",
|
|
31951
|
+
{ matchingRuntimeCount: matches.length }
|
|
31952
|
+
);
|
|
31953
|
+
}
|
|
31954
|
+
if (registrations.length === 0) {
|
|
31955
|
+
throw new DelegationControlError(
|
|
31956
|
+
"PARENT_THREAD_AMBIGUOUS",
|
|
31957
|
+
"Thread is not owned by exactly one active Host Runtime session",
|
|
31958
|
+
{ matchingRuntimeCount: 0 }
|
|
31959
|
+
);
|
|
31960
|
+
}
|
|
31961
|
+
if (registrations.length === 1) return registrations[0];
|
|
31962
|
+
throw new DelegationControlError(
|
|
31963
|
+
"PARENT_THREAD_AMBIGUOUS",
|
|
31964
|
+
"Thread is not owned by exactly one active Host Runtime session",
|
|
31965
|
+
{ matchingRuntimeCount: 0 }
|
|
31597
31966
|
);
|
|
31598
31967
|
}
|
|
31599
31968
|
#compareThreads(left, right, sort) {
|
|
@@ -31612,17 +31981,17 @@ var DelegationControlRegistry = class {
|
|
|
31612
31981
|
|
|
31613
31982
|
// packages/host-runtime/src/installed-harness-plugins.ts
|
|
31614
31983
|
import os3 from "node:os";
|
|
31615
|
-
import
|
|
31984
|
+
import path14 from "node:path";
|
|
31616
31985
|
import { fileURLToPath } from "node:url";
|
|
31617
31986
|
|
|
31618
31987
|
// packages/host-runtime/src/launcher-url-opener.ts
|
|
31619
31988
|
import { spawn as spawn3 } from "node:child_process";
|
|
31620
|
-
import
|
|
31989
|
+
import path13 from "node:path";
|
|
31621
31990
|
var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["127.0.0.1", "localhost", "[::1]"]);
|
|
31622
31991
|
var OPEN_TIMEOUT_MS = 1e4;
|
|
31623
31992
|
function createLauncherUrlOpener(environment, spawnLauncher = (command, arguments_2, options2) => spawn3(command, arguments_2, options2)) {
|
|
31624
31993
|
const launcher = environment.CODEXHOST_LAUNCHER_EXECUTABLE;
|
|
31625
|
-
if (!launcher || !
|
|
31994
|
+
if (!launcher || !path13.isAbsolute(launcher)) return void 0;
|
|
31626
31995
|
const launcherEnvironment = Object.fromEntries(
|
|
31627
31996
|
Object.entries(environment).filter(([name]) => {
|
|
31628
31997
|
const normalized = name.toUpperCase();
|
|
@@ -31680,9 +32049,9 @@ function installedHarnessPluginOptions(environment, managedRemoteHost = false, h
|
|
|
31680
32049
|
const opener = managedRemoteHost ? void 0 : createLauncherUrlOpener(environment);
|
|
31681
32050
|
return {
|
|
31682
32051
|
pluginRoots: [
|
|
31683
|
-
|
|
31684
|
-
environment[HARNESS_PLUGIN_DIRECTORY_ENV] ??
|
|
31685
|
-
environment.CODEXHOST_DATA_DIR ?
|
|
32052
|
+
path14.join(path14.dirname(fileURLToPath(hostRuntimeUrl)), "plugins"),
|
|
32053
|
+
environment[HARNESS_PLUGIN_DIRECTORY_ENV] ?? path14.join(
|
|
32054
|
+
environment.CODEXHOST_DATA_DIR ? path14.resolve(environment.CODEXHOST_DATA_DIR) : path14.join(os3.homedir(), ".codexhost"),
|
|
31686
32055
|
"plugins"
|
|
31687
32056
|
)
|
|
31688
32057
|
],
|
|
@@ -31761,6 +32130,9 @@ async function startDelegationControlServer(input) {
|
|
|
31761
32130
|
}
|
|
31762
32131
|
const body = await jsonBody(request);
|
|
31763
32132
|
switch (request.url) {
|
|
32133
|
+
case "/v1/harness/list":
|
|
32134
|
+
writeJson2(response, 200, await input.api.listHarnesses());
|
|
32135
|
+
return;
|
|
31764
32136
|
case "/v1/harness/inspect":
|
|
31765
32137
|
writeJson2(response, 200, await input.api.inspect(body));
|
|
31766
32138
|
return;
|
|
@@ -31807,10 +32179,13 @@ async function startDelegationControlServer(input) {
|
|
|
31807
32179
|
import { createHash as createHash6, randomUUID as randomUUID9 } from "node:crypto";
|
|
31808
32180
|
import { mkdir as mkdir7, open as open5, readFile as readFile7, rename as rename5, rm as rm5, stat as stat3 } from "node:fs/promises";
|
|
31809
32181
|
import os4 from "node:os";
|
|
31810
|
-
import
|
|
31811
|
-
var SKILL_VERSION =
|
|
31812
|
-
var SKILL_RELATIVE_PATH =
|
|
32182
|
+
import path15 from "node:path";
|
|
32183
|
+
var SKILL_VERSION = 7;
|
|
32184
|
+
var SKILL_RELATIVE_PATH = path15.join("skills", "codexhost-delegation", "SKILL.md");
|
|
31813
32185
|
var PREVIOUS_MANAGED_DIGESTS = [
|
|
32186
|
+
"9d2f491850fb0b4084a31ba9b5e4a550b5e833747af322090d8ed0ff80b88c30",
|
|
32187
|
+
"2bb0aebb9b06febbc6c0c0bcdb0b32506c7cdbf8dc3b734cc6b2a86621270e4e",
|
|
32188
|
+
"aff258622dc8ff321f32b15620d081e578cb9c9ed1134d6a57f35ca8e7762c0a",
|
|
31814
32189
|
"ba509f57e5448e796b3dfdd5031dcb08672eded50b61c0a54de84cfa02c49dd3",
|
|
31815
32190
|
"d3ddf6db9bc5c5df825479c885bbbf0ca08da66f7057a12e02e1fdf57525149e",
|
|
31816
32191
|
"15eb63519ff867e1536c97188a0c43738d7a49d38d4d6adeb7a1036726e7246d"
|
|
@@ -31819,12 +32194,12 @@ var CODEXHOST_DELEGATION_SKILL = `---
|
|
|
31819
32194
|
name: codexhost-delegation
|
|
31820
32195
|
version: ${SKILL_VERSION}
|
|
31821
32196
|
description: >
|
|
31822
|
-
Delegate
|
|
31823
|
-
|
|
31824
|
-
|
|
31825
|
-
|
|
31826
|
-
|
|
31827
|
-
|
|
32197
|
+
Delegate tasks to other coding agents, or read and follow up on existing
|
|
32198
|
+
external agent sessions. Use when the user asks another agent (including
|
|
32199
|
+
@agent) to independently perform a task, or asks to view a specified external
|
|
32200
|
+
session's content, progress, or results, send follow-up messages, wait, or
|
|
32201
|
+
cancel a task. Not for recapping the current conversation, discussing or
|
|
32202
|
+
configuring agents, or role-playing.
|
|
31828
32203
|
---
|
|
31829
32204
|
|
|
31830
32205
|
# Execute the task
|
|
@@ -31833,25 +32208,22 @@ Before acting, run:
|
|
|
31833
32208
|
|
|
31834
32209
|
\`codexhost delegate --help\`
|
|
31835
32210
|
|
|
31836
|
-
|
|
31837
|
-
|
|
31838
|
-
|
|
31839
|
-
|
|
31840
|
-
- available target Harness IDs;
|
|
31841
|
-
- Thread identifier formats;
|
|
31842
|
-
- waiting and reading behavior;
|
|
31843
|
-
- response fields;
|
|
31844
|
-
- errors and recovery guidance.
|
|
32211
|
+
Use CLI help as the authoritative source for commands and behavior. Consult
|
|
32212
|
+
command-specific help for options and the Harness listing command when the
|
|
32213
|
+
target is unknown. Prefer compact output when supported, and use its task links
|
|
32214
|
+
directly for subsequent commands.
|
|
31845
32215
|
|
|
31846
|
-
|
|
32216
|
+
Use the Harness native defaults. Inspect the target when a Model or Thinking
|
|
32217
|
+
selection is needed or the default is unavailable.
|
|
31847
32218
|
|
|
31848
|
-
|
|
31849
|
-
|
|
31850
|
-
|
|
32219
|
+
For a new delegation, create an independent child session and submit the
|
|
32220
|
+
requested task. For an existing external session, resolve the target from the
|
|
32221
|
+
user-provided session link, identifier, or context and operate on that Thread
|
|
32222
|
+
directly; it need not have been created by the current assistant. If the target
|
|
32223
|
+
is ambiguous, ask the user to identify it. Keep requests to view or summarize a
|
|
32224
|
+
session read-only.
|
|
31851
32225
|
|
|
31852
|
-
|
|
31853
|
-
|
|
31854
|
-
After starting the task, choose the appropriate next action based on the
|
|
32226
|
+
For a new or existing task, choose the appropriate next action based on the
|
|
31855
32227
|
user’s request and the task:
|
|
31856
32228
|
|
|
31857
32229
|
- send a follow-up message to the same Thread;
|
|
@@ -31861,17 +32233,8 @@ user’s request and the task:
|
|
|
31861
32233
|
- check it again later;
|
|
31862
32234
|
- leave it running in the background.
|
|
31863
32235
|
|
|
31864
|
-
|
|
31865
|
-
|
|
31866
|
-
|
|
31867
|
-
Provide the user with the necessary tracking information, including:
|
|
31868
|
-
|
|
31869
|
-
- target agent;
|
|
31870
|
-
- \`delegationId\`;
|
|
31871
|
-
- \`threadId\`;
|
|
31872
|
-
- \`turnId\`;
|
|
31873
|
-
- \`deepLink\`;
|
|
31874
|
-
- current or final status.
|
|
32236
|
+
Report the result returned by read or a completed wait, together with the target
|
|
32237
|
+
agent, status, and a labeled task link. Keep internal tracking IDs in tool calls.
|
|
31875
32238
|
`;
|
|
31876
32239
|
var CURRENT_DIGEST = createHash6("sha256").update(CODEXHOST_DELEGATION_SKILL).digest("hex");
|
|
31877
32240
|
function digest(value2) {
|
|
@@ -31890,8 +32253,8 @@ async function readOptional(filePath) {
|
|
|
31890
32253
|
}
|
|
31891
32254
|
}
|
|
31892
32255
|
async function atomicWrite(filePath, content) {
|
|
31893
|
-
await mkdir7(
|
|
31894
|
-
const temporaryPath =
|
|
32256
|
+
await mkdir7(path15.dirname(filePath), { recursive: true, mode: 448 });
|
|
32257
|
+
const temporaryPath = path15.join(path15.dirname(filePath), `.SKILL.md.${randomUUID9()}.tmp`);
|
|
31895
32258
|
const handle = await open5(temporaryPath, "wx", 384);
|
|
31896
32259
|
try {
|
|
31897
32260
|
await handle.writeFile(content, "utf8");
|
|
@@ -31908,8 +32271,8 @@ async function atomicWrite(filePath, content) {
|
|
|
31908
32271
|
async function installDelegationSkills(input = {}) {
|
|
31909
32272
|
const home = input.homeDirectory ?? os4.homedir();
|
|
31910
32273
|
const destinations = [
|
|
31911
|
-
|
|
31912
|
-
|
|
32274
|
+
path15.join(home, ".agents", SKILL_RELATIVE_PATH),
|
|
32275
|
+
path15.join(home, ".claude", SKILL_RELATIVE_PATH)
|
|
31913
32276
|
];
|
|
31914
32277
|
const knownDigests = /* @__PURE__ */ new Set([
|
|
31915
32278
|
CURRENT_DIGEST,
|
|
@@ -31976,7 +32339,7 @@ async function installDelegationSkills(input = {}) {
|
|
|
31976
32339
|
// packages/host-runtime/src/remote-control-app-server.ts
|
|
31977
32340
|
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
31978
32341
|
import { mkdir as mkdir8, open as open6, rename as rename6, rm as rm6 } from "node:fs/promises";
|
|
31979
|
-
import
|
|
32342
|
+
import path16 from "node:path";
|
|
31980
32343
|
|
|
31981
32344
|
// packages/host-runtime/src/remote-official-connection.ts
|
|
31982
32345
|
import net from "node:net";
|
|
@@ -32166,8 +32529,8 @@ var BRIDGE_READY_METHOD = "codexhost/remote-control-bridge/ready";
|
|
|
32166
32529
|
function absoluteEnvironmentPath2(environment, name, fallback, platform = process.platform) {
|
|
32167
32530
|
const value2 = environment[name] ?? fallback;
|
|
32168
32531
|
if (!value2) return null;
|
|
32169
|
-
if (
|
|
32170
|
-
return platform === "win32" &&
|
|
32532
|
+
if (path16.isAbsolute(value2)) return path16.normalize(value2);
|
|
32533
|
+
return platform === "win32" && path16.win32.isAbsolute(value2) ? path16.win32.normalize(value2) : null;
|
|
32171
32534
|
}
|
|
32172
32535
|
function nodeCompatibleWindowsPath(value2) {
|
|
32173
32536
|
if (value2.startsWith("\\\\?\\UNC\\")) return `\\\\${value2.slice(8)}`;
|
|
@@ -32181,13 +32544,13 @@ function remoteControlBridgePipePath(processId = process.pid, instanceId = rando
|
|
|
32181
32544
|
}
|
|
32182
32545
|
function remoteControlBridgeDescriptorPath(environment) {
|
|
32183
32546
|
const root = environment.LOCALAPPDATA;
|
|
32184
|
-
if (!root || !
|
|
32185
|
-
return
|
|
32547
|
+
if (!root || !path16.isAbsolute(root)) return null;
|
|
32548
|
+
return path16.join(path16.normalize(root), "codexhost", REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE);
|
|
32186
32549
|
}
|
|
32187
32550
|
async function publishRemoteControlAppServerDescriptor(plan) {
|
|
32188
|
-
const directory =
|
|
32551
|
+
const directory = path16.dirname(plan.descriptorPath);
|
|
32189
32552
|
await mkdir8(directory, { recursive: true, mode: 448 });
|
|
32190
|
-
const temporaryPath =
|
|
32553
|
+
const temporaryPath = path16.join(
|
|
32191
32554
|
directory,
|
|
32192
32555
|
`.${REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE}.${plan.descriptor.ownerPid}.${randomUUID10()}.tmp`
|
|
32193
32556
|
);
|
|
@@ -32280,14 +32643,14 @@ async function runRemoteControlAppServerBridge(input = {}) {
|
|
|
32280
32643
|
import { createServer as createServer2 } from "node:http";
|
|
32281
32644
|
import net2 from "node:net";
|
|
32282
32645
|
import { chmod as chmod3, lstat as lstat6, mkdir as mkdir10, rm as rm8 } from "node:fs/promises";
|
|
32283
|
-
import
|
|
32646
|
+
import path18 from "node:path";
|
|
32284
32647
|
import { PassThrough as PassThrough2 } from "node:stream";
|
|
32285
32648
|
|
|
32286
32649
|
// packages/host-runtime/src/remote-socket-lock.ts
|
|
32287
32650
|
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
32288
32651
|
import { chmod as chmod2, lstat as lstat5, mkdir as mkdir9, open as open7, readFile as readFile8, readdir as readdir4, rename as rename7, rm as rm7 } from "node:fs/promises";
|
|
32289
32652
|
import { uptime } from "node:os";
|
|
32290
|
-
import
|
|
32653
|
+
import path17 from "node:path";
|
|
32291
32654
|
import { setTimeout as delay4 } from "node:timers/promises";
|
|
32292
32655
|
var LOCK_RETRY_COUNT = 200;
|
|
32293
32656
|
var LOCK_RETRY_DELAY_MS = 25;
|
|
@@ -32361,7 +32724,7 @@ async function readLockEntrySnapshot(filePath) {
|
|
|
32361
32724
|
source,
|
|
32362
32725
|
identity: { dev: metadata.dev, ino: metadata.ino },
|
|
32363
32726
|
mtimeMs: metadata.mtimeMs,
|
|
32364
|
-
record: record3 &&
|
|
32727
|
+
record: record3 && path17.basename(filePath) === lockEntryName(record3.ownerToken) ? record3 : null
|
|
32365
32728
|
};
|
|
32366
32729
|
}
|
|
32367
32730
|
function lockEntryIsAbandoned(snapshot) {
|
|
@@ -32382,7 +32745,7 @@ async function readLockEntryCatalog(lockDirectory) {
|
|
|
32382
32745
|
let unsettled = false;
|
|
32383
32746
|
for (const name of names) {
|
|
32384
32747
|
if (!name.startsWith(LOCK_ENTRY_PREFIX) || !name.endsWith(LOCK_ENTRY_SUFFIX)) continue;
|
|
32385
|
-
const snapshot = await readLockEntrySnapshot(
|
|
32748
|
+
const snapshot = await readLockEntrySnapshot(path17.join(lockDirectory, name));
|
|
32386
32749
|
if (snapshot === null) continue;
|
|
32387
32750
|
if (lockEntryIsAbandoned(snapshot)) {
|
|
32388
32751
|
if (!await removeAbandonedLockEntry(snapshot)) unsettled = true;
|
|
@@ -32410,7 +32773,7 @@ async function preparePrivateLockDirectory(lockDirectory) {
|
|
|
32410
32773
|
await chmod2(lockDirectory, 448);
|
|
32411
32774
|
}
|
|
32412
32775
|
async function writeLockRecordAtomic(lockDirectory, entryPath, record3) {
|
|
32413
|
-
const temporary =
|
|
32776
|
+
const temporary = path17.join(lockDirectory, `.tmp-${record3.ownerToken}-${randomUUID11()}`);
|
|
32414
32777
|
const handle = await open7(temporary, "wx", 384);
|
|
32415
32778
|
try {
|
|
32416
32779
|
await handle.writeFile(`${JSON.stringify(record3)}
|
|
@@ -32486,7 +32849,7 @@ async function withRemoteAppServerSocketInitializationLock(socketPath, action) {
|
|
|
32486
32849
|
const lockDirectory = `${socketPath}.initializers`;
|
|
32487
32850
|
await preparePrivateLockDirectory(lockDirectory);
|
|
32488
32851
|
const ownerToken = randomUUID11();
|
|
32489
|
-
const entryPath =
|
|
32852
|
+
const entryPath = path17.join(lockDirectory, lockEntryName(ownerToken));
|
|
32490
32853
|
const baseRecord = {
|
|
32491
32854
|
version: 2,
|
|
32492
32855
|
ownerToken,
|
|
@@ -32660,14 +33023,14 @@ function remoteAppServerSocketPath(environment, listenUrl = "unix://") {
|
|
|
32660
33023
|
throw new Error("Remote app-server listener must use a Unix URL");
|
|
32661
33024
|
}
|
|
32662
33025
|
const explicit = listenUrl.slice("unix://".length);
|
|
32663
|
-
if (explicit.length > 0) return
|
|
32664
|
-
const codexHome = environment.CODEX_HOME ?? (environment.HOME ?
|
|
33026
|
+
if (explicit.length > 0) return path18.posix.resolve(decodeURIComponent(explicit));
|
|
33027
|
+
const codexHome = environment.CODEX_HOME ?? (environment.HOME ? path18.posix.join(environment.HOME, ".codex") : void 0);
|
|
32665
33028
|
if (!codexHome)
|
|
32666
33029
|
throw new Error("CODEX_HOME or HOME is required for the remote app-server socket");
|
|
32667
|
-
return
|
|
33030
|
+
return path18.posix.join(codexHome, "app-server-control", "app-server-control.sock");
|
|
32668
33031
|
}
|
|
32669
33032
|
function officialListenerArgumentsForRemoteListener(arguments_2, socketPath) {
|
|
32670
|
-
if (!
|
|
33033
|
+
if (!path18.posix.isAbsolute(socketPath)) {
|
|
32671
33034
|
throw new Error("Shared official app-server socket path must be absolute");
|
|
32672
33035
|
}
|
|
32673
33036
|
if (remoteUnixListenerUrl(arguments_2) === null) {
|
|
@@ -32778,7 +33141,7 @@ async function removeStaleSocket(socketPath) {
|
|
|
32778
33141
|
await rm8(socketPath, { force: true });
|
|
32779
33142
|
}
|
|
32780
33143
|
async function prepareRemoteAppServerSocketDirectory(socketPath) {
|
|
32781
|
-
const socketDirectory =
|
|
33144
|
+
const socketDirectory = path18.dirname(socketPath);
|
|
32782
33145
|
const existing = await lstat6(socketDirectory).catch((error51) => {
|
|
32783
33146
|
if (error51.code === "ENOENT") return null;
|
|
32784
33147
|
throw error51;
|
|
@@ -32985,18 +33348,18 @@ function createRemoteAppServerWebSocketListener(input) {
|
|
|
32985
33348
|
import { spawn as spawn4 } from "node:child_process";
|
|
32986
33349
|
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
32987
33350
|
import { lstat as lstat7, rm as rm9 } from "node:fs/promises";
|
|
32988
|
-
import
|
|
33351
|
+
import path19 from "node:path";
|
|
32989
33352
|
var DEFAULT_CLOSE_TIMEOUT_MS = 2e3;
|
|
32990
33353
|
var DEFAULT_LISTEN_TIMEOUT_MS = 1e4;
|
|
32991
33354
|
function remoteOfficialAppServerSocketPath(desktopControlSocketPath, token = randomUUID12()) {
|
|
32992
|
-
if (!
|
|
33355
|
+
if (!path19.posix.isAbsolute(desktopControlSocketPath)) {
|
|
32993
33356
|
throw new Error("Desktop control socket path must be absolute");
|
|
32994
33357
|
}
|
|
32995
33358
|
if (!/^[A-Za-z0-9-]+$/u.test(token) || !/[A-Za-z0-9]/u.test(token)) {
|
|
32996
33359
|
throw new Error("Shared official app-server socket token is invalid");
|
|
32997
33360
|
}
|
|
32998
33361
|
const compactToken = token.replaceAll("-", "").slice(0, 15);
|
|
32999
|
-
return
|
|
33362
|
+
return path19.posix.join(path19.posix.dirname(desktopControlSocketPath), `.c-${compactToken}.sock`);
|
|
33000
33363
|
}
|
|
33001
33364
|
function errorMessage5(error51) {
|
|
33002
33365
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
@@ -33463,9 +33826,9 @@ function hasLauncherManagedUpdateRuntime(environment, hostRuntimePath) {
|
|
|
33463
33826
|
if (!environment[UPDATE_RUNTIME_ENV.launcherPid]) return false;
|
|
33464
33827
|
const npmPackageRoot = environment[UPDATE_RUNTIME_ENV.npmPackageRoot];
|
|
33465
33828
|
if (!npmPackageRoot || !hostRuntimePath) return true;
|
|
33466
|
-
if (!
|
|
33467
|
-
const runtimePackageRoot =
|
|
33468
|
-
return
|
|
33829
|
+
if (!path20.isAbsolute(npmPackageRoot) || !path20.isAbsolute(hostRuntimePath)) return false;
|
|
33830
|
+
const runtimePackageRoot = path20.dirname(path20.dirname(path20.normalize(hostRuntimePath)));
|
|
33831
|
+
return path20.relative(path20.normalize(npmPackageRoot), runtimePackageRoot) === "";
|
|
33469
33832
|
}
|
|
33470
33833
|
function requiredRuntimeConfiguration(environment) {
|
|
33471
33834
|
const stockCodexPath = environment[STOCK_CODEX_PATH_ENV];
|
|
@@ -33546,19 +33909,15 @@ async function runHostRuntime(input) {
|
|
|
33546
33909
|
const officialPlan = createRemoteControlOfficialAppServerPlan(
|
|
33547
33910
|
remoteControlPlan.officialArguments
|
|
33548
33911
|
);
|
|
33549
|
-
const
|
|
33550
|
-
|
|
33551
|
-
|
|
33552
|
-
|
|
33553
|
-
|
|
33554
|
-
|
|
33555
|
-
|
|
33556
|
-
|
|
33557
|
-
|
|
33558
|
-
throw new Error("Shared official app-server endpoint is unavailable");
|
|
33559
|
-
}
|
|
33560
|
-
return createRemoteOfficialAppServerConnection(officialEndpoint);
|
|
33561
|
-
};
|
|
33912
|
+
const officialListeners = new AccountOfficialListeners(
|
|
33913
|
+
(account) => createLoopbackOfficialAppServerListener({
|
|
33914
|
+
stockCodexPath,
|
|
33915
|
+
arguments: officialPlan.listenerArguments,
|
|
33916
|
+
environment: officialAccountEnvironment(delegationEnvironment, account),
|
|
33917
|
+
diagnosticOutput: process.stderr
|
|
33918
|
+
})
|
|
33919
|
+
);
|
|
33920
|
+
const createOfficialConnection = async (account) => createRemoteOfficialAppServerConnection(await officialListeners.endpoint(account));
|
|
33562
33921
|
const mappingStore = createProductionExternalThreadStore(delegationEnvironment);
|
|
33563
33922
|
await mappingStore.initialize();
|
|
33564
33923
|
const host = new AppServerHost({
|
|
@@ -33595,7 +33954,11 @@ async function runHostRuntime(input) {
|
|
|
33595
33954
|
}
|
|
33596
33955
|
});
|
|
33597
33956
|
try {
|
|
33598
|
-
|
|
33957
|
+
await officialListeners.endpoint({
|
|
33958
|
+
codexHome: path20.resolve(
|
|
33959
|
+
delegationEnvironment.CODEX_HOME ?? path20.join(homedir(), ".codex")
|
|
33960
|
+
)
|
|
33961
|
+
});
|
|
33599
33962
|
await listener.listen();
|
|
33600
33963
|
await publishRemoteControlAppServerDescriptor(remoteControlPlan);
|
|
33601
33964
|
return await host.run();
|
|
@@ -33604,7 +33967,7 @@ async function runHostRuntime(input) {
|
|
|
33604
33967
|
await listener.close();
|
|
33605
33968
|
} finally {
|
|
33606
33969
|
try {
|
|
33607
|
-
await
|
|
33970
|
+
await officialListeners.close();
|
|
33608
33971
|
} finally {
|
|
33609
33972
|
await mappingStore.close();
|
|
33610
33973
|
}
|
|
@@ -33709,7 +34072,7 @@ import {
|
|
|
33709
34072
|
stat as stat4,
|
|
33710
34073
|
writeFile as writeFile5
|
|
33711
34074
|
} from "node:fs/promises";
|
|
33712
|
-
import
|
|
34075
|
+
import path21 from "node:path";
|
|
33713
34076
|
var MANIFEST_FORMAT = 1;
|
|
33714
34077
|
var WRAPPER_MARKER = "# codexhost remote SSH wrapper v1";
|
|
33715
34078
|
var PROFILE_START = "# >>> codexhost remote SSH >>>";
|
|
@@ -33720,25 +34083,25 @@ function resolvePaths(options2) {
|
|
|
33720
34083
|
if (!configuredHome) {
|
|
33721
34084
|
throw new Error("A non-root HOME is required for remote Host installation");
|
|
33722
34085
|
}
|
|
33723
|
-
const home =
|
|
33724
|
-
if (!home || home ===
|
|
34086
|
+
const home = path21.resolve(configuredHome);
|
|
34087
|
+
if (!home || home === path21.parse(home).root) {
|
|
33725
34088
|
throw new Error("A non-root HOME is required for remote Host installation");
|
|
33726
34089
|
}
|
|
33727
|
-
const installRoot =
|
|
33728
|
-
const profilePath =
|
|
33729
|
-
options2.profilePath ??
|
|
34090
|
+
const installRoot = path21.resolve(options2.installRoot ?? path21.join(home, ".codexhost", "remote"));
|
|
34091
|
+
const profilePath = path21.resolve(
|
|
34092
|
+
options2.profilePath ?? path21.join(
|
|
33730
34093
|
home,
|
|
33731
|
-
|
|
34094
|
+
path21.basename(environment.SHELL ?? "") === "zsh" ? ".zshenv" : path21.basename(environment.SHELL ?? "") === "bash" ? ".bashrc" : ".profile"
|
|
33732
34095
|
)
|
|
33733
34096
|
);
|
|
33734
|
-
const binDirectory =
|
|
34097
|
+
const binDirectory = path21.join(installRoot, "bin");
|
|
33735
34098
|
return {
|
|
33736
34099
|
home,
|
|
33737
34100
|
installRoot,
|
|
33738
34101
|
binDirectory,
|
|
33739
|
-
wrapperPath:
|
|
33740
|
-
manifestPath:
|
|
33741
|
-
dataDirectory:
|
|
34102
|
+
wrapperPath: path21.join(binDirectory, "codex"),
|
|
34103
|
+
manifestPath: path21.join(installRoot, "manifest.json"),
|
|
34104
|
+
dataDirectory: path21.join(installRoot, "data"),
|
|
33742
34105
|
profilePath
|
|
33743
34106
|
};
|
|
33744
34107
|
}
|
|
@@ -33757,7 +34120,7 @@ async function fileSha256(filePath) {
|
|
|
33757
34120
|
return createHash7("sha256").update(await readFile9(filePath)).digest("hex");
|
|
33758
34121
|
}
|
|
33759
34122
|
async function executable(filePath, label) {
|
|
33760
|
-
const absolute =
|
|
34123
|
+
const absolute = path21.resolve(filePath);
|
|
33761
34124
|
try {
|
|
33762
34125
|
if (!(await stat4(absolute)).isFile()) throw new Error("not a regular file");
|
|
33763
34126
|
await access(absolute, fsConstants.X_OK);
|
|
@@ -33767,7 +34130,7 @@ async function executable(filePath, label) {
|
|
|
33767
34130
|
return absolute;
|
|
33768
34131
|
}
|
|
33769
34132
|
async function existingFile(filePath, label) {
|
|
33770
|
-
const absolute =
|
|
34133
|
+
const absolute = path21.resolve(filePath);
|
|
33771
34134
|
try {
|
|
33772
34135
|
const metadata = await stat4(absolute);
|
|
33773
34136
|
if (!metadata.isFile()) throw new Error("not a regular file");
|
|
@@ -33777,9 +34140,9 @@ async function existingFile(filePath, label) {
|
|
|
33777
34140
|
return absolute;
|
|
33778
34141
|
}
|
|
33779
34142
|
async function discoverExecutable(name, environment) {
|
|
33780
|
-
for (const directory of (environment.PATH ?? "").split(
|
|
34143
|
+
for (const directory of (environment.PATH ?? "").split(path21.delimiter)) {
|
|
33781
34144
|
if (!directory) continue;
|
|
33782
|
-
const candidate =
|
|
34145
|
+
const candidate = path21.resolve(directory, name);
|
|
33783
34146
|
try {
|
|
33784
34147
|
await access(candidate, fsConstants.X_OK);
|
|
33785
34148
|
return candidate;
|
|
@@ -33790,10 +34153,10 @@ async function discoverExecutable(name, environment) {
|
|
|
33790
34153
|
return null;
|
|
33791
34154
|
}
|
|
33792
34155
|
async function writeAtomic(filePath, contents, mode) {
|
|
33793
|
-
await mkdir11(
|
|
33794
|
-
const temporary =
|
|
33795
|
-
|
|
33796
|
-
`.${
|
|
34156
|
+
await mkdir11(path21.dirname(filePath), { recursive: true, mode: 448 });
|
|
34157
|
+
const temporary = path21.join(
|
|
34158
|
+
path21.dirname(filePath),
|
|
34159
|
+
`.${path21.basename(filePath)}.${process.pid}.${randomUUID13()}.tmp`
|
|
33797
34160
|
);
|
|
33798
34161
|
try {
|
|
33799
34162
|
if (typeof contents === "string") {
|
|
@@ -33814,10 +34177,10 @@ async function writeAtomic(filePath, contents, mode) {
|
|
|
33814
34177
|
}
|
|
33815
34178
|
}
|
|
33816
34179
|
async function writeAtomicExecutable(filePath, sourcePath) {
|
|
33817
|
-
await mkdir11(
|
|
33818
|
-
const temporary =
|
|
33819
|
-
|
|
33820
|
-
`.${
|
|
34180
|
+
await mkdir11(path21.dirname(filePath), { recursive: true, mode: 448 });
|
|
34181
|
+
const temporary = path21.join(
|
|
34182
|
+
path21.dirname(filePath),
|
|
34183
|
+
`.${path21.basename(filePath)}.${process.pid}.${randomUUID13()}.tmp`
|
|
33821
34184
|
);
|
|
33822
34185
|
try {
|
|
33823
34186
|
await copyFile3(sourcePath, temporary);
|
|
@@ -33858,8 +34221,8 @@ function removeManagedProfileBlock(contents) {
|
|
|
33858
34221
|
function installManagedProfileBlock(contents, manifest) {
|
|
33859
34222
|
const base = removeManagedProfileBlock(contents);
|
|
33860
34223
|
const environment = [
|
|
33861
|
-
`export CODEX_INSTALL_DIR=${shellQuote(
|
|
33862
|
-
`export PATH=${shellQuote(
|
|
34224
|
+
`export CODEX_INSTALL_DIR=${shellQuote(path21.dirname(manifest.wrapperPath))}`,
|
|
34225
|
+
`export PATH=${shellQuote(path21.dirname(manifest.wrapperPath))}:${shellQuote(path21.dirname(manifest.nodePath))}:${shellQuote(path21.dirname(manifest.stockCodexPath))}:"\${PATH:-/usr/local/bin:/usr/bin:/bin}"`,
|
|
33863
34226
|
`export CODEXHOST_STOCK_CODEX_PATH=${shellQuote(manifest.stockCodexPath)}`,
|
|
33864
34227
|
`export CODEXHOST_HOST_NODE_PATH=${shellQuote(manifest.nodePath)}`,
|
|
33865
34228
|
`export CODEXHOST_HOST_RUNTIME_PATH=${shellQuote(manifest.hostRuntimePath)}`,
|
|
@@ -33876,7 +34239,7 @@ function installManagedProfileBlock(contents, manifest) {
|
|
|
33876
34239
|
PROFILE_END,
|
|
33877
34240
|
""
|
|
33878
34241
|
].join("\n");
|
|
33879
|
-
if (
|
|
34242
|
+
if (path21.basename(manifest.profilePath) === ".bashrc") return `${block}${base}`;
|
|
33880
34243
|
const separator = base.length > 0 && !base.endsWith("\n") ? "\n" : "";
|
|
33881
34244
|
return `${base}${separator}${block}`;
|
|
33882
34245
|
}
|
|
@@ -33941,9 +34304,9 @@ async function readManifest(filePath) {
|
|
|
33941
34304
|
];
|
|
33942
34305
|
const optionalPaths = ["claudeCommand", "profileBackupPath"];
|
|
33943
34306
|
if (manifest.format !== MANIFEST_FORMAT || Object.keys(manifest).some((key) => !allowed.has(key)) || requiredPaths.some(
|
|
33944
|
-
(key) => typeof manifest[key] !== "string" || !
|
|
34307
|
+
(key) => typeof manifest[key] !== "string" || !path21.isAbsolute(manifest[key])
|
|
33945
34308
|
) || optionalPaths.some(
|
|
33946
|
-
(key) => manifest[key] !== void 0 && (typeof manifest[key] !== "string" || !
|
|
34309
|
+
(key) => manifest[key] !== void 0 && (typeof manifest[key] !== "string" || !path21.isAbsolute(manifest[key]))
|
|
33947
34310
|
) || manifest.entrypointSha256 !== void 0 && (typeof manifest.entrypointSha256 !== "string" || !/^[a-f0-9]{64}$/u.test(manifest.entrypointSha256))) {
|
|
33948
34311
|
throw new Error("Remote Host manifest has an unsupported format");
|
|
33949
34312
|
}
|
|
@@ -34172,7 +34535,7 @@ async function uninstallRemoteHost(options2) {
|
|
|
34172
34535
|
import { spawn as spawn5 } from "node:child_process";
|
|
34173
34536
|
import { stat as stat5 } from "node:fs/promises";
|
|
34174
34537
|
import net3 from "node:net";
|
|
34175
|
-
import
|
|
34538
|
+
import path22 from "node:path";
|
|
34176
34539
|
import { Duplex } from "node:stream";
|
|
34177
34540
|
var CODEXHOST_STATUS_METHOD = "codexhost/update/status";
|
|
34178
34541
|
var DIRECT_PROBE_TIMEOUT_MS = 5e3;
|
|
@@ -34191,9 +34554,9 @@ function classifyRemoteHostProbeResponse(response, socketPath) {
|
|
|
34191
34554
|
}
|
|
34192
34555
|
var lifecycleDependencyOverrides = {};
|
|
34193
34556
|
function socketPathFor(environment) {
|
|
34194
|
-
const codexHome = environment.CODEX_HOME ?? (environment.HOME ?
|
|
34557
|
+
const codexHome = environment.CODEX_HOME ?? (environment.HOME ? path22.join(environment.HOME, ".codex") : void 0);
|
|
34195
34558
|
if (!codexHome) throw new Error("CODEX_HOME or HOME is required for remote Host lifecycle");
|
|
34196
|
-
return
|
|
34559
|
+
return path22.join(codexHome, "app-server-control", "app-server-control.sock");
|
|
34197
34560
|
}
|
|
34198
34561
|
async function defaultSocketExists(socketPath) {
|
|
34199
34562
|
const metadata = await stat5(socketPath).catch((error51) => {
|
|
@@ -34320,7 +34683,7 @@ function installedManifest(status) {
|
|
|
34320
34683
|
function managedEnvironment(manifest, environment) {
|
|
34321
34684
|
return {
|
|
34322
34685
|
...environment,
|
|
34323
|
-
CODEX_INSTALL_DIR:
|
|
34686
|
+
CODEX_INSTALL_DIR: path22.dirname(manifest.wrapperPath),
|
|
34324
34687
|
CODEXHOST_STOCK_CODEX_PATH: manifest.stockCodexPath,
|
|
34325
34688
|
CODEXHOST_HOST_NODE_PATH: manifest.nodePath,
|
|
34326
34689
|
CODEXHOST_HOST_RUNTIME_PATH: manifest.hostRuntimePath,
|
|
@@ -34328,7 +34691,7 @@ function managedEnvironment(manifest, environment) {
|
|
|
34328
34691
|
CODEXHOST_DEFAULT_AGENT: "codex",
|
|
34329
34692
|
CODEXHOST_REMOTE_SSH_MANAGED: "1",
|
|
34330
34693
|
...manifest.claudeCommand ? { CODEXHOST_CLAUDE_COMMAND: manifest.claudeCommand } : {},
|
|
34331
|
-
PATH: `${
|
|
34694
|
+
PATH: `${path22.dirname(manifest.wrapperPath)}${path22.delimiter}${path22.dirname(manifest.stockCodexPath)}${path22.delimiter}${environment.PATH ?? "/usr/bin:/bin"}`
|
|
34332
34695
|
};
|
|
34333
34696
|
}
|
|
34334
34697
|
async function defaultRunTerminator(manifest, socketPath, role, environment) {
|
|
@@ -34667,19 +35030,19 @@ function consumeBrokerFrames(socket, onFrame, onError) {
|
|
|
34667
35030
|
|
|
34668
35031
|
// packages/harness-broker/dist/paths.js
|
|
34669
35032
|
import os5 from "node:os";
|
|
34670
|
-
import
|
|
35033
|
+
import path23 from "node:path";
|
|
34671
35034
|
var HARNESS_BROKER_DESCRIPTOR_ENV = "CODEXHOST_CLAUDE_BROKER_DESCRIPTOR";
|
|
34672
35035
|
var HARNESS_BROKER_DESCRIPTOR_FILE = "claude-code-broker-v1.json";
|
|
34673
35036
|
var HARNESS_BROKER_SOCKET_FILE = "claude-code-broker-v1.sock";
|
|
34674
35037
|
function defaultHarnessBrokerDirectory(environment = process.env) {
|
|
34675
35038
|
const home = environment.HOME || os5.homedir();
|
|
34676
|
-
return
|
|
35039
|
+
return path23.join(home, ".codexhost", "harness-broker");
|
|
34677
35040
|
}
|
|
34678
35041
|
function defaultHarnessBrokerDescriptorPath(environment = process.env) {
|
|
34679
|
-
return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ??
|
|
35042
|
+
return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ?? path23.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_DESCRIPTOR_FILE);
|
|
34680
35043
|
}
|
|
34681
35044
|
function defaultHarnessBrokerSocketPath(environment = process.env) {
|
|
34682
|
-
return
|
|
35045
|
+
return path23.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_SOCKET_FILE);
|
|
34683
35046
|
}
|
|
34684
35047
|
|
|
34685
35048
|
// packages/harness-broker/dist/validation.js
|
|
@@ -34694,6 +35057,8 @@ var createSchema = external_exports.object({
|
|
|
34694
35057
|
}).strict();
|
|
34695
35058
|
var resumeSchema = external_exports.object({
|
|
34696
35059
|
kind: external_exports.literal("resume"),
|
|
35060
|
+
model: harnessModelRefSchema.optional(),
|
|
35061
|
+
thinkingOptionId: harnessThinkingOptionIdSchema.optional(),
|
|
34697
35062
|
nativeRef: nativeSessionRefSchema,
|
|
34698
35063
|
cwd: cwdSchema,
|
|
34699
35064
|
knownTurnRefs: external_exports.array(nativeTurnRefSchema).max(1e5).optional()
|
|
@@ -34706,6 +35071,9 @@ var forkSchema = external_exports.object({
|
|
|
34706
35071
|
}).strict();
|
|
34707
35072
|
var rollbackSchema = external_exports.object({
|
|
34708
35073
|
kind: external_exports.literal("rollbackLastTurn"),
|
|
35074
|
+
model: harnessModelRefSchema.optional(),
|
|
35075
|
+
thinkingOptionId: harnessThinkingOptionIdSchema.optional(),
|
|
35076
|
+
permissionModeId: harnessPermissionModeIdSchema.optional(),
|
|
34709
35077
|
sourceRef: nativeSessionRefSchema,
|
|
34710
35078
|
cwd: cwdSchema
|
|
34711
35079
|
}).strict();
|
|
@@ -34879,7 +35247,7 @@ var harnessOutputSchema = external_exports.custom((value2) => {
|
|
|
34879
35247
|
import { randomBytes as randomBytes2, randomUUID as randomUUID14 } from "node:crypto";
|
|
34880
35248
|
import { chmod as chmod5, lstat as lstat9, mkdir as mkdir12, open as open8, readFile as readFile10, rename as rename9, rm as rm11 } from "node:fs/promises";
|
|
34881
35249
|
import net4, {} from "node:net";
|
|
34882
|
-
import
|
|
35250
|
+
import path24 from "node:path";
|
|
34883
35251
|
function harnessError(message, retryable = true) {
|
|
34884
35252
|
return { code: "unavailable", message, retryable, stage: "harnessBroker" };
|
|
34885
35253
|
}
|
|
@@ -35004,13 +35372,13 @@ async function startHarnessBrokerServer(input) {
|
|
|
35004
35372
|
if (input.adapter.harnessId !== "claude-code") {
|
|
35005
35373
|
throw new Error("Harness broker accepts only the claude-code adapter");
|
|
35006
35374
|
}
|
|
35007
|
-
if (process.platform !== "win32" &&
|
|
35375
|
+
if (process.platform !== "win32" && path24.dirname(input.descriptorPath) !== path24.dirname(input.socketPath)) {
|
|
35008
35376
|
throw new Error("Harness broker descriptor and socket must share one private directory");
|
|
35009
35377
|
}
|
|
35010
35378
|
if (process.platform === "darwin" && Buffer.byteLength(input.socketPath) > 103) {
|
|
35011
35379
|
throw new Error("Harness broker Unix socket path is too long for macOS");
|
|
35012
35380
|
}
|
|
35013
|
-
await privateDirectory(
|
|
35381
|
+
await privateDirectory(path24.dirname(input.descriptorPath));
|
|
35014
35382
|
await assertNoLiveDescriptor(input.descriptorPath);
|
|
35015
35383
|
if (process.platform !== "win32")
|
|
35016
35384
|
await prepareUnixSocketPath(input.socketPath);
|