@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.
@@ -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
- if (group === "delegate" && (!command || command === "--help" || command === "help") || group === "--help" || group === "-h") {
3874
- output.write(DELEGATION_HELP);
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
- writeJson(
3895
- output,
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
- writeJson(
3931
- output,
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
- writeJson(
3967
- output,
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
- writeJson(
3991
- output,
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
- writeJson(
4035
- output,
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
- writeJson(
4065
- output,
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 path20 from "node:path";
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" ? "codexhost-updater.exe" : "codexhost-updater");
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, `codexhost-updater${executableSuffix}`);
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, path25) {
5962
- if (!path25)
6145
+ function getElementAtPath(obj, path26) {
6146
+ if (!path26)
5963
6147
  return obj;
5964
- return path25.reduce((acc, key) => acc?.[key], obj);
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(path25, issues) {
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(path25);
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, path25 = []) => {
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 }, [...path25, ...issue2.path]));
6711
+ issue2.errors.map((issues) => processError({ issues }, [...path26, ...issue2.path]));
6528
6712
  } else if (issue2.code === "invalid_key") {
6529
- processError({ issues: issue2.issues }, [...path25, ...issue2.path]);
6713
+ processError({ issues: issue2.issues }, [...path26, ...issue2.path]);
6530
6714
  } else if (issue2.code === "invalid_element") {
6531
- processError({ issues: issue2.issues }, [...path25, ...issue2.path]);
6715
+ processError({ issues: issue2.issues }, [...path26, ...issue2.path]);
6532
6716
  } else {
6533
- const fullpath = [...path25, ...issue2.path];
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, path25 = []) => {
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 }, [...path25, ...issue2.path]));
6748
+ issue2.errors.map((issues) => processError({ issues }, [...path26, ...issue2.path]));
6565
6749
  } else if (issue2.code === "invalid_key") {
6566
- processError({ issues: issue2.issues }, [...path25, ...issue2.path]);
6750
+ processError({ issues: issue2.issues }, [...path26, ...issue2.path]);
6567
6751
  } else if (issue2.code === "invalid_element") {
6568
- processError({ issues: issue2.issues }, [...path25, ...issue2.path]);
6752
+ processError({ issues: issue2.issues }, [...path26, ...issue2.path]);
6569
6753
  } else {
6570
- const fullpath = [...path25, ...issue2.path];
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 path25 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
6603
- for (const seg of path25) {
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 path25 = ref.slice(1).split("/").filter(Boolean);
19296
- if (path25.length === 0) {
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 (path25[0] === defsKey) {
19301
- const key = path25[1];
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: path25, kind, unifiedDiff }) => ({
22333
- path: path25,
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 { startedAtMs, completedAtMs } = snapshot;
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: startedAtMs === void 0 ? null : Math.floor(startedAtMs / 1e3),
22660
- completedAt: completedAtMs === void 0 ? null : Math.floor(completedAtMs / 1e3),
22661
- durationMs: startedAtMs === void 0 || completedAtMs === void 0 ? null : Math.max(0, completedAtMs - startedAtMs),
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 path25 = optionalText(params, "path", { allowEmpty: true });
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
- ...path25 ? { path: path25 } : {},
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" ? visible.slice(offset, offset + options2.limit) : void 0;
26249
- const nextOffset = options2.view === "messages" ? offset + (page?.length ?? 0) : visible.length;
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 ? { messages: 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?.trim())
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
- return this.#startOfficial({ ...input, parentThreadId, cwd: selectedCwd });
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 this.#result(delegationId, childThreadId, turnId, targetHarnessId, "running", {
26491
- requested: {
26492
- ...input.model ? { model: input.model } : {},
26493
- ...input.thinkingOptionId ? { thinkingOptionId: input.thinkingOptionId } : {}
26494
- },
26495
- effective: {
26496
- ...thread.stateObserver.state.effectiveModel ? { effectiveModel: thread.stateObserver.state.effectiveModel } : {},
26497
- ...thread.stateObserver.state.resolvedModelLabel ? { resolvedModelLabel: thread.stateObserver.state.resolvedModelLabel } : {},
26498
- ...thread.stateObserver.state.effectiveThinkingOptionId ? { effectiveThinkingOptionId: thread.stateObserver.state.effectiveThinkingOptionId } : {}
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 (!record3) return { harnessId: "codex" };
26730
- return { harnessId: record3.harnessId, cwd: record3.cwd };
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 this.#result(
26736
- delegation.delegationId,
26737
- delegation.childHostThreadId,
26738
- turnId,
26739
- delegation.targetHarnessId,
26740
- delegation.status
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 path25 = [];
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 path25) resolved.set(record3.hostThreadId, known);
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
- path25.push(current);
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 path25) resolved.set(record3.hostThreadId, root);
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 path14 from "node:path";
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 path13 from "node:path";
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 || !path13.isAbsolute(launcher)) return void 0;
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
- path14.join(path14.dirname(fileURLToPath(hostRuntimeUrl)), "plugins"),
32287
- environment[HARNESS_PLUGIN_DIRECTORY_ENV] ?? path14.join(
32288
- environment.CODEXHOST_DATA_DIR ? path14.resolve(environment.CODEXHOST_DATA_DIR) : path14.join(os3.homedir(), ".codexhost"),
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 path15 from "node:path";
32414
- var SKILL_VERSION = 5;
32415
- var SKILL_RELATIVE_PATH = path15.join("skills", "codexhost-delegation", "SKILL.md");
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
- Treat its output as the sole authoritative source for:
32442
-
32443
- - available commands;
32444
- - command parameters;
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
- Do not construct commands, parameters, or Harness IDs from memory.
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
- When the result is needed, explicitly read the target Thread. Report only the
32475
- visible result returned by that Thread.
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(path15.dirname(filePath), { recursive: true, mode: 448 });
32505
- const temporaryPath = path15.join(path15.dirname(filePath), `.SKILL.md.${randomUUID9()}.tmp`);
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
- path15.join(home, ".agents", SKILL_RELATIVE_PATH),
32523
- path15.join(home, ".claude", SKILL_RELATIVE_PATH)
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 path16 from "node:path";
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 (path16.isAbsolute(value2)) return path16.normalize(value2);
32781
- return platform === "win32" && path16.win32.isAbsolute(value2) ? path16.win32.normalize(value2) : null;
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 || !path16.isAbsolute(root)) return null;
32796
- return path16.join(path16.normalize(root), "codexhost", REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE);
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 = path16.dirname(plan.descriptorPath);
33060
+ const directory = path17.dirname(plan.descriptorPath);
32800
33061
  await mkdir8(directory, { recursive: true, mode: 448 });
32801
- const temporaryPath = path16.join(
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 path18 from "node:path";
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 path17 from "node:path";
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 && path17.basename(filePath) === lockEntryName(record3.ownerToken) ? record3 : null
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(path17.join(lockDirectory, name));
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 = path17.join(lockDirectory, `.tmp-${record3.ownerToken}-${randomUUID11()}`);
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 = path17.join(lockDirectory, lockEntryName(ownerToken));
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 path18.posix.resolve(decodeURIComponent(explicit));
33275
- const codexHome = environment.CODEX_HOME ?? (environment.HOME ? path18.posix.join(environment.HOME, ".codex") : void 0);
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 path18.posix.join(codexHome, "app-server-control", "app-server-control.sock");
33539
+ return path19.posix.join(codexHome, "app-server-control", "app-server-control.sock");
33279
33540
  }
33280
33541
  function officialListenerArgumentsForRemoteListener(arguments_2, socketPath) {
33281
- if (!path18.posix.isAbsolute(socketPath)) {
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 = path18.dirname(socketPath);
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 path19 from "node:path";
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 (!path19.posix.isAbsolute(desktopControlSocketPath)) {
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 path19.posix.join(path19.posix.dirname(desktopControlSocketPath), `.c-${compactToken}.sock`);
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 (!path20.isAbsolute(npmPackageRoot) || !path20.isAbsolute(hostRuntimePath)) return false;
34078
- const runtimePackageRoot = path20.dirname(path20.dirname(path20.normalize(hostRuntimePath)));
34079
- return path20.relative(path20.normalize(npmPackageRoot), runtimePackageRoot) === "";
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 officialListener = createLoopbackOfficialAppServerListener({
34161
- stockCodexPath,
34162
- arguments: officialPlan.listenerArguments,
34163
- environment: officialEnvironment(delegationEnvironment),
34164
- diagnosticOutput: process.stderr
34165
- });
34166
- let officialEndpoint = null;
34167
- const createOfficialConnection = () => {
34168
- if (!officialEndpoint) {
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
- officialEndpoint = await officialListener.listen();
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 officialListener.close();
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 path21 from "node:path";
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 = path21.resolve(configuredHome);
34335
- if (!home || home === path21.parse(home).root) {
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 = path21.resolve(options2.installRoot ?? path21.join(home, ".codexhost", "remote"));
34339
- const profilePath = path21.resolve(
34340
- options2.profilePath ?? path21.join(
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
- path21.basename(environment.SHELL ?? "") === "zsh" ? ".zshenv" : path21.basename(environment.SHELL ?? "") === "bash" ? ".bashrc" : ".profile"
34603
+ path22.basename(environment.SHELL ?? "") === "zsh" ? ".zshenv" : path22.basename(environment.SHELL ?? "") === "bash" ? ".bashrc" : ".profile"
34343
34604
  )
34344
34605
  );
34345
- const binDirectory = path21.join(installRoot, "bin");
34606
+ const binDirectory = path22.join(installRoot, "bin");
34346
34607
  return {
34347
34608
  home,
34348
34609
  installRoot,
34349
34610
  binDirectory,
34350
- wrapperPath: path21.join(binDirectory, "codex"),
34351
- manifestPath: path21.join(installRoot, "manifest.json"),
34352
- dataDirectory: path21.join(installRoot, "data"),
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 = path21.resolve(filePath);
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 = path21.resolve(filePath);
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(path21.delimiter)) {
34652
+ for (const directory of (environment.PATH ?? "").split(path22.delimiter)) {
34392
34653
  if (!directory) continue;
34393
- const candidate = path21.resolve(directory, name);
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(path21.dirname(filePath), { recursive: true, mode: 448 });
34405
- const temporary = path21.join(
34406
- path21.dirname(filePath),
34407
- `.${path21.basename(filePath)}.${process.pid}.${randomUUID13()}.tmp`
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(path21.dirname(filePath), { recursive: true, mode: 448 });
34429
- const temporary = path21.join(
34430
- path21.dirname(filePath),
34431
- `.${path21.basename(filePath)}.${process.pid}.${randomUUID13()}.tmp`
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(path21.dirname(manifest.wrapperPath))}`,
34473
- `export PATH=${shellQuote(path21.dirname(manifest.wrapperPath))}:${shellQuote(path21.dirname(manifest.nodePath))}:${shellQuote(path21.dirname(manifest.stockCodexPath))}:"\${PATH:-/usr/local/bin:/usr/bin:/bin}"`,
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 (path21.basename(manifest.profilePath) === ".bashrc") return `${block}${base}`;
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" || !path21.isAbsolute(manifest[key])
34816
+ (key) => typeof manifest[key] !== "string" || !path22.isAbsolute(manifest[key])
34556
34817
  ) || optionalPaths.some(
34557
- (key) => manifest[key] !== void 0 && (typeof manifest[key] !== "string" || !path21.isAbsolute(manifest[key]))
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 path22 from "node:path";
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 ? path22.join(environment.HOME, ".codex") : void 0);
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 path22.join(codexHome, "app-server-control", "app-server-control.sock");
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: path22.dirname(manifest.wrapperPath),
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: `${path22.dirname(manifest.wrapperPath)}${path22.delimiter}${path22.dirname(manifest.stockCodexPath)}${path22.delimiter}${environment.PATH ?? "/usr/bin:/bin"}`
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 path23 from "node:path";
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 path23.join(home, ".codexhost", "harness-broker");
35554
+ return path24.join(home, ".codexhost", "harness-broker");
35294
35555
  }
35295
35556
  function defaultHarnessBrokerDescriptorPath(environment = process.env) {
35296
- return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ?? path23.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_DESCRIPTOR_FILE);
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 path23.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_SOCKET_FILE);
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 path24 from "node:path";
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" && path24.dirname(input.descriptorPath) !== path24.dirname(input.socketPath)) {
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(path24.dirname(input.descriptorPath));
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);