@liberseek/boft-cli-win32-arm64 0.6.4 → 0.6.6
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/host-runtime.mjs +508 -242
- package/app/plugins/antigravity/plugin.mjs +9 -7
- package/app/plugins/claude-code/plugin.mjs +664 -229
- package/app/plugins/deepseek-harness/plugin.mjs +7797 -10553
- package/app/plugins/grok/plugin.mjs +48 -24
- package/app/plugins/kiro-cli/plugin.mjs +77 -61
- package/app/plugins/omp/plugin.mjs +6 -0
- package/app/plugins/opencode/plugin.mjs +292 -142
- package/app/plugins/pi/plugin.mjs +1489 -1304
- package/app/renderer-extension.js +812 -449
- package/bin/{codexhost.exe → boft.exe} +0 -0
- package/libexec/{codexhost-node-repl.exe → boft-node-repl.exe} +0 -0
- package/libexec/{codexhost-shim.exe → boft-shim.exe} +0 -0
- package/libexec/{codexhost-updater.exe → boft-updater.exe} +0 -0
- package/package.json +1 -1
package/app/host-runtime.mjs
CHANGED
|
@@ -3709,6 +3709,93 @@ 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": `boft harness list [--format json|compact]
|
|
3715
|
+
List Harnesses available in the active Runtime.`,
|
|
3716
|
+
"harness inspect": `boft 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": `boft 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": `boft 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": `boft 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": `boft 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": `boft 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": `boft 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
|
+
Native Codex shell commands also need the Host-provided CODEXHOST_* environment variables. If shell_environment_policy filters them, prefer inherit = "all" with ignore_default_excludes = true and a narrow include_only containing "CODEXHOST_RUNTIME_ENDPOINT" and "CODEXHOST_RUNTIME_TOKEN" plus the variables required by the platform and invoked tools. Avoid unconstrained inherit = "all", which forwards unrelated ambient variables.`;
|
|
3753
|
+
var DELEGATION_HELP = `usage:
|
|
3754
|
+
boft harness list
|
|
3755
|
+
boft harness inspect <harness>
|
|
3756
|
+
boft delegate start --harness <id> --task <text>
|
|
3757
|
+
boft thread send <thread> --message <text>
|
|
3758
|
+
boft thread cancel <thread>
|
|
3759
|
+
boft thread read <thread>
|
|
3760
|
+
boft thread wait <thread>
|
|
3761
|
+
boft thread list
|
|
3762
|
+
|
|
3763
|
+
Use <command> --help for its options. Use harness list to discover targets.
|
|
3764
|
+
${COMMON_HELP}
|
|
3765
|
+
`;
|
|
3766
|
+
function hasHelpOption(arguments_2) {
|
|
3767
|
+
for (let index = 0; index < arguments_2.length; index += 1) {
|
|
3768
|
+
const argument = arguments_2[index];
|
|
3769
|
+
if (argument === "--help" || argument === "-h") return true;
|
|
3770
|
+
if (argument?.startsWith("--")) index += 1;
|
|
3771
|
+
}
|
|
3772
|
+
return false;
|
|
3773
|
+
}
|
|
3774
|
+
function delegationCliHelp(arguments_2) {
|
|
3775
|
+
const [group, command, ...rest] = arguments_2;
|
|
3776
|
+
if (!group || group === "--help" || group === "-h") return DELEGATION_HELP;
|
|
3777
|
+
if (!command || command === "--help" || command === "-h" || command === "help") {
|
|
3778
|
+
if (group === "delegate") return DELEGATION_HELP;
|
|
3779
|
+
if (group === "harness" || group === "thread") {
|
|
3780
|
+
const usages = Object.entries(COMMAND_HELP).filter(([name]) => name.startsWith(`${group} `)).map(([, help]) => help.split("\n")[0]);
|
|
3781
|
+
return `${usages.join("\n")}
|
|
3782
|
+
|
|
3783
|
+
${COMMON_HELP}
|
|
3784
|
+
`;
|
|
3785
|
+
}
|
|
3786
|
+
}
|
|
3787
|
+
if (hasHelpOption(rest)) {
|
|
3788
|
+
const name = `${group} ${command}`;
|
|
3789
|
+
if (Object.hasOwn(COMMAND_HELP, name)) {
|
|
3790
|
+
return `${COMMAND_HELP[name]}
|
|
3791
|
+
|
|
3792
|
+
${COMMON_HELP}
|
|
3793
|
+
`;
|
|
3794
|
+
}
|
|
3795
|
+
}
|
|
3796
|
+
return void 0;
|
|
3797
|
+
}
|
|
3798
|
+
|
|
3712
3799
|
// packages/host-runtime/src/delegation-types.ts
|
|
3713
3800
|
var DELEGATION_RUNTIME_ENDPOINT_ENV = "CODEXHOST_RUNTIME_ENDPOINT";
|
|
3714
3801
|
var DELEGATION_RUNTIME_TOKEN_ENV = "CODEXHOST_RUNTIME_TOKEN";
|
|
@@ -3725,6 +3812,114 @@ var DelegationControlError = class extends Error {
|
|
|
3725
3812
|
details;
|
|
3726
3813
|
};
|
|
3727
3814
|
|
|
3815
|
+
// packages/host-runtime/src/delegation-cli-output.ts
|
|
3816
|
+
function threadLink(threadId3) {
|
|
3817
|
+
return `codex://threads/${threadId3}`;
|
|
3818
|
+
}
|
|
3819
|
+
function inspectOutput({ harnessId, inspection }) {
|
|
3820
|
+
if (inspection.status !== "ready") return { harnessId, ...inspection };
|
|
3821
|
+
const { catalog } = inspection;
|
|
3822
|
+
return {
|
|
3823
|
+
harnessId,
|
|
3824
|
+
status: inspection.status,
|
|
3825
|
+
models: catalog.models.map(({ ref, label, supportedThinkingOptionIds }) => ({
|
|
3826
|
+
id: ref.id,
|
|
3827
|
+
label,
|
|
3828
|
+
...supportedThinkingOptionIds ? { thinking: supportedThinkingOptionIds } : {}
|
|
3829
|
+
})),
|
|
3830
|
+
...catalog.defaultModel ? { defaultModel: catalog.defaultModel.id } : {},
|
|
3831
|
+
thinkingOptions: catalog.thinkingOptions,
|
|
3832
|
+
...catalog.defaultThinkingOptionId ? { defaultThinkingOptionId: catalog.defaultThinkingOptionId } : {},
|
|
3833
|
+
capabilities: inspection.capabilities
|
|
3834
|
+
};
|
|
3835
|
+
}
|
|
3836
|
+
function snapshotOutput(snapshot, view) {
|
|
3837
|
+
const common = {
|
|
3838
|
+
thread: threadLink(snapshot.threadId),
|
|
3839
|
+
harnessId: snapshot.harnessId,
|
|
3840
|
+
status: snapshot.status,
|
|
3841
|
+
...snapshot.timedOut !== void 0 ? { timedOut: snapshot.timedOut } : {}
|
|
3842
|
+
};
|
|
3843
|
+
if (view === "messages") {
|
|
3844
|
+
if (typeof snapshot.hasMore !== "boolean") {
|
|
3845
|
+
throw new DelegationControlError(
|
|
3846
|
+
"INTERNAL_ERROR",
|
|
3847
|
+
"Compact message pagination requires an updated Host Runtime; use --format json with this Runtime."
|
|
3848
|
+
);
|
|
3849
|
+
}
|
|
3850
|
+
return {
|
|
3851
|
+
...common,
|
|
3852
|
+
messages: (snapshot.messages ?? []).map(({ role, phase, text: text2 }) => ({
|
|
3853
|
+
role,
|
|
3854
|
+
...phase ? { phase } : {},
|
|
3855
|
+
text: text2
|
|
3856
|
+
})),
|
|
3857
|
+
hasMore: snapshot.hasMore,
|
|
3858
|
+
nextCursor: snapshot.nextCursor,
|
|
3859
|
+
...snapshot.result.message ? { error: snapshot.result.message } : {}
|
|
3860
|
+
};
|
|
3861
|
+
}
|
|
3862
|
+
const progress = snapshot.progress.filter(({ text: text2 }) => text2.trim()).at(-1)?.text;
|
|
3863
|
+
return {
|
|
3864
|
+
...common,
|
|
3865
|
+
result: snapshot.result,
|
|
3866
|
+
...snapshot.status === "running" && progress ? { progress } : {}
|
|
3867
|
+
};
|
|
3868
|
+
}
|
|
3869
|
+
function compactDelegationOutput(command, body, view = "result") {
|
|
3870
|
+
switch (command) {
|
|
3871
|
+
case "harness list":
|
|
3872
|
+
return body;
|
|
3873
|
+
case "harness inspect":
|
|
3874
|
+
return inspectOutput(body);
|
|
3875
|
+
case "delegate start": {
|
|
3876
|
+
const result = body;
|
|
3877
|
+
const effective = result.configuration?.effective;
|
|
3878
|
+
return {
|
|
3879
|
+
thread: result.deepLink,
|
|
3880
|
+
harnessId: result.harnessId,
|
|
3881
|
+
status: result.status,
|
|
3882
|
+
...result.cwd ? { cwd: result.cwd } : {},
|
|
3883
|
+
...result.parentThreadId ? { parent: threadLink(result.parentThreadId) } : {},
|
|
3884
|
+
...effective?.resolvedModelLabel ? { model: effective.resolvedModelLabel } : {},
|
|
3885
|
+
...effective?.effectiveThinkingOptionId ? { thinking: effective.effectiveThinkingOptionId } : {}
|
|
3886
|
+
};
|
|
3887
|
+
}
|
|
3888
|
+
case "thread send": {
|
|
3889
|
+
const result = body;
|
|
3890
|
+
return {
|
|
3891
|
+
thread: threadLink(result.threadId),
|
|
3892
|
+
harnessId: result.harnessId,
|
|
3893
|
+
status: result.status
|
|
3894
|
+
};
|
|
3895
|
+
}
|
|
3896
|
+
case "thread cancel": {
|
|
3897
|
+
const result = body;
|
|
3898
|
+
return {
|
|
3899
|
+
thread: threadLink(result.threadId),
|
|
3900
|
+
harnessId: result.harnessId,
|
|
3901
|
+
cancelRequested: result.cancelled
|
|
3902
|
+
};
|
|
3903
|
+
}
|
|
3904
|
+
case "thread read":
|
|
3905
|
+
case "thread wait":
|
|
3906
|
+
return snapshotOutput(body, view);
|
|
3907
|
+
case "thread list": {
|
|
3908
|
+
const result = body;
|
|
3909
|
+
return {
|
|
3910
|
+
threads: result.threads.map(({ deepLink, harnessId, status, title, cwd }) => ({
|
|
3911
|
+
thread: deepLink,
|
|
3912
|
+
harnessId,
|
|
3913
|
+
status,
|
|
3914
|
+
...title ? { title } : {},
|
|
3915
|
+
...cwd ? { cwd } : {}
|
|
3916
|
+
})),
|
|
3917
|
+
nextCursor: result.nextCursor
|
|
3918
|
+
};
|
|
3919
|
+
}
|
|
3920
|
+
}
|
|
3921
|
+
}
|
|
3922
|
+
|
|
3728
3923
|
// packages/host-runtime/src/delegation-cli.ts
|
|
3729
3924
|
var DEFAULT_WAIT_TIMEOUT_MS = 3e4;
|
|
3730
3925
|
var DEFAULT_LIMIT = 25;
|
|
@@ -3771,45 +3966,12 @@ function value(parsed, name) {
|
|
|
3771
3966
|
return parsed.options.get(name);
|
|
3772
3967
|
}
|
|
3773
3968
|
function rejectUnknown(parsed, allowed) {
|
|
3774
|
-
const known = new Set(allowed);
|
|
3969
|
+
const known = /* @__PURE__ */ new Set([...allowed, "--format"]);
|
|
3775
3970
|
for (const name of parsed.options.keys()) {
|
|
3776
3971
|
if (!known.has(name))
|
|
3777
3972
|
throw new DelegationControlError("INVALID_ARGUMENT", `Unknown option '${name}'`);
|
|
3778
3973
|
}
|
|
3779
3974
|
}
|
|
3780
|
-
var DELEGATION_HELP = `usage:
|
|
3781
|
-
boft harness inspect <harness> [--cwd <path>] [--refresh true|false]
|
|
3782
|
-
boft delegate start --harness <id> --task <text> [--cwd <path>] [--model <opaque-ref>] [--thinking <option-id>] [--parent-thread <thread>] [--request-id <id>]
|
|
3783
|
-
boft thread send <thread> --message <text>
|
|
3784
|
-
boft thread cancel <thread>
|
|
3785
|
-
boft thread read <thread> [--view result|messages] [--cursor <cursor>] [--limit <n>]
|
|
3786
|
-
boft thread wait <thread> [--timeout-ms <n>] [--view result|messages] [--cursor <cursor>] [--limit <n>]
|
|
3787
|
-
boft 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. --cwd selects the child workspace and defaults to the resolved parent Thread workspace, with the caller process cwd as a fallback. --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
|
-
Native Codex shell commands also need the Host-provided CODEXHOST_* environment variables. If shell_environment_policy filters them, prefer inherit = "all" with ignore_default_excludes = true and a narrow include_only containing "CODEXHOST_RUNTIME_ENDPOINT" and "CODEXHOST_RUNTIME_TOKEN" plus the variables required by the platform and invoked tools. Avoid unconstrained inherit = "all", which forwards unrelated ambient variables.
|
|
3802
|
-
|
|
3803
|
-
Errors are JSON: {"error":{"code":"...","message":"...","details":{...}}}.
|
|
3804
|
-
INVALID_ARGUMENT: fix the named argument or incompatible option combination.
|
|
3805
|
-
HARNESS_NOT_FOUND: choose a Harness ID listed in error.details.validHarnessIds.
|
|
3806
|
-
THREAD_NOT_FOUND: verify the bare ID or codex:// deep link.
|
|
3807
|
-
THREAD_BUSY: wait for or cancel the active Turn before sending another message.
|
|
3808
|
-
PARENT_THREAD_AMBIGUOUS: pass --parent-thread explicitly.
|
|
3809
|
-
RUNTIME_UNREACHABLE: run inside the Host-provided environment and, for native Codex, allow local Runtime connections; boft never falls back to PATH or another Runtime.
|
|
3810
|
-
DELEGATION_FAILED: the target Session or initial task delivery failed and no successful child was published.
|
|
3811
|
-
INTERNAL_ERROR: retry after checking the Host Runtime diagnostics.
|
|
3812
|
-
`;
|
|
3813
3975
|
async function requestRuntime(input) {
|
|
3814
3976
|
const endpoint = input.environment[DELEGATION_RUNTIME_ENDPOINT_ENV];
|
|
3815
3977
|
const token = input.environment[DELEGATION_RUNTIME_TOKEN_ENV];
|
|
@@ -3870,12 +4032,37 @@ async function runDelegationCli(input) {
|
|
|
3870
4032
|
const environment = input.environment ?? process.env;
|
|
3871
4033
|
try {
|
|
3872
4034
|
const [group, command, ...rest] = input.arguments;
|
|
3873
|
-
|
|
3874
|
-
|
|
4035
|
+
const help = delegationCliHelp(input.arguments);
|
|
4036
|
+
if (help !== void 0) {
|
|
4037
|
+
output.write(help);
|
|
4038
|
+
return 0;
|
|
4039
|
+
}
|
|
4040
|
+
const parsed = options(rest);
|
|
4041
|
+
const format = value(parsed, "--format") ?? "json";
|
|
4042
|
+
if (format !== "json" && format !== "compact") {
|
|
4043
|
+
throw new DelegationControlError("INVALID_ARGUMENT", "--format must be json or compact");
|
|
4044
|
+
}
|
|
4045
|
+
const writeResult = (name, body, view = "result") => writeJson(output, format === "json" ? body : compactDelegationOutput(name, body, view));
|
|
4046
|
+
if (group === "harness" && command === "list") {
|
|
4047
|
+
rejectUnknown(parsed, []);
|
|
4048
|
+
if (parsed.positionals.length > 0) {
|
|
4049
|
+
throw new DelegationControlError(
|
|
4050
|
+
"INVALID_ARGUMENT",
|
|
4051
|
+
"harness list accepts no positional arguments"
|
|
4052
|
+
);
|
|
4053
|
+
}
|
|
4054
|
+
writeResult(
|
|
4055
|
+
"harness list",
|
|
4056
|
+
await requestRuntime({
|
|
4057
|
+
environment,
|
|
4058
|
+
path: "/v1/harness/list",
|
|
4059
|
+
body: {},
|
|
4060
|
+
...input.fetchImpl ? { fetchImpl: input.fetchImpl } : {}
|
|
4061
|
+
})
|
|
4062
|
+
);
|
|
3875
4063
|
return 0;
|
|
3876
4064
|
}
|
|
3877
4065
|
if (group === "harness" && command === "inspect") {
|
|
3878
|
-
const parsed = options(rest);
|
|
3879
4066
|
rejectUnknown(parsed, ["--cwd", "--refresh"]);
|
|
3880
4067
|
if (parsed.positionals.length !== 1) {
|
|
3881
4068
|
throw new DelegationControlError(
|
|
@@ -3891,8 +4078,8 @@ async function runDelegationCli(input) {
|
|
|
3891
4078
|
if (refresh !== void 0 && refresh !== "true" && refresh !== "false") {
|
|
3892
4079
|
throw new DelegationControlError("INVALID_ARGUMENT", "--refresh must be true or false");
|
|
3893
4080
|
}
|
|
3894
|
-
|
|
3895
|
-
|
|
4081
|
+
writeResult(
|
|
4082
|
+
"harness inspect",
|
|
3896
4083
|
await requestRuntime({
|
|
3897
4084
|
environment,
|
|
3898
4085
|
path: "/v1/harness/inspect",
|
|
@@ -3907,7 +4094,6 @@ async function runDelegationCli(input) {
|
|
|
3907
4094
|
return 0;
|
|
3908
4095
|
}
|
|
3909
4096
|
if (group === "delegate" && command === "start") {
|
|
3910
|
-
const parsed = options(rest);
|
|
3911
4097
|
rejectUnknown(parsed, [
|
|
3912
4098
|
"--harness",
|
|
3913
4099
|
"--task",
|
|
@@ -3927,8 +4113,8 @@ async function runDelegationCli(input) {
|
|
|
3927
4113
|
if (!harnessId || !task)
|
|
3928
4114
|
throw new DelegationControlError("INVALID_ARGUMENT", "--harness and --task are required");
|
|
3929
4115
|
const parentThread = value(parsed, "--parent-thread") ?? environment[DELEGATION_THREAD_ID_ENV];
|
|
3930
|
-
|
|
3931
|
-
|
|
4116
|
+
writeResult(
|
|
4117
|
+
"delegate start",
|
|
3932
4118
|
await requestRuntime({
|
|
3933
4119
|
environment,
|
|
3934
4120
|
path: "/v1/delegate/start",
|
|
@@ -3947,7 +4133,6 @@ async function runDelegationCli(input) {
|
|
|
3947
4133
|
return 0;
|
|
3948
4134
|
}
|
|
3949
4135
|
if (group === "thread" && command === "send") {
|
|
3950
|
-
const parsed = options(rest);
|
|
3951
4136
|
rejectUnknown(parsed, ["--message"]);
|
|
3952
4137
|
if (parsed.positionals.length !== 1) {
|
|
3953
4138
|
throw new DelegationControlError(
|
|
@@ -3963,8 +4148,8 @@ async function runDelegationCli(input) {
|
|
|
3963
4148
|
"Thread identifier and --message are required"
|
|
3964
4149
|
);
|
|
3965
4150
|
}
|
|
3966
|
-
|
|
3967
|
-
|
|
4151
|
+
writeResult(
|
|
4152
|
+
"thread send",
|
|
3968
4153
|
await requestRuntime({
|
|
3969
4154
|
environment,
|
|
3970
4155
|
path: "/v1/thread/send",
|
|
@@ -3975,7 +4160,6 @@ async function runDelegationCli(input) {
|
|
|
3975
4160
|
return 0;
|
|
3976
4161
|
}
|
|
3977
4162
|
if (group === "thread" && command === "cancel") {
|
|
3978
|
-
const parsed = options(rest);
|
|
3979
4163
|
rejectUnknown(parsed, []);
|
|
3980
4164
|
if (parsed.positionals.length !== 1) {
|
|
3981
4165
|
throw new DelegationControlError(
|
|
@@ -3987,8 +4171,8 @@ async function runDelegationCli(input) {
|
|
|
3987
4171
|
if (!threadId3) {
|
|
3988
4172
|
throw new DelegationControlError("INVALID_ARGUMENT", "Thread identifier is required");
|
|
3989
4173
|
}
|
|
3990
|
-
|
|
3991
|
-
|
|
4174
|
+
writeResult(
|
|
4175
|
+
"thread cancel",
|
|
3992
4176
|
await requestRuntime({
|
|
3993
4177
|
environment,
|
|
3994
4178
|
path: "/v1/thread/cancel",
|
|
@@ -3999,7 +4183,6 @@ async function runDelegationCli(input) {
|
|
|
3999
4183
|
return 0;
|
|
4000
4184
|
}
|
|
4001
4185
|
if (group === "thread" && (command === "read" || command === "wait")) {
|
|
4002
|
-
const parsed = options(rest);
|
|
4003
4186
|
rejectUnknown(parsed, ["--view", "--cursor", "--limit", "--timeout-ms"]);
|
|
4004
4187
|
if (parsed.positionals.length !== 1)
|
|
4005
4188
|
throw new DelegationControlError(
|
|
@@ -4031,19 +4214,19 @@ async function runDelegationCli(input) {
|
|
|
4031
4214
|
timeoutMs: value(parsed, "--timeout-ms") ? positiveInteger(value(parsed, "--timeout-ms"), "--timeout-ms") : DEFAULT_WAIT_TIMEOUT_MS
|
|
4032
4215
|
} : {}
|
|
4033
4216
|
};
|
|
4034
|
-
|
|
4035
|
-
|
|
4217
|
+
writeResult(
|
|
4218
|
+
command === "read" ? "thread read" : "thread wait",
|
|
4036
4219
|
await requestRuntime({
|
|
4037
4220
|
environment,
|
|
4038
4221
|
path: command === "read" ? "/v1/thread/read" : "/v1/thread/wait",
|
|
4039
4222
|
body,
|
|
4040
4223
|
...input.fetchImpl ? { fetchImpl: input.fetchImpl } : {}
|
|
4041
|
-
})
|
|
4224
|
+
}),
|
|
4225
|
+
view
|
|
4042
4226
|
);
|
|
4043
4227
|
return 0;
|
|
4044
4228
|
}
|
|
4045
4229
|
if (group === "thread" && command === "list") {
|
|
4046
|
-
const parsed = options(rest);
|
|
4047
4230
|
rejectUnknown(parsed, ["--cwd", "--parent", "--limit", "--cursor", "--sort"]);
|
|
4048
4231
|
if (parsed.positionals.length > 0)
|
|
4049
4232
|
throw new DelegationControlError(
|
|
@@ -4061,8 +4244,8 @@ async function runDelegationCli(input) {
|
|
|
4061
4244
|
])).has(sort))
|
|
4062
4245
|
throw new DelegationControlError("INVALID_ARGUMENT", "--sort is invalid");
|
|
4063
4246
|
const parentThread = value(parsed, "--parent");
|
|
4064
|
-
|
|
4065
|
-
|
|
4247
|
+
writeResult(
|
|
4248
|
+
"thread list",
|
|
4066
4249
|
await requestRuntime({
|
|
4067
4250
|
environment,
|
|
4068
4251
|
path: "/v1/thread/list",
|
|
@@ -4100,7 +4283,8 @@ async function runDelegationCli(input) {
|
|
|
4100
4283
|
|
|
4101
4284
|
// packages/host-runtime/src/run-host-runtime.ts
|
|
4102
4285
|
import { randomBytes } from "node:crypto";
|
|
4103
|
-
import
|
|
4286
|
+
import path21 from "node:path";
|
|
4287
|
+
import { homedir } from "node:os";
|
|
4104
4288
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
4105
4289
|
|
|
4106
4290
|
// packages/update-manager/dist/distribution.js
|
|
@@ -4260,7 +4444,7 @@ async function resolveInstalledUpdateContext(options2) {
|
|
|
4260
4444
|
const stateDirectory = path.normalize(options2.stateDirectory ?? defaultUpdateStateDirectory(platform, environment));
|
|
4261
4445
|
const resourcesRoot = path.dirname(appDirectory);
|
|
4262
4446
|
const installationRoot = platform === "darwin" ? path.dirname(path.dirname(resourcesRoot)) : resourcesRoot;
|
|
4263
|
-
const updaterExecutable = path.join(resourcesRoot, "libexec", platform === "win32" ? "
|
|
4447
|
+
const updaterExecutable = path.join(resourcesRoot, "libexec", platform === "win32" ? "boft-updater.exe" : "boft-updater");
|
|
4264
4448
|
const common = {
|
|
4265
4449
|
version: metadata.version,
|
|
4266
4450
|
launcherPid,
|
|
@@ -4823,7 +5007,7 @@ function createBackgroundUpdateManager(dependencies2 = {}) {
|
|
|
4823
5007
|
const workDirectory = path3.join(stateDirectory, `update-${version2}-${randomId()}`);
|
|
4824
5008
|
await mkdir2(workDirectory, { recursive: false, mode: 448 });
|
|
4825
5009
|
const executableSuffix = platform === "win32" ? ".exe" : "";
|
|
4826
|
-
const helperPath = path3.join(workDirectory, `
|
|
5010
|
+
const helperPath = path3.join(workDirectory, `boft-updater${executableSuffix}`);
|
|
4827
5011
|
await copyFile(updaterExecutable, helperPath);
|
|
4828
5012
|
if (platform !== "win32")
|
|
4829
5013
|
await chmod(helperPath, 448);
|
|
@@ -5958,10 +6142,10 @@ function mergeDefs(...defs) {
|
|
|
5958
6142
|
function cloneDef(schema) {
|
|
5959
6143
|
return mergeDefs(schema._zod.def);
|
|
5960
6144
|
}
|
|
5961
|
-
function getElementAtPath(obj,
|
|
5962
|
-
if (!
|
|
6145
|
+
function getElementAtPath(obj, path26) {
|
|
6146
|
+
if (!path26)
|
|
5963
6147
|
return obj;
|
|
5964
|
-
return
|
|
6148
|
+
return path26.reduce((acc, key) => acc?.[key], obj);
|
|
5965
6149
|
}
|
|
5966
6150
|
function promiseAllObject(promisesObj) {
|
|
5967
6151
|
const keys = Object.keys(promisesObj);
|
|
@@ -6370,11 +6554,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
6370
6554
|
}
|
|
6371
6555
|
return false;
|
|
6372
6556
|
}
|
|
6373
|
-
function prefixIssues(
|
|
6557
|
+
function prefixIssues(path26, issues) {
|
|
6374
6558
|
return issues.map((iss) => {
|
|
6375
6559
|
var _a3;
|
|
6376
6560
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
6377
|
-
iss.path.unshift(
|
|
6561
|
+
iss.path.unshift(path26);
|
|
6378
6562
|
return iss;
|
|
6379
6563
|
});
|
|
6380
6564
|
}
|
|
@@ -6521,16 +6705,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
6521
6705
|
}
|
|
6522
6706
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
6523
6707
|
const fieldErrors = { _errors: [] };
|
|
6524
|
-
const processError = (error52,
|
|
6708
|
+
const processError = (error52, path26 = []) => {
|
|
6525
6709
|
for (const issue2 of error52.issues) {
|
|
6526
6710
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
6527
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
6711
|
+
issue2.errors.map((issues) => processError({ issues }, [...path26, ...issue2.path]));
|
|
6528
6712
|
} else if (issue2.code === "invalid_key") {
|
|
6529
|
-
processError({ issues: issue2.issues }, [...
|
|
6713
|
+
processError({ issues: issue2.issues }, [...path26, ...issue2.path]);
|
|
6530
6714
|
} else if (issue2.code === "invalid_element") {
|
|
6531
|
-
processError({ issues: issue2.issues }, [...
|
|
6715
|
+
processError({ issues: issue2.issues }, [...path26, ...issue2.path]);
|
|
6532
6716
|
} else {
|
|
6533
|
-
const fullpath = [...
|
|
6717
|
+
const fullpath = [...path26, ...issue2.path];
|
|
6534
6718
|
if (fullpath.length === 0) {
|
|
6535
6719
|
fieldErrors._errors.push(mapper(issue2));
|
|
6536
6720
|
} else {
|
|
@@ -6557,17 +6741,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
6557
6741
|
}
|
|
6558
6742
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
6559
6743
|
const result = { errors: [] };
|
|
6560
|
-
const processError = (error52,
|
|
6744
|
+
const processError = (error52, path26 = []) => {
|
|
6561
6745
|
var _a3, _b;
|
|
6562
6746
|
for (const issue2 of error52.issues) {
|
|
6563
6747
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
6564
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
6748
|
+
issue2.errors.map((issues) => processError({ issues }, [...path26, ...issue2.path]));
|
|
6565
6749
|
} else if (issue2.code === "invalid_key") {
|
|
6566
|
-
processError({ issues: issue2.issues }, [...
|
|
6750
|
+
processError({ issues: issue2.issues }, [...path26, ...issue2.path]);
|
|
6567
6751
|
} else if (issue2.code === "invalid_element") {
|
|
6568
|
-
processError({ issues: issue2.issues }, [...
|
|
6752
|
+
processError({ issues: issue2.issues }, [...path26, ...issue2.path]);
|
|
6569
6753
|
} else {
|
|
6570
|
-
const fullpath = [...
|
|
6754
|
+
const fullpath = [...path26, ...issue2.path];
|
|
6571
6755
|
if (fullpath.length === 0) {
|
|
6572
6756
|
result.errors.push(mapper(issue2));
|
|
6573
6757
|
continue;
|
|
@@ -6599,8 +6783,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
6599
6783
|
}
|
|
6600
6784
|
function toDotPath(_path) {
|
|
6601
6785
|
const segs = [];
|
|
6602
|
-
const
|
|
6603
|
-
for (const seg of
|
|
6786
|
+
const path26 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
6787
|
+
for (const seg of path26) {
|
|
6604
6788
|
if (typeof seg === "number")
|
|
6605
6789
|
segs.push(`[${seg}]`);
|
|
6606
6790
|
else if (typeof seg === "symbol")
|
|
@@ -19292,13 +19476,13 @@ function resolveRef(ref, ctx) {
|
|
|
19292
19476
|
if (!ref.startsWith("#")) {
|
|
19293
19477
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
19294
19478
|
}
|
|
19295
|
-
const
|
|
19296
|
-
if (
|
|
19479
|
+
const path26 = ref.slice(1).split("/").filter(Boolean);
|
|
19480
|
+
if (path26.length === 0) {
|
|
19297
19481
|
return ctx.rootSchema;
|
|
19298
19482
|
}
|
|
19299
19483
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
19300
|
-
if (
|
|
19301
|
-
const key =
|
|
19484
|
+
if (path26[0] === defsKey) {
|
|
19485
|
+
const key = path26[1];
|
|
19302
19486
|
if (!key || !ctx.defs[key]) {
|
|
19303
19487
|
throw new Error(`Reference not found: ${ref}`);
|
|
19304
19488
|
}
|
|
@@ -20687,6 +20871,12 @@ function parseHostUsage(value2) {
|
|
|
20687
20871
|
throw new Error(`Harness Usage contains unknown field '${key}'`);
|
|
20688
20872
|
}
|
|
20689
20873
|
}
|
|
20874
|
+
for (const field of ["totalCredits", "contextUsagePercent"]) {
|
|
20875
|
+
const candidate = value2[field];
|
|
20876
|
+
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0)) {
|
|
20877
|
+
throw new Error(`Harness Usage '${field}' must be a finite non-negative number`);
|
|
20878
|
+
}
|
|
20879
|
+
}
|
|
20690
20880
|
for (const field of tokenFields) {
|
|
20691
20881
|
const candidate = value2[field];
|
|
20692
20882
|
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
|
|
@@ -22329,8 +22519,8 @@ function projectFileChangeKind(kind) {
|
|
|
22329
22519
|
return { type: kind };
|
|
22330
22520
|
}
|
|
22331
22521
|
function projectFileChanges(changes) {
|
|
22332
|
-
return changes.map(({ path:
|
|
22333
|
-
path:
|
|
22522
|
+
return changes.map(({ path: path26, kind, unifiedDiff }) => ({
|
|
22523
|
+
path: path26,
|
|
22334
22524
|
kind: projectFileChangeKind(kind),
|
|
22335
22525
|
diff: unifiedDiff
|
|
22336
22526
|
}));
|
|
@@ -22561,6 +22751,7 @@ function projectItem(item, outcome, defaultCwd, includeCommandOutput = true, sen
|
|
|
22561
22751
|
};
|
|
22562
22752
|
case "subagentDelegation": {
|
|
22563
22753
|
const primary = item.subagents[0];
|
|
22754
|
+
const sameConfiguration = item.subagents.every((subagent) => subagent.model === primary?.model && subagent.reasoningEffort === primary?.reasoningEffort);
|
|
22564
22755
|
return {
|
|
22565
22756
|
id: item.itemId,
|
|
22566
22757
|
type: "collabAgentToolCall",
|
|
@@ -22569,8 +22760,8 @@ function projectItem(item, outcome, defaultCwd, includeCommandOutput = true, sen
|
|
|
22569
22760
|
senderThreadId: senderThreadId ?? "",
|
|
22570
22761
|
receiverThreadIds: item.subagents.map(({ subagentId }) => subagentId),
|
|
22571
22762
|
prompt: item.prompt ?? null,
|
|
22572
|
-
model: primary?.model ?? null,
|
|
22573
|
-
reasoningEffort: primary?.reasoningEffort ?? null,
|
|
22763
|
+
model: sameConfiguration ? primary?.model ?? null : null,
|
|
22764
|
+
reasoningEffort: sameConfiguration ? primary?.reasoningEffort ?? null : null,
|
|
22574
22765
|
agentsStates: Object.fromEntries(item.subagents.map(({ subagentId, status, resultSummary }) => [
|
|
22575
22766
|
subagentId,
|
|
22576
22767
|
{ status: collabAgentStatus(status), message: resultSummary ?? null }
|
|
@@ -22625,7 +22816,9 @@ function projectHistoricalTurn(input) {
|
|
|
22625
22816
|
codexErrorInfo: "other",
|
|
22626
22817
|
additionalDetails: null
|
|
22627
22818
|
} : null;
|
|
22628
|
-
const
|
|
22819
|
+
const startedAtMs = snapshot.startedAtMs;
|
|
22820
|
+
const completedAtMs = snapshot.completedAtMs;
|
|
22821
|
+
const hasTiming = startedAtMs !== void 0 && completedAtMs !== void 0 && Number.isFinite(startedAtMs) && Number.isFinite(completedAtMs) && startedAtMs >= 0 && completedAtMs >= startedAtMs;
|
|
22629
22822
|
return {
|
|
22630
22823
|
id: turnId,
|
|
22631
22824
|
status: historicalStatus(snapshot.outcome),
|
|
@@ -22656,9 +22849,9 @@ function projectHistoricalTurn(input) {
|
|
|
22656
22849
|
})
|
|
22657
22850
|
],
|
|
22658
22851
|
error: error51,
|
|
22659
|
-
startedAt:
|
|
22660
|
-
completedAt:
|
|
22661
|
-
durationMs:
|
|
22852
|
+
startedAt: hasTiming ? Math.floor(startedAtMs / 1e3) : null,
|
|
22853
|
+
completedAt: hasTiming ? Math.floor(completedAtMs / 1e3) : null,
|
|
22854
|
+
durationMs: hasTiming ? completedAtMs - startedAtMs : null,
|
|
22662
22855
|
itemsView: "full"
|
|
22663
22856
|
};
|
|
22664
22857
|
}
|
|
@@ -23285,13 +23478,13 @@ function decodeThreadForkRequest(request) {
|
|
|
23285
23478
|
if (runtimeWorkspaceRoots !== void 0 && runtimeWorkspaceRoots !== null && (!Array.isArray(runtimeWorkspaceRoots) || runtimeWorkspaceRoots.some((root) => typeof root !== "string" || root.length === 0))) {
|
|
23286
23479
|
throw new Error("thread/fork params.runtimeWorkspaceRoots must be text paths or null");
|
|
23287
23480
|
}
|
|
23288
|
-
const
|
|
23481
|
+
const path26 = optionalText(params, "path", { allowEmpty: true });
|
|
23289
23482
|
const ephemeral = optionalBoolean(params, "ephemeral");
|
|
23290
23483
|
return {
|
|
23291
23484
|
threadId: threadId3,
|
|
23292
23485
|
...lastTurnText ? { lastTurnId: hostTurnIdSchema.parse(lastTurnText) } : {},
|
|
23293
23486
|
...beforeTurnText ? { beforeTurnId: hostTurnIdSchema.parse(beforeTurnText) } : {},
|
|
23294
|
-
...
|
|
23487
|
+
...path26 ? { path: path26 } : {},
|
|
23295
23488
|
...optionalField(params, "model"),
|
|
23296
23489
|
...optionalField(params, "modelProvider"),
|
|
23297
23490
|
...optionalField(params, "cwd"),
|
|
@@ -25284,6 +25477,7 @@ async function executeCurrentLastTurnRollback(input) {
|
|
|
25284
25477
|
error: { code: -32079, message: "External Native Session is unavailable" }
|
|
25285
25478
|
};
|
|
25286
25479
|
}
|
|
25480
|
+
const configuration = currentConfiguration(current);
|
|
25287
25481
|
let opened;
|
|
25288
25482
|
try {
|
|
25289
25483
|
opened = await adapter.open({
|
|
@@ -25293,7 +25487,10 @@ async function executeCurrentLastTurnRollback(input) {
|
|
|
25293
25487
|
...input.environment ?? process.env,
|
|
25294
25488
|
[DELEGATION_THREAD_ID_ENV]: current.id
|
|
25295
25489
|
},
|
|
25296
|
-
sourceRef: currentNativeRef
|
|
25490
|
+
sourceRef: currentNativeRef,
|
|
25491
|
+
...configuration.effectiveModel ? { model: configuration.effectiveModel } : {},
|
|
25492
|
+
...configuration.effectiveThinkingOptionId ? { thinkingOptionId: configuration.effectiveThinkingOptionId } : {},
|
|
25493
|
+
...configuration.effectivePermissionModeId ? { permissionModeId: configuration.effectivePermissionModeId } : {}
|
|
25297
25494
|
});
|
|
25298
25495
|
} catch {
|
|
25299
25496
|
return { ok: false, error: { code: -32076, message: "External Thread rollback failed" } };
|
|
@@ -25310,7 +25507,6 @@ async function executeCurrentLastTurnRollback(input) {
|
|
|
25310
25507
|
error: { code: -32076, message: "External rollback did not return a valid Session" }
|
|
25311
25508
|
};
|
|
25312
25509
|
}
|
|
25313
|
-
const configuration = currentConfiguration(current);
|
|
25314
25510
|
const configurationError = await restoreCurrentConfiguration(session, configuration);
|
|
25315
25511
|
if (configurationError) {
|
|
25316
25512
|
await session.close().catch(() => void 0);
|
|
@@ -25882,6 +26078,8 @@ var ExternalThreadRuntime = class {
|
|
|
25882
26078
|
environment: { ...this.#environment, [DELEGATION_THREAD_ID_ENV]: record3.hostThreadId },
|
|
25883
26079
|
nativeRef: record3.nativeSessionRef,
|
|
25884
26080
|
knownTurnRefs: record3.turnMappings.map(({ nativeTurnRef }) => nativeTurnRef),
|
|
26081
|
+
...restoredSelection?.model ? { model: restoredSelection.model } : {},
|
|
26082
|
+
...restoredSelection?.thinkingOptionId ? { thinkingOptionId: restoredSelection.thinkingOptionId } : {},
|
|
25885
26083
|
...harnessId === "grok" && restoredSelection?.permissionModeId ? { permissionModeId: restoredSelection.permissionModeId } : {}
|
|
25886
26084
|
});
|
|
25887
26085
|
if (!opened.ok) {
|
|
@@ -26238,15 +26436,21 @@ function projectDelegationThreadSnapshot(input) {
|
|
|
26238
26436
|
const latestTurnStatus = latestTurn ? turnStatus2(latestTurn.status) : null;
|
|
26239
26437
|
const status = input.running ? "running" : latestTurnStatus === "failed" || latestTurnStatus === "interrupted" ? latestTurnStatus : threadStatus(input.thread.status, input.running);
|
|
26240
26438
|
const latestTurnMessages = latestTurnId ? visible.filter((message) => message.turnId === latestTurnId && message.role === "agent") : [];
|
|
26241
|
-
const final = latestTurnMessages.filter((message) => message.phase === "final").at(-1);
|
|
26242
|
-
const progress = latestTurnMessages.filter((message) => message.phase !== "final").map(({ id: id2, turnId, text: text2 }) => ({ id: id2, turnId, text: text2 }));
|
|
26439
|
+
const final = latestTurnMessages.filter((message) => message.phase === "final" && message.text.trim()).at(-1);
|
|
26440
|
+
const progress = latestTurnMessages.filter((message) => message.phase !== "final" && message.text.trim()).map(({ id: id2, turnId, text: text2 }) => ({ id: id2, turnId, text: text2 }));
|
|
26243
26441
|
const result = input.running ? { availability: "pending" } : final ? { availability: "available", text: final.text } : {
|
|
26244
26442
|
availability: "unavailable",
|
|
26245
26443
|
...isRecord9(latestTurn?.error) && typeof latestTurn.error.message === "string" ? { message: latestTurn.error.message } : {}
|
|
26246
26444
|
};
|
|
26247
26445
|
const offset = options2.view === "messages" ? decodeCursor(input.threadId, options2.cursor) : visible.length;
|
|
26248
|
-
const page = options2.view === "messages" ?
|
|
26249
|
-
|
|
26446
|
+
const page = options2.view === "messages" ? [] : void 0;
|
|
26447
|
+
let nextOffset = offset;
|
|
26448
|
+
if (page) {
|
|
26449
|
+
while (nextOffset < visible.length && page.length < options2.limit) {
|
|
26450
|
+
const message = visible[nextOffset++];
|
|
26451
|
+
if (message?.text.trim()) page.push(message);
|
|
26452
|
+
}
|
|
26453
|
+
}
|
|
26250
26454
|
return {
|
|
26251
26455
|
threadId: input.threadId,
|
|
26252
26456
|
harnessId: input.harnessId,
|
|
@@ -26254,7 +26458,10 @@ function projectDelegationThreadSnapshot(input) {
|
|
|
26254
26458
|
turn: latestTurnId && latestTurnStatus ? { turnId: latestTurnId, status: latestTurnStatus } : null,
|
|
26255
26459
|
progress,
|
|
26256
26460
|
result,
|
|
26257
|
-
...page ? {
|
|
26461
|
+
...page ? {
|
|
26462
|
+
messages: page,
|
|
26463
|
+
hasMore: visible.slice(nextOffset).some((message) => message.text.trim())
|
|
26464
|
+
} : {},
|
|
26258
26465
|
nextCursor: encodeCursor(input.threadId, nextOffset)
|
|
26259
26466
|
};
|
|
26260
26467
|
}
|
|
@@ -26302,11 +26509,11 @@ function statusFromThread(thread) {
|
|
|
26302
26509
|
return last ? "completed" : "creating";
|
|
26303
26510
|
}
|
|
26304
26511
|
function validateStart(input) {
|
|
26305
|
-
if (!input.task
|
|
26512
|
+
if (typeof input.task !== "string" || !input.task.trim())
|
|
26306
26513
|
throw new DelegationControlError("INVALID_ARGUMENT", "Task must not be empty");
|
|
26307
|
-
if (input.cwd !== void 0 && !input.cwd.trim())
|
|
26514
|
+
if (input.cwd !== void 0 && (typeof input.cwd !== "string" || !input.cwd.trim()))
|
|
26308
26515
|
throw new DelegationControlError("INVALID_ARGUMENT", "cwd must not be empty");
|
|
26309
|
-
if (input.requestId !== void 0 && !input.requestId.trim()) {
|
|
26516
|
+
if (input.requestId !== void 0 && (typeof input.requestId !== "string" || !input.requestId.trim())) {
|
|
26310
26517
|
throw new DelegationControlError("INVALID_ARGUMENT", "Request ID must not be empty");
|
|
26311
26518
|
}
|
|
26312
26519
|
}
|
|
@@ -26324,6 +26531,7 @@ var HarnessDelegationCoordinator = class {
|
|
|
26324
26531
|
#cancelOfficial;
|
|
26325
26532
|
#startOfficial;
|
|
26326
26533
|
#listOfficial;
|
|
26534
|
+
#officialThreadCwd;
|
|
26327
26535
|
#activeOfficialParents;
|
|
26328
26536
|
constructor(input) {
|
|
26329
26537
|
this.#adapters = input.adapters;
|
|
@@ -26339,8 +26547,12 @@ var HarnessDelegationCoordinator = class {
|
|
|
26339
26547
|
this.#cancelOfficial = input.cancelOfficial;
|
|
26340
26548
|
this.#startOfficial = input.startOfficial;
|
|
26341
26549
|
this.#listOfficial = input.listOfficial;
|
|
26550
|
+
this.#officialThreadCwd = input.officialThreadCwd;
|
|
26342
26551
|
this.#activeOfficialParents = input.activeOfficialParents;
|
|
26343
26552
|
}
|
|
26553
|
+
async listHarnesses() {
|
|
26554
|
+
return { harnesses: ["codex", ...this.#adapters.keys()] };
|
|
26555
|
+
}
|
|
26344
26556
|
async inspect(input) {
|
|
26345
26557
|
if (input.harnessId === "codex") return this.#inspectOfficial(input);
|
|
26346
26558
|
const adapter = this.#adapters.get(input.harnessId);
|
|
@@ -26365,7 +26577,8 @@ var HarnessDelegationCoordinator = class {
|
|
|
26365
26577
|
const parent = await this.#parentMetadata(parentThreadId);
|
|
26366
26578
|
const selectedCwd = input.cwd ?? parent.cwd ?? process.cwd();
|
|
26367
26579
|
if (input.harnessId === "codex") {
|
|
26368
|
-
|
|
26580
|
+
const result = await this.#startOfficial({ ...input, parentThreadId, cwd: selectedCwd });
|
|
26581
|
+
return { ...result, parentThreadId, cwd: result.cwd ?? selectedCwd };
|
|
26369
26582
|
}
|
|
26370
26583
|
const startInput = { ...input, parentThreadId, cwd: path7.resolve(selectedCwd) };
|
|
26371
26584
|
if (!this.#adapters.has(input.harnessId)) {
|
|
@@ -26487,17 +26700,21 @@ var HarnessDelegationCoordinator = class {
|
|
|
26487
26700
|
}
|
|
26488
26701
|
await this.#repository.setDelegationStatus(delegationId, "running");
|
|
26489
26702
|
await this.#notifyThreadStarted(thread.thread);
|
|
26490
|
-
return
|
|
26491
|
-
|
|
26492
|
-
|
|
26493
|
-
|
|
26494
|
-
|
|
26495
|
-
|
|
26496
|
-
|
|
26497
|
-
|
|
26498
|
-
|
|
26499
|
-
|
|
26500
|
-
|
|
26703
|
+
return {
|
|
26704
|
+
...this.#result(delegationId, childThreadId, turnId, targetHarnessId, "running", {
|
|
26705
|
+
requested: {
|
|
26706
|
+
...input.model ? { model: input.model } : {},
|
|
26707
|
+
...input.thinkingOptionId ? { thinkingOptionId: input.thinkingOptionId } : {}
|
|
26708
|
+
},
|
|
26709
|
+
effective: {
|
|
26710
|
+
...thread.stateObserver.state.effectiveModel ? { effectiveModel: thread.stateObserver.state.effectiveModel } : {},
|
|
26711
|
+
...thread.stateObserver.state.resolvedModelLabel ? { resolvedModelLabel: thread.stateObserver.state.resolvedModelLabel } : {},
|
|
26712
|
+
...thread.stateObserver.state.effectiveThinkingOptionId ? { effectiveThinkingOptionId: thread.stateObserver.state.effectiveThinkingOptionId } : {}
|
|
26713
|
+
}
|
|
26714
|
+
}),
|
|
26715
|
+
cwd: record3.cwd,
|
|
26716
|
+
parentThreadId
|
|
26717
|
+
};
|
|
26501
26718
|
} catch (error51) {
|
|
26502
26719
|
if (session) await session.close().catch(() => void 0);
|
|
26503
26720
|
this.#externalRuntime.remove(childThreadId);
|
|
@@ -26726,19 +26943,24 @@ var HarnessDelegationCoordinator = class {
|
|
|
26726
26943
|
}
|
|
26727
26944
|
async #parentMetadata(parentThreadId) {
|
|
26728
26945
|
const record3 = await this.#repository.find(parentThreadId);
|
|
26729
|
-
if (
|
|
26730
|
-
|
|
26946
|
+
if (record3) return { harnessId: record3.harnessId, cwd: record3.cwd };
|
|
26947
|
+
const cwd = await this.#officialThreadCwd(parentThreadId).catch(() => void 0);
|
|
26948
|
+
return { harnessId: "codex", ...cwd ? { cwd } : {} };
|
|
26731
26949
|
}
|
|
26732
26950
|
async #existingResult(delegation) {
|
|
26733
26951
|
const record3 = await this.#repository.find(delegation.childHostThreadId);
|
|
26734
26952
|
const turnId = record3?.turnMappings.at(-1)?.hostTurnId ?? "pending";
|
|
26735
|
-
return
|
|
26736
|
-
|
|
26737
|
-
|
|
26738
|
-
|
|
26739
|
-
|
|
26740
|
-
|
|
26741
|
-
|
|
26953
|
+
return {
|
|
26954
|
+
...this.#result(
|
|
26955
|
+
delegation.delegationId,
|
|
26956
|
+
delegation.childHostThreadId,
|
|
26957
|
+
turnId,
|
|
26958
|
+
delegation.targetHarnessId,
|
|
26959
|
+
delegation.status
|
|
26960
|
+
),
|
|
26961
|
+
...record3 ? { cwd: record3.cwd } : {},
|
|
26962
|
+
parentThreadId: delegation.parentHostThreadId
|
|
26963
|
+
};
|
|
26742
26964
|
}
|
|
26743
26965
|
#turnResult(threadId3, turnId, harnessId) {
|
|
26744
26966
|
return {
|
|
@@ -27798,25 +28020,25 @@ function resolveExternalSessionTreeIds(records) {
|
|
|
27798
28020
|
const resolve = (start) => {
|
|
27799
28021
|
const cached2 = resolved.get(start.hostThreadId);
|
|
27800
28022
|
if (cached2) return cached2;
|
|
27801
|
-
const
|
|
28023
|
+
const path26 = [];
|
|
27802
28024
|
const visited = /* @__PURE__ */ new Set();
|
|
27803
28025
|
let current = start;
|
|
27804
28026
|
while (true) {
|
|
27805
28027
|
const known = resolved.get(current.hostThreadId);
|
|
27806
28028
|
if (known) {
|
|
27807
|
-
for (const record3 of
|
|
28029
|
+
for (const record3 of path26) resolved.set(record3.hostThreadId, known);
|
|
27808
28030
|
return known;
|
|
27809
28031
|
}
|
|
27810
28032
|
if (visited.has(current.hostThreadId)) {
|
|
27811
28033
|
throw new Error("External Thread Fork tree contains a cycle");
|
|
27812
28034
|
}
|
|
27813
28035
|
visited.add(current.hostThreadId);
|
|
27814
|
-
|
|
28036
|
+
path26.push(current);
|
|
27815
28037
|
const sourceId = current.forkSource?.hostThreadId;
|
|
27816
28038
|
const source = sourceId ? byId.get(sourceId) : void 0;
|
|
27817
28039
|
if (!source) {
|
|
27818
28040
|
const root = current.hostThreadId;
|
|
27819
|
-
for (const record3 of
|
|
28041
|
+
for (const record3 of path26) resolved.set(record3.hostThreadId, root);
|
|
27820
28042
|
return root;
|
|
27821
28043
|
}
|
|
27822
28044
|
current = source;
|
|
@@ -28361,6 +28583,8 @@ function approvalServerName(harnessId) {
|
|
|
28361
28583
|
return "Oh My Pi";
|
|
28362
28584
|
case "antigravity":
|
|
28363
28585
|
return "Antigravity CLI";
|
|
28586
|
+
case "kiro-cli":
|
|
28587
|
+
return "Kiro CLI";
|
|
28364
28588
|
default:
|
|
28365
28589
|
return harnessId;
|
|
28366
28590
|
}
|
|
@@ -28562,9 +28786,11 @@ var AppServerHost = class {
|
|
|
28562
28786
|
cancelOfficial: (input) => this.#cancelOfficialDelegationThread(input),
|
|
28563
28787
|
startOfficial: (input) => this.#startOfficialDelegation(input),
|
|
28564
28788
|
listOfficial: (input) => this.#listDelegationThreads(input),
|
|
28789
|
+
officialThreadCwd: (threadId3) => this.#readOfficialThreadCwd(threadId3),
|
|
28565
28790
|
activeOfficialParents: () => [...this.#activeOfficialTurns.keys()]
|
|
28566
28791
|
});
|
|
28567
28792
|
const unregisterDelegationApi = options2.onDelegationApi?.({
|
|
28793
|
+
listHarnesses: () => this.#delegationCoordinator.listHarnesses(),
|
|
28568
28794
|
inspect: (input) => this.#delegationCoordinator.inspect(input),
|
|
28569
28795
|
start: (input) => this.#delegationCoordinator.start(input),
|
|
28570
28796
|
send: (input) => this.#delegationCoordinator.send(input),
|
|
@@ -29599,6 +29825,13 @@ var AppServerHost = class {
|
|
|
29599
29825
|
]);
|
|
29600
29826
|
return thread !== null || childDelegation !== null || delegation !== null;
|
|
29601
29827
|
}
|
|
29828
|
+
async #readOfficialThreadCwd(threadId3) {
|
|
29829
|
+
const response = await this.#requestOfficial("thread/read", { threadId: threadId3 });
|
|
29830
|
+
if (isRecord13(response.error)) return void 0;
|
|
29831
|
+
const result = isRecord13(response.result) ? response.result : null;
|
|
29832
|
+
const thread = result && isRecord13(result.thread) ? result.thread : null;
|
|
29833
|
+
return thread && typeof thread.cwd === "string" && thread.cwd.trim() ? thread.cwd : void 0;
|
|
29834
|
+
}
|
|
29602
29835
|
async #inspectOfficialDelegationTarget(input) {
|
|
29603
29836
|
const response = await this.#requestOfficial("model/list", {});
|
|
29604
29837
|
if (isRecord13(response.error)) {
|
|
@@ -29791,6 +30024,7 @@ var AppServerHost = class {
|
|
|
29791
30024
|
harnessId: "codex",
|
|
29792
30025
|
deepLink: `codex://threads/${threadId3}`,
|
|
29793
30026
|
status: pendingTerminal ?? "running",
|
|
30027
|
+
cwd: thread && typeof thread.cwd === "string" ? thread.cwd : input.cwd,
|
|
29794
30028
|
...requestedModel || input.thinkingOptionId ? {
|
|
29795
30029
|
configuration: {
|
|
29796
30030
|
requested: {
|
|
@@ -32107,6 +32341,40 @@ var AppServerHost = class {
|
|
|
32107
32341
|
}
|
|
32108
32342
|
};
|
|
32109
32343
|
|
|
32344
|
+
// packages/host-runtime/src/codex-runtime/account-official-listeners.ts
|
|
32345
|
+
import path13 from "node:path";
|
|
32346
|
+
var AccountOfficialListeners = class {
|
|
32347
|
+
constructor(createListener) {
|
|
32348
|
+
this.createListener = createListener;
|
|
32349
|
+
}
|
|
32350
|
+
createListener;
|
|
32351
|
+
#listeners = /* @__PURE__ */ new Map();
|
|
32352
|
+
#starting = /* @__PURE__ */ new Map();
|
|
32353
|
+
#closed = false;
|
|
32354
|
+
async endpoint(account) {
|
|
32355
|
+
if (this.#closed) throw new Error("Account official listeners are closed");
|
|
32356
|
+
const key = path13.resolve(account.codexHome);
|
|
32357
|
+
const existing = this.#starting.get(key);
|
|
32358
|
+
if (existing) return existing;
|
|
32359
|
+
const listener = this.createListener(account);
|
|
32360
|
+
this.#listeners.set(key, listener);
|
|
32361
|
+
const starting = listener.listen().catch(async (error51) => {
|
|
32362
|
+
await listener.close();
|
|
32363
|
+
this.#listeners.delete(key);
|
|
32364
|
+
this.#starting.delete(key);
|
|
32365
|
+
throw error51;
|
|
32366
|
+
});
|
|
32367
|
+
this.#starting.set(key, starting);
|
|
32368
|
+
return starting;
|
|
32369
|
+
}
|
|
32370
|
+
async close() {
|
|
32371
|
+
this.#closed = true;
|
|
32372
|
+
await Promise.all([...this.#listeners.values()].map((listener) => listener.close()));
|
|
32373
|
+
this.#listeners.clear();
|
|
32374
|
+
this.#starting.clear();
|
|
32375
|
+
}
|
|
32376
|
+
};
|
|
32377
|
+
|
|
32110
32378
|
// packages/host-runtime/src/delegation-control-registry.ts
|
|
32111
32379
|
function only(values, message) {
|
|
32112
32380
|
const value2 = values.length === 1 ? values[0] : void 0;
|
|
@@ -32133,6 +32401,12 @@ var DelegationControlRegistry = class {
|
|
|
32133
32401
|
"Harness inspection requires exactly one active Host Runtime session"
|
|
32134
32402
|
).inspect(input);
|
|
32135
32403
|
}
|
|
32404
|
+
async listHarnesses() {
|
|
32405
|
+
return only(
|
|
32406
|
+
[...this.#registrations],
|
|
32407
|
+
"Harness discovery requires exactly one active Host Runtime session"
|
|
32408
|
+
).listHarnesses();
|
|
32409
|
+
}
|
|
32136
32410
|
async start(input) {
|
|
32137
32411
|
return (await this.#registrationForStart(input)).start(input);
|
|
32138
32412
|
}
|
|
@@ -32215,17 +32489,17 @@ var DelegationControlRegistry = class {
|
|
|
32215
32489
|
|
|
32216
32490
|
// packages/host-runtime/src/installed-harness-plugins.ts
|
|
32217
32491
|
import os3 from "node:os";
|
|
32218
|
-
import
|
|
32492
|
+
import path15 from "node:path";
|
|
32219
32493
|
import { fileURLToPath } from "node:url";
|
|
32220
32494
|
|
|
32221
32495
|
// packages/host-runtime/src/launcher-url-opener.ts
|
|
32222
32496
|
import { spawn as spawn3 } from "node:child_process";
|
|
32223
|
-
import
|
|
32497
|
+
import path14 from "node:path";
|
|
32224
32498
|
var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["127.0.0.1", "localhost", "[::1]"]);
|
|
32225
32499
|
var OPEN_TIMEOUT_MS = 1e4;
|
|
32226
32500
|
function createLauncherUrlOpener(environment, spawnLauncher = (command, arguments_2, options2) => spawn3(command, arguments_2, options2)) {
|
|
32227
32501
|
const launcher = environment.CODEXHOST_LAUNCHER_EXECUTABLE;
|
|
32228
|
-
if (!launcher || !
|
|
32502
|
+
if (!launcher || !path14.isAbsolute(launcher)) return void 0;
|
|
32229
32503
|
const launcherEnvironment = Object.fromEntries(
|
|
32230
32504
|
Object.entries(environment).filter(([name]) => {
|
|
32231
32505
|
const normalized = name.toUpperCase();
|
|
@@ -32283,9 +32557,9 @@ function installedHarnessPluginOptions(environment, managedRemoteHost = false, h
|
|
|
32283
32557
|
const opener = managedRemoteHost ? void 0 : createLauncherUrlOpener(environment);
|
|
32284
32558
|
return {
|
|
32285
32559
|
pluginRoots: [
|
|
32286
|
-
|
|
32287
|
-
environment[HARNESS_PLUGIN_DIRECTORY_ENV] ??
|
|
32288
|
-
environment.CODEXHOST_DATA_DIR ?
|
|
32560
|
+
path15.join(path15.dirname(fileURLToPath(hostRuntimeUrl)), "plugins"),
|
|
32561
|
+
environment[HARNESS_PLUGIN_DIRECTORY_ENV] ?? path15.join(
|
|
32562
|
+
environment.CODEXHOST_DATA_DIR ? path15.resolve(environment.CODEXHOST_DATA_DIR) : path15.join(os3.homedir(), ".codexhost"),
|
|
32289
32563
|
"plugins"
|
|
32290
32564
|
)
|
|
32291
32565
|
],
|
|
@@ -32364,6 +32638,9 @@ async function startDelegationControlServer(input) {
|
|
|
32364
32638
|
}
|
|
32365
32639
|
const body = await jsonBody(request);
|
|
32366
32640
|
switch (request.url) {
|
|
32641
|
+
case "/v1/harness/list":
|
|
32642
|
+
writeJson2(response, 200, await input.api.listHarnesses());
|
|
32643
|
+
return;
|
|
32367
32644
|
case "/v1/harness/inspect":
|
|
32368
32645
|
writeJson2(response, 200, await input.api.inspect(body));
|
|
32369
32646
|
return;
|
|
@@ -32410,10 +32687,12 @@ async function startDelegationControlServer(input) {
|
|
|
32410
32687
|
import { createHash as createHash6, randomUUID as randomUUID9 } from "node:crypto";
|
|
32411
32688
|
import { mkdir as mkdir7, open as open5, readFile as readFile8, rename as rename5, rm as rm5, stat as stat3 } from "node:fs/promises";
|
|
32412
32689
|
import os4 from "node:os";
|
|
32413
|
-
import
|
|
32414
|
-
var SKILL_VERSION =
|
|
32415
|
-
var SKILL_RELATIVE_PATH =
|
|
32690
|
+
import path16 from "node:path";
|
|
32691
|
+
var SKILL_VERSION = 7;
|
|
32692
|
+
var SKILL_RELATIVE_PATH = path16.join("skills", "codexhost-delegation", "SKILL.md");
|
|
32416
32693
|
var PREVIOUS_MANAGED_DIGESTS = [
|
|
32694
|
+
"9d2f491850fb0b4084a31ba9b5e4a550b5e833747af322090d8ed0ff80b88c30",
|
|
32695
|
+
"2bb0aebb9b06febbc6c0c0bcdb0b32506c7cdbf8dc3b734cc6b2a86621270e4e",
|
|
32417
32696
|
"aff258622dc8ff321f32b15620d081e578cb9c9ed1134d6a57f35ca8e7762c0a",
|
|
32418
32697
|
"ba509f57e5448e796b3dfdd5031dcb08672eded50b61c0a54de84cfa02c49dd3",
|
|
32419
32698
|
"d3ddf6db9bc5c5df825479c885bbbf0ca08da66f7057a12e02e1fdf57525149e",
|
|
@@ -32438,21 +32717,13 @@ Before acting, run:
|
|
|
32438
32717
|
|
|
32439
32718
|
\`boft delegate --help\`
|
|
32440
32719
|
|
|
32441
|
-
|
|
32442
|
-
|
|
32443
|
-
|
|
32444
|
-
|
|
32445
|
-
- available target Harness IDs;
|
|
32446
|
-
- Thread identifier formats;
|
|
32447
|
-
- waiting and reading behavior;
|
|
32448
|
-
- response fields;
|
|
32449
|
-
- errors and recovery guidance.
|
|
32720
|
+
Use CLI help as the authoritative source for commands and behavior. Consult
|
|
32721
|
+
command-specific help for options and the Harness listing command when the
|
|
32722
|
+
target is unknown. Prefer compact output when supported, and use its task links
|
|
32723
|
+
directly for subsequent commands.
|
|
32450
32724
|
|
|
32451
|
-
|
|
32452
|
-
|
|
32453
|
-
When the user asks for a specific Model or Thinking level, inspect the target
|
|
32454
|
-
Harness first and use the exact opaque IDs returned by the authoritative CLI.
|
|
32455
|
-
When they do not specify either setting, omit it so the target keeps its default.
|
|
32725
|
+
Use the Harness native defaults. Inspect the target when a Model or Thinking
|
|
32726
|
+
selection is needed or the default is unavailable.
|
|
32456
32727
|
|
|
32457
32728
|
For a new delegation, create an independent child session and submit the
|
|
32458
32729
|
requested task. For an existing external session, resolve the target from the
|
|
@@ -32471,18 +32742,8 @@ user’s request and the task:
|
|
|
32471
32742
|
- check it again later;
|
|
32472
32743
|
- leave it running in the background.
|
|
32473
32744
|
|
|
32474
|
-
|
|
32475
|
-
|
|
32476
|
-
|
|
32477
|
-
Provide the user with the necessary tracking information available from the
|
|
32478
|
-
CLI; omit unavailable fields rather than inventing them:
|
|
32479
|
-
|
|
32480
|
-
- target agent;
|
|
32481
|
-
- \`delegationId\`;
|
|
32482
|
-
- \`threadId\`;
|
|
32483
|
-
- \`turnId\`;
|
|
32484
|
-
- \`deepLink\`;
|
|
32485
|
-
- current or final status.
|
|
32745
|
+
Report the result returned by read or a completed wait, together with the target
|
|
32746
|
+
agent, status, and a labeled task link. Keep internal tracking IDs in tool calls.
|
|
32486
32747
|
`;
|
|
32487
32748
|
var CURRENT_DIGEST = createHash6("sha256").update(CODEXHOST_DELEGATION_SKILL).digest("hex");
|
|
32488
32749
|
function digest(value2) {
|
|
@@ -32501,8 +32762,8 @@ async function readOptional(filePath) {
|
|
|
32501
32762
|
}
|
|
32502
32763
|
}
|
|
32503
32764
|
async function atomicWrite(filePath, content) {
|
|
32504
|
-
await mkdir7(
|
|
32505
|
-
const temporaryPath =
|
|
32765
|
+
await mkdir7(path16.dirname(filePath), { recursive: true, mode: 448 });
|
|
32766
|
+
const temporaryPath = path16.join(path16.dirname(filePath), `.SKILL.md.${randomUUID9()}.tmp`);
|
|
32506
32767
|
const handle = await open5(temporaryPath, "wx", 384);
|
|
32507
32768
|
try {
|
|
32508
32769
|
await handle.writeFile(content, "utf8");
|
|
@@ -32519,8 +32780,8 @@ async function atomicWrite(filePath, content) {
|
|
|
32519
32780
|
async function installDelegationSkills(input = {}) {
|
|
32520
32781
|
const home = input.homeDirectory ?? os4.homedir();
|
|
32521
32782
|
const destinations = [
|
|
32522
|
-
|
|
32523
|
-
|
|
32783
|
+
path16.join(home, ".agents", SKILL_RELATIVE_PATH),
|
|
32784
|
+
path16.join(home, ".claude", SKILL_RELATIVE_PATH)
|
|
32524
32785
|
];
|
|
32525
32786
|
const knownDigests = /* @__PURE__ */ new Set([
|
|
32526
32787
|
CURRENT_DIGEST,
|
|
@@ -32587,7 +32848,7 @@ async function installDelegationSkills(input = {}) {
|
|
|
32587
32848
|
// packages/host-runtime/src/remote-control-app-server.ts
|
|
32588
32849
|
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
32589
32850
|
import { mkdir as mkdir8, open as open6, rename as rename6, rm as rm6 } from "node:fs/promises";
|
|
32590
|
-
import
|
|
32851
|
+
import path17 from "node:path";
|
|
32591
32852
|
|
|
32592
32853
|
// packages/host-runtime/src/remote-official-connection.ts
|
|
32593
32854
|
import net from "node:net";
|
|
@@ -32777,8 +33038,8 @@ var BRIDGE_READY_METHOD = "codexhost/remote-control-bridge/ready";
|
|
|
32777
33038
|
function absoluteEnvironmentPath2(environment, name, fallback, platform = process.platform) {
|
|
32778
33039
|
const value2 = environment[name] ?? fallback;
|
|
32779
33040
|
if (!value2) return null;
|
|
32780
|
-
if (
|
|
32781
|
-
return platform === "win32" &&
|
|
33041
|
+
if (path17.isAbsolute(value2)) return path17.normalize(value2);
|
|
33042
|
+
return platform === "win32" && path17.win32.isAbsolute(value2) ? path17.win32.normalize(value2) : null;
|
|
32782
33043
|
}
|
|
32783
33044
|
function nodeCompatibleWindowsPath(value2) {
|
|
32784
33045
|
if (value2.startsWith("\\\\?\\UNC\\")) return `\\\\${value2.slice(8)}`;
|
|
@@ -32792,13 +33053,13 @@ function remoteControlBridgePipePath(processId = process.pid, instanceId = rando
|
|
|
32792
33053
|
}
|
|
32793
33054
|
function remoteControlBridgeDescriptorPath(environment) {
|
|
32794
33055
|
const root = environment.LOCALAPPDATA;
|
|
32795
|
-
if (!root || !
|
|
32796
|
-
return
|
|
33056
|
+
if (!root || !path17.isAbsolute(root)) return null;
|
|
33057
|
+
return path17.join(path17.normalize(root), "codexhost", REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE);
|
|
32797
33058
|
}
|
|
32798
33059
|
async function publishRemoteControlAppServerDescriptor(plan) {
|
|
32799
|
-
const directory =
|
|
33060
|
+
const directory = path17.dirname(plan.descriptorPath);
|
|
32800
33061
|
await mkdir8(directory, { recursive: true, mode: 448 });
|
|
32801
|
-
const temporaryPath =
|
|
33062
|
+
const temporaryPath = path17.join(
|
|
32802
33063
|
directory,
|
|
32803
33064
|
`.${REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE}.${plan.descriptor.ownerPid}.${randomUUID10()}.tmp`
|
|
32804
33065
|
);
|
|
@@ -32891,14 +33152,14 @@ async function runRemoteControlAppServerBridge(input = {}) {
|
|
|
32891
33152
|
import { createServer as createServer2 } from "node:http";
|
|
32892
33153
|
import net2 from "node:net";
|
|
32893
33154
|
import { chmod as chmod3, lstat as lstat6, mkdir as mkdir10, rm as rm8 } from "node:fs/promises";
|
|
32894
|
-
import
|
|
33155
|
+
import path19 from "node:path";
|
|
32895
33156
|
import { PassThrough as PassThrough2 } from "node:stream";
|
|
32896
33157
|
|
|
32897
33158
|
// packages/host-runtime/src/remote-socket-lock.ts
|
|
32898
33159
|
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
32899
33160
|
import { chmod as chmod2, lstat as lstat5, mkdir as mkdir9, open as open7, readFile as readFile9, readdir as readdir4, rename as rename7, rm as rm7 } from "node:fs/promises";
|
|
32900
33161
|
import { uptime } from "node:os";
|
|
32901
|
-
import
|
|
33162
|
+
import path18 from "node:path";
|
|
32902
33163
|
import { setTimeout as delay4 } from "node:timers/promises";
|
|
32903
33164
|
var LOCK_RETRY_COUNT = 200;
|
|
32904
33165
|
var LOCK_RETRY_DELAY_MS = 25;
|
|
@@ -32972,7 +33233,7 @@ async function readLockEntrySnapshot(filePath) {
|
|
|
32972
33233
|
source,
|
|
32973
33234
|
identity: { dev: metadata.dev, ino: metadata.ino },
|
|
32974
33235
|
mtimeMs: metadata.mtimeMs,
|
|
32975
|
-
record: record3 &&
|
|
33236
|
+
record: record3 && path18.basename(filePath) === lockEntryName(record3.ownerToken) ? record3 : null
|
|
32976
33237
|
};
|
|
32977
33238
|
}
|
|
32978
33239
|
function lockEntryIsAbandoned(snapshot) {
|
|
@@ -32993,7 +33254,7 @@ async function readLockEntryCatalog(lockDirectory) {
|
|
|
32993
33254
|
let unsettled = false;
|
|
32994
33255
|
for (const name of names) {
|
|
32995
33256
|
if (!name.startsWith(LOCK_ENTRY_PREFIX) || !name.endsWith(LOCK_ENTRY_SUFFIX)) continue;
|
|
32996
|
-
const snapshot = await readLockEntrySnapshot(
|
|
33257
|
+
const snapshot = await readLockEntrySnapshot(path18.join(lockDirectory, name));
|
|
32997
33258
|
if (snapshot === null) continue;
|
|
32998
33259
|
if (lockEntryIsAbandoned(snapshot)) {
|
|
32999
33260
|
if (!await removeAbandonedLockEntry(snapshot)) unsettled = true;
|
|
@@ -33021,7 +33282,7 @@ async function preparePrivateLockDirectory(lockDirectory) {
|
|
|
33021
33282
|
await chmod2(lockDirectory, 448);
|
|
33022
33283
|
}
|
|
33023
33284
|
async function writeLockRecordAtomic(lockDirectory, entryPath, record3) {
|
|
33024
|
-
const temporary =
|
|
33285
|
+
const temporary = path18.join(lockDirectory, `.tmp-${record3.ownerToken}-${randomUUID11()}`);
|
|
33025
33286
|
const handle = await open7(temporary, "wx", 384);
|
|
33026
33287
|
try {
|
|
33027
33288
|
await handle.writeFile(`${JSON.stringify(record3)}
|
|
@@ -33097,7 +33358,7 @@ async function withRemoteAppServerSocketInitializationLock(socketPath, action) {
|
|
|
33097
33358
|
const lockDirectory = `${socketPath}.initializers`;
|
|
33098
33359
|
await preparePrivateLockDirectory(lockDirectory);
|
|
33099
33360
|
const ownerToken = randomUUID11();
|
|
33100
|
-
const entryPath =
|
|
33361
|
+
const entryPath = path18.join(lockDirectory, lockEntryName(ownerToken));
|
|
33101
33362
|
const baseRecord = {
|
|
33102
33363
|
version: 2,
|
|
33103
33364
|
ownerToken,
|
|
@@ -33271,14 +33532,14 @@ function remoteAppServerSocketPath(environment, listenUrl = "unix://") {
|
|
|
33271
33532
|
throw new Error("Remote app-server listener must use a Unix URL");
|
|
33272
33533
|
}
|
|
33273
33534
|
const explicit = listenUrl.slice("unix://".length);
|
|
33274
|
-
if (explicit.length > 0) return
|
|
33275
|
-
const codexHome = environment.CODEX_HOME ?? (environment.HOME ?
|
|
33535
|
+
if (explicit.length > 0) return path19.posix.resolve(decodeURIComponent(explicit));
|
|
33536
|
+
const codexHome = environment.CODEX_HOME ?? (environment.HOME ? path19.posix.join(environment.HOME, ".codex") : void 0);
|
|
33276
33537
|
if (!codexHome)
|
|
33277
33538
|
throw new Error("CODEX_HOME or HOME is required for the remote app-server socket");
|
|
33278
|
-
return
|
|
33539
|
+
return path19.posix.join(codexHome, "app-server-control", "app-server-control.sock");
|
|
33279
33540
|
}
|
|
33280
33541
|
function officialListenerArgumentsForRemoteListener(arguments_2, socketPath) {
|
|
33281
|
-
if (!
|
|
33542
|
+
if (!path19.posix.isAbsolute(socketPath)) {
|
|
33282
33543
|
throw new Error("Shared official app-server socket path must be absolute");
|
|
33283
33544
|
}
|
|
33284
33545
|
if (remoteUnixListenerUrl(arguments_2) === null) {
|
|
@@ -33389,7 +33650,7 @@ async function removeStaleSocket(socketPath) {
|
|
|
33389
33650
|
await rm8(socketPath, { force: true });
|
|
33390
33651
|
}
|
|
33391
33652
|
async function prepareRemoteAppServerSocketDirectory(socketPath) {
|
|
33392
|
-
const socketDirectory =
|
|
33653
|
+
const socketDirectory = path19.dirname(socketPath);
|
|
33393
33654
|
const existing = await lstat6(socketDirectory).catch((error51) => {
|
|
33394
33655
|
if (error51.code === "ENOENT") return null;
|
|
33395
33656
|
throw error51;
|
|
@@ -33596,18 +33857,18 @@ function createRemoteAppServerWebSocketListener(input) {
|
|
|
33596
33857
|
import { spawn as spawn4 } from "node:child_process";
|
|
33597
33858
|
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
33598
33859
|
import { lstat as lstat7, rm as rm9 } from "node:fs/promises";
|
|
33599
|
-
import
|
|
33860
|
+
import path20 from "node:path";
|
|
33600
33861
|
var DEFAULT_CLOSE_TIMEOUT_MS = 2e3;
|
|
33601
33862
|
var DEFAULT_LISTEN_TIMEOUT_MS = 1e4;
|
|
33602
33863
|
function remoteOfficialAppServerSocketPath(desktopControlSocketPath, token = randomUUID12()) {
|
|
33603
|
-
if (!
|
|
33864
|
+
if (!path20.posix.isAbsolute(desktopControlSocketPath)) {
|
|
33604
33865
|
throw new Error("Desktop control socket path must be absolute");
|
|
33605
33866
|
}
|
|
33606
33867
|
if (!/^[A-Za-z0-9-]+$/u.test(token) || !/[A-Za-z0-9]/u.test(token)) {
|
|
33607
33868
|
throw new Error("Shared official app-server socket token is invalid");
|
|
33608
33869
|
}
|
|
33609
33870
|
const compactToken = token.replaceAll("-", "").slice(0, 15);
|
|
33610
|
-
return
|
|
33871
|
+
return path20.posix.join(path20.posix.dirname(desktopControlSocketPath), `.c-${compactToken}.sock`);
|
|
33611
33872
|
}
|
|
33612
33873
|
function errorMessage5(error51) {
|
|
33613
33874
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
@@ -34074,9 +34335,9 @@ function hasLauncherManagedUpdateRuntime(environment, hostRuntimePath) {
|
|
|
34074
34335
|
if (!environment[UPDATE_RUNTIME_ENV.launcherPid]) return false;
|
|
34075
34336
|
const npmPackageRoot = environment[UPDATE_RUNTIME_ENV.npmPackageRoot];
|
|
34076
34337
|
if (!npmPackageRoot || !hostRuntimePath) return true;
|
|
34077
|
-
if (!
|
|
34078
|
-
const runtimePackageRoot =
|
|
34079
|
-
return
|
|
34338
|
+
if (!path21.isAbsolute(npmPackageRoot) || !path21.isAbsolute(hostRuntimePath)) return false;
|
|
34339
|
+
const runtimePackageRoot = path21.dirname(path21.dirname(path21.normalize(hostRuntimePath)));
|
|
34340
|
+
return path21.relative(path21.normalize(npmPackageRoot), runtimePackageRoot) === "";
|
|
34080
34341
|
}
|
|
34081
34342
|
function requiredRuntimeConfiguration(environment) {
|
|
34082
34343
|
const stockCodexPath = environment[STOCK_CODEX_PATH_ENV];
|
|
@@ -34157,19 +34418,15 @@ async function runHostRuntime(input) {
|
|
|
34157
34418
|
const officialPlan = createRemoteControlOfficialAppServerPlan(
|
|
34158
34419
|
remoteControlPlan.officialArguments
|
|
34159
34420
|
);
|
|
34160
|
-
const
|
|
34161
|
-
|
|
34162
|
-
|
|
34163
|
-
|
|
34164
|
-
|
|
34165
|
-
|
|
34166
|
-
|
|
34167
|
-
|
|
34168
|
-
|
|
34169
|
-
throw new Error("Shared official app-server endpoint is unavailable");
|
|
34170
|
-
}
|
|
34171
|
-
return createRemoteOfficialAppServerConnection(officialEndpoint);
|
|
34172
|
-
};
|
|
34421
|
+
const officialListeners = new AccountOfficialListeners(
|
|
34422
|
+
(account) => createLoopbackOfficialAppServerListener({
|
|
34423
|
+
stockCodexPath,
|
|
34424
|
+
arguments: officialPlan.listenerArguments,
|
|
34425
|
+
environment: officialAccountEnvironment(delegationEnvironment, account),
|
|
34426
|
+
diagnosticOutput: process.stderr
|
|
34427
|
+
})
|
|
34428
|
+
);
|
|
34429
|
+
const createOfficialConnection = async (account) => createRemoteOfficialAppServerConnection(await officialListeners.endpoint(account));
|
|
34173
34430
|
const mappingStore = createProductionExternalThreadStore(delegationEnvironment);
|
|
34174
34431
|
await mappingStore.initialize();
|
|
34175
34432
|
const host = new AppServerHost({
|
|
@@ -34206,7 +34463,11 @@ async function runHostRuntime(input) {
|
|
|
34206
34463
|
}
|
|
34207
34464
|
});
|
|
34208
34465
|
try {
|
|
34209
|
-
|
|
34466
|
+
await officialListeners.endpoint({
|
|
34467
|
+
codexHome: path21.resolve(
|
|
34468
|
+
delegationEnvironment.CODEX_HOME ?? path21.join(homedir(), ".codex")
|
|
34469
|
+
)
|
|
34470
|
+
});
|
|
34210
34471
|
await listener.listen();
|
|
34211
34472
|
await publishRemoteControlAppServerDescriptor(remoteControlPlan);
|
|
34212
34473
|
return await host.run();
|
|
@@ -34215,7 +34476,7 @@ async function runHostRuntime(input) {
|
|
|
34215
34476
|
await listener.close();
|
|
34216
34477
|
} finally {
|
|
34217
34478
|
try {
|
|
34218
|
-
await
|
|
34479
|
+
await officialListeners.close();
|
|
34219
34480
|
} finally {
|
|
34220
34481
|
await mappingStore.close();
|
|
34221
34482
|
}
|
|
@@ -34320,7 +34581,7 @@ import {
|
|
|
34320
34581
|
stat as stat4,
|
|
34321
34582
|
writeFile as writeFile5
|
|
34322
34583
|
} from "node:fs/promises";
|
|
34323
|
-
import
|
|
34584
|
+
import path22 from "node:path";
|
|
34324
34585
|
var MANIFEST_FORMAT = 1;
|
|
34325
34586
|
var WRAPPER_MARKER = "# codexhost remote SSH wrapper v1";
|
|
34326
34587
|
var PROFILE_START = "# >>> codexhost remote SSH >>>";
|
|
@@ -34331,25 +34592,25 @@ function resolvePaths(options2) {
|
|
|
34331
34592
|
if (!configuredHome) {
|
|
34332
34593
|
throw new Error("A non-root HOME is required for remote Host installation");
|
|
34333
34594
|
}
|
|
34334
|
-
const home =
|
|
34335
|
-
if (!home || home ===
|
|
34595
|
+
const home = path22.resolve(configuredHome);
|
|
34596
|
+
if (!home || home === path22.parse(home).root) {
|
|
34336
34597
|
throw new Error("A non-root HOME is required for remote Host installation");
|
|
34337
34598
|
}
|
|
34338
|
-
const installRoot =
|
|
34339
|
-
const profilePath =
|
|
34340
|
-
options2.profilePath ??
|
|
34599
|
+
const installRoot = path22.resolve(options2.installRoot ?? path22.join(home, ".codexhost", "remote"));
|
|
34600
|
+
const profilePath = path22.resolve(
|
|
34601
|
+
options2.profilePath ?? path22.join(
|
|
34341
34602
|
home,
|
|
34342
|
-
|
|
34603
|
+
path22.basename(environment.SHELL ?? "") === "zsh" ? ".zshenv" : path22.basename(environment.SHELL ?? "") === "bash" ? ".bashrc" : ".profile"
|
|
34343
34604
|
)
|
|
34344
34605
|
);
|
|
34345
|
-
const binDirectory =
|
|
34606
|
+
const binDirectory = path22.join(installRoot, "bin");
|
|
34346
34607
|
return {
|
|
34347
34608
|
home,
|
|
34348
34609
|
installRoot,
|
|
34349
34610
|
binDirectory,
|
|
34350
|
-
wrapperPath:
|
|
34351
|
-
manifestPath:
|
|
34352
|
-
dataDirectory:
|
|
34611
|
+
wrapperPath: path22.join(binDirectory, "codex"),
|
|
34612
|
+
manifestPath: path22.join(installRoot, "manifest.json"),
|
|
34613
|
+
dataDirectory: path22.join(installRoot, "data"),
|
|
34353
34614
|
profilePath
|
|
34354
34615
|
};
|
|
34355
34616
|
}
|
|
@@ -34368,7 +34629,7 @@ async function fileSha256(filePath) {
|
|
|
34368
34629
|
return createHash7("sha256").update(await readFile10(filePath)).digest("hex");
|
|
34369
34630
|
}
|
|
34370
34631
|
async function executable(filePath, label) {
|
|
34371
|
-
const absolute =
|
|
34632
|
+
const absolute = path22.resolve(filePath);
|
|
34372
34633
|
try {
|
|
34373
34634
|
if (!(await stat4(absolute)).isFile()) throw new Error("not a regular file");
|
|
34374
34635
|
await access(absolute, fsConstants.X_OK);
|
|
@@ -34378,7 +34639,7 @@ async function executable(filePath, label) {
|
|
|
34378
34639
|
return absolute;
|
|
34379
34640
|
}
|
|
34380
34641
|
async function existingFile(filePath, label) {
|
|
34381
|
-
const absolute =
|
|
34642
|
+
const absolute = path22.resolve(filePath);
|
|
34382
34643
|
try {
|
|
34383
34644
|
const metadata = await stat4(absolute);
|
|
34384
34645
|
if (!metadata.isFile()) throw new Error("not a regular file");
|
|
@@ -34388,9 +34649,9 @@ async function existingFile(filePath, label) {
|
|
|
34388
34649
|
return absolute;
|
|
34389
34650
|
}
|
|
34390
34651
|
async function discoverExecutable(name, environment) {
|
|
34391
|
-
for (const directory of (environment.PATH ?? "").split(
|
|
34652
|
+
for (const directory of (environment.PATH ?? "").split(path22.delimiter)) {
|
|
34392
34653
|
if (!directory) continue;
|
|
34393
|
-
const candidate =
|
|
34654
|
+
const candidate = path22.resolve(directory, name);
|
|
34394
34655
|
try {
|
|
34395
34656
|
await access(candidate, fsConstants.X_OK);
|
|
34396
34657
|
return candidate;
|
|
@@ -34401,10 +34662,10 @@ async function discoverExecutable(name, environment) {
|
|
|
34401
34662
|
return null;
|
|
34402
34663
|
}
|
|
34403
34664
|
async function writeAtomic(filePath, contents, mode) {
|
|
34404
|
-
await mkdir11(
|
|
34405
|
-
const temporary =
|
|
34406
|
-
|
|
34407
|
-
`.${
|
|
34665
|
+
await mkdir11(path22.dirname(filePath), { recursive: true, mode: 448 });
|
|
34666
|
+
const temporary = path22.join(
|
|
34667
|
+
path22.dirname(filePath),
|
|
34668
|
+
`.${path22.basename(filePath)}.${process.pid}.${randomUUID13()}.tmp`
|
|
34408
34669
|
);
|
|
34409
34670
|
try {
|
|
34410
34671
|
if (typeof contents === "string") {
|
|
@@ -34425,10 +34686,10 @@ async function writeAtomic(filePath, contents, mode) {
|
|
|
34425
34686
|
}
|
|
34426
34687
|
}
|
|
34427
34688
|
async function writeAtomicExecutable(filePath, sourcePath) {
|
|
34428
|
-
await mkdir11(
|
|
34429
|
-
const temporary =
|
|
34430
|
-
|
|
34431
|
-
`.${
|
|
34689
|
+
await mkdir11(path22.dirname(filePath), { recursive: true, mode: 448 });
|
|
34690
|
+
const temporary = path22.join(
|
|
34691
|
+
path22.dirname(filePath),
|
|
34692
|
+
`.${path22.basename(filePath)}.${process.pid}.${randomUUID13()}.tmp`
|
|
34432
34693
|
);
|
|
34433
34694
|
try {
|
|
34434
34695
|
await copyFile3(sourcePath, temporary);
|
|
@@ -34469,8 +34730,8 @@ function removeManagedProfileBlock(contents) {
|
|
|
34469
34730
|
function installManagedProfileBlock(contents, manifest) {
|
|
34470
34731
|
const base = removeManagedProfileBlock(contents);
|
|
34471
34732
|
const environment = [
|
|
34472
|
-
`export CODEX_INSTALL_DIR=${shellQuote(
|
|
34473
|
-
`export PATH=${shellQuote(
|
|
34733
|
+
`export CODEX_INSTALL_DIR=${shellQuote(path22.dirname(manifest.wrapperPath))}`,
|
|
34734
|
+
`export PATH=${shellQuote(path22.dirname(manifest.wrapperPath))}:${shellQuote(path22.dirname(manifest.nodePath))}:${shellQuote(path22.dirname(manifest.stockCodexPath))}:"\${PATH:-/usr/local/bin:/usr/bin:/bin}"`,
|
|
34474
34735
|
`export CODEXHOST_STOCK_CODEX_PATH=${shellQuote(manifest.stockCodexPath)}`,
|
|
34475
34736
|
`export CODEXHOST_HOST_NODE_PATH=${shellQuote(manifest.nodePath)}`,
|
|
34476
34737
|
`export CODEXHOST_HOST_RUNTIME_PATH=${shellQuote(manifest.hostRuntimePath)}`,
|
|
@@ -34487,7 +34748,7 @@ function installManagedProfileBlock(contents, manifest) {
|
|
|
34487
34748
|
PROFILE_END,
|
|
34488
34749
|
""
|
|
34489
34750
|
].join("\n");
|
|
34490
|
-
if (
|
|
34751
|
+
if (path22.basename(manifest.profilePath) === ".bashrc") return `${block}${base}`;
|
|
34491
34752
|
const separator = base.length > 0 && !base.endsWith("\n") ? "\n" : "";
|
|
34492
34753
|
return `${base}${separator}${block}`;
|
|
34493
34754
|
}
|
|
@@ -34552,9 +34813,9 @@ async function readManifest(filePath) {
|
|
|
34552
34813
|
];
|
|
34553
34814
|
const optionalPaths = ["claudeCommand", "profileBackupPath"];
|
|
34554
34815
|
if (manifest.format !== MANIFEST_FORMAT || Object.keys(manifest).some((key) => !allowed.has(key)) || requiredPaths.some(
|
|
34555
|
-
(key) => typeof manifest[key] !== "string" || !
|
|
34816
|
+
(key) => typeof manifest[key] !== "string" || !path22.isAbsolute(manifest[key])
|
|
34556
34817
|
) || optionalPaths.some(
|
|
34557
|
-
(key) => manifest[key] !== void 0 && (typeof manifest[key] !== "string" || !
|
|
34818
|
+
(key) => manifest[key] !== void 0 && (typeof manifest[key] !== "string" || !path22.isAbsolute(manifest[key]))
|
|
34558
34819
|
) || manifest.entrypointSha256 !== void 0 && (typeof manifest.entrypointSha256 !== "string" || !/^[a-f0-9]{64}$/u.test(manifest.entrypointSha256))) {
|
|
34559
34820
|
throw new Error("Remote Host manifest has an unsupported format");
|
|
34560
34821
|
}
|
|
@@ -34783,7 +35044,7 @@ async function uninstallRemoteHost(options2) {
|
|
|
34783
35044
|
import { spawn as spawn5 } from "node:child_process";
|
|
34784
35045
|
import { stat as stat5 } from "node:fs/promises";
|
|
34785
35046
|
import net3 from "node:net";
|
|
34786
|
-
import
|
|
35047
|
+
import path23 from "node:path";
|
|
34787
35048
|
import { Duplex } from "node:stream";
|
|
34788
35049
|
var CODEXHOST_STATUS_METHOD = "codexhost/update/status";
|
|
34789
35050
|
var DIRECT_PROBE_TIMEOUT_MS = 5e3;
|
|
@@ -34802,9 +35063,9 @@ function classifyRemoteHostProbeResponse(response, socketPath) {
|
|
|
34802
35063
|
}
|
|
34803
35064
|
var lifecycleDependencyOverrides = {};
|
|
34804
35065
|
function socketPathFor(environment) {
|
|
34805
|
-
const codexHome = environment.CODEX_HOME ?? (environment.HOME ?
|
|
35066
|
+
const codexHome = environment.CODEX_HOME ?? (environment.HOME ? path23.join(environment.HOME, ".codex") : void 0);
|
|
34806
35067
|
if (!codexHome) throw new Error("CODEX_HOME or HOME is required for remote Host lifecycle");
|
|
34807
|
-
return
|
|
35068
|
+
return path23.join(codexHome, "app-server-control", "app-server-control.sock");
|
|
34808
35069
|
}
|
|
34809
35070
|
async function defaultSocketExists(socketPath) {
|
|
34810
35071
|
const metadata = await stat5(socketPath).catch((error51) => {
|
|
@@ -34934,7 +35195,7 @@ function installedManifest(status) {
|
|
|
34934
35195
|
function managedEnvironment(manifest, environment) {
|
|
34935
35196
|
return {
|
|
34936
35197
|
...environment,
|
|
34937
|
-
CODEX_INSTALL_DIR:
|
|
35198
|
+
CODEX_INSTALL_DIR: path23.dirname(manifest.wrapperPath),
|
|
34938
35199
|
CODEXHOST_STOCK_CODEX_PATH: manifest.stockCodexPath,
|
|
34939
35200
|
CODEXHOST_HOST_NODE_PATH: manifest.nodePath,
|
|
34940
35201
|
CODEXHOST_HOST_RUNTIME_PATH: manifest.hostRuntimePath,
|
|
@@ -34942,7 +35203,7 @@ function managedEnvironment(manifest, environment) {
|
|
|
34942
35203
|
CODEXHOST_DEFAULT_AGENT: "codex",
|
|
34943
35204
|
CODEXHOST_REMOTE_SSH_MANAGED: "1",
|
|
34944
35205
|
...manifest.claudeCommand ? { CODEXHOST_CLAUDE_COMMAND: manifest.claudeCommand } : {},
|
|
34945
|
-
PATH: `${
|
|
35206
|
+
PATH: `${path23.dirname(manifest.wrapperPath)}${path23.delimiter}${path23.dirname(manifest.stockCodexPath)}${path23.delimiter}${environment.PATH ?? "/usr/bin:/bin"}`
|
|
34946
35207
|
};
|
|
34947
35208
|
}
|
|
34948
35209
|
async function defaultRunTerminator(manifest, socketPath, role, environment) {
|
|
@@ -35284,19 +35545,19 @@ function consumeBrokerFrames(socket, onFrame, onError) {
|
|
|
35284
35545
|
|
|
35285
35546
|
// packages/harness-broker/dist/paths.js
|
|
35286
35547
|
import os5 from "node:os";
|
|
35287
|
-
import
|
|
35548
|
+
import path24 from "node:path";
|
|
35288
35549
|
var HARNESS_BROKER_DESCRIPTOR_ENV = "CODEXHOST_CLAUDE_BROKER_DESCRIPTOR";
|
|
35289
35550
|
var HARNESS_BROKER_DESCRIPTOR_FILE = "claude-code-broker-v1.json";
|
|
35290
35551
|
var HARNESS_BROKER_SOCKET_FILE = "claude-code-broker-v1.sock";
|
|
35291
35552
|
function defaultHarnessBrokerDirectory(environment = process.env) {
|
|
35292
35553
|
const home = environment.HOME || os5.homedir();
|
|
35293
|
-
return
|
|
35554
|
+
return path24.join(home, ".codexhost", "harness-broker");
|
|
35294
35555
|
}
|
|
35295
35556
|
function defaultHarnessBrokerDescriptorPath(environment = process.env) {
|
|
35296
|
-
return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ??
|
|
35557
|
+
return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ?? path24.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_DESCRIPTOR_FILE);
|
|
35297
35558
|
}
|
|
35298
35559
|
function defaultHarnessBrokerSocketPath(environment = process.env) {
|
|
35299
|
-
return
|
|
35560
|
+
return path24.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_SOCKET_FILE);
|
|
35300
35561
|
}
|
|
35301
35562
|
|
|
35302
35563
|
// packages/harness-broker/dist/validation.js
|
|
@@ -35311,6 +35572,8 @@ var createSchema = external_exports.object({
|
|
|
35311
35572
|
}).strict();
|
|
35312
35573
|
var resumeSchema = external_exports.object({
|
|
35313
35574
|
kind: external_exports.literal("resume"),
|
|
35575
|
+
model: harnessModelRefSchema.optional(),
|
|
35576
|
+
thinkingOptionId: harnessThinkingOptionIdSchema.optional(),
|
|
35314
35577
|
nativeRef: nativeSessionRefSchema,
|
|
35315
35578
|
cwd: cwdSchema,
|
|
35316
35579
|
knownTurnRefs: external_exports.array(nativeTurnRefSchema).max(1e5).optional()
|
|
@@ -35323,6 +35586,9 @@ var forkSchema = external_exports.object({
|
|
|
35323
35586
|
}).strict();
|
|
35324
35587
|
var rollbackSchema = external_exports.object({
|
|
35325
35588
|
kind: external_exports.literal("rollbackLastTurn"),
|
|
35589
|
+
model: harnessModelRefSchema.optional(),
|
|
35590
|
+
thinkingOptionId: harnessThinkingOptionIdSchema.optional(),
|
|
35591
|
+
permissionModeId: harnessPermissionModeIdSchema.optional(),
|
|
35326
35592
|
sourceRef: nativeSessionRefSchema,
|
|
35327
35593
|
cwd: cwdSchema
|
|
35328
35594
|
}).strict();
|
|
@@ -35517,7 +35783,7 @@ var harnessOutputSchema = external_exports.custom((value2) => {
|
|
|
35517
35783
|
import { randomBytes as randomBytes2, randomUUID as randomUUID14 } from "node:crypto";
|
|
35518
35784
|
import { chmod as chmod5, lstat as lstat9, mkdir as mkdir12, open as open8, readFile as readFile11, rename as rename9, rm as rm11 } from "node:fs/promises";
|
|
35519
35785
|
import net4, {} from "node:net";
|
|
35520
|
-
import
|
|
35786
|
+
import path25 from "node:path";
|
|
35521
35787
|
function harnessError(message, retryable = true) {
|
|
35522
35788
|
return { code: "unavailable", message, retryable, stage: "harnessBroker" };
|
|
35523
35789
|
}
|
|
@@ -35642,13 +35908,13 @@ async function startHarnessBrokerServer(input) {
|
|
|
35642
35908
|
if (input.adapter.harnessId !== "claude-code") {
|
|
35643
35909
|
throw new Error("Harness broker accepts only the claude-code adapter");
|
|
35644
35910
|
}
|
|
35645
|
-
if (process.platform !== "win32" &&
|
|
35911
|
+
if (process.platform !== "win32" && path25.dirname(input.descriptorPath) !== path25.dirname(input.socketPath)) {
|
|
35646
35912
|
throw new Error("Harness broker descriptor and socket must share one private directory");
|
|
35647
35913
|
}
|
|
35648
35914
|
if (process.platform === "darwin" && Buffer.byteLength(input.socketPath) > 103) {
|
|
35649
35915
|
throw new Error("Harness broker Unix socket path is too long for macOS");
|
|
35650
35916
|
}
|
|
35651
|
-
await privateDirectory(
|
|
35917
|
+
await privateDirectory(path25.dirname(input.descriptorPath));
|
|
35652
35918
|
await assertNoLiveDescriptor(input.descriptorPath);
|
|
35653
35919
|
if (process.platform !== "win32")
|
|
35654
35920
|
await prepareUnixSocketPath(input.socketPath);
|