@openscout/scout 0.2.73 → 0.2.74

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.
Files changed (52) hide show
  1. package/bin/scoutd +0 -0
  2. package/dist/build-manifest.json +9 -0
  3. package/dist/client/assets/{RepoDiffViewer-D8gg36W3.js → RepoDiffViewer-CTXJvjIL.js} +1 -1
  4. package/dist/client/assets/{addon-fit-D4KdY-pj.js → addon-fit-3IrvLm2n.js} +1 -1
  5. package/dist/client/assets/{addon-webgl-Bo_tmKBp.js → addon-webgl-BgxIDUI-.js} +1 -1
  6. package/dist/client/assets/{arc.es-D0gujIKy.js → arc.es-Bh8P_xre.js} +1 -1
  7. package/dist/client/assets/c-BIGW1oBm.js +1 -0
  8. package/dist/client/assets/cpp-DIPi6g--.js +1 -0
  9. package/dist/client/assets/css-CLj8gQPS.js +1 -0
  10. package/dist/client/assets/dart-bE4Kk8sk.js +1 -0
  11. package/dist/client/assets/docker-BcOcwvcX.js +1 -0
  12. package/dist/client/assets/{embed-entry-CUVNwyB_.js → embed-entry-wAEtYUEM.js} +1 -1
  13. package/dist/client/assets/go-C27-OAKa.js +1 -0
  14. package/dist/client/assets/html-pp8916En.js +1 -0
  15. package/dist/client/assets/index-BK3mRYyN.js +272 -0
  16. package/dist/client/assets/index-Dm1ZQS9G.css +1 -0
  17. package/dist/client/assets/java-CylS5w8V.js +1 -0
  18. package/dist/client/assets/javascript-wDzz0qaB.js +1 -0
  19. package/dist/client/assets/json-Cp-IABpG.js +1 -0
  20. package/dist/client/assets/jsx-g9-lgVsj.js +1 -0
  21. package/dist/client/assets/kotlin-BdnUsdx6.js +1 -0
  22. package/dist/client/assets/make-CHLpvVh8.js +1 -0
  23. package/dist/client/assets/markdown-Cvjx9yec.js +1 -0
  24. package/dist/client/assets/objective-c-DXmwc3jG.js +1 -0
  25. package/dist/client/assets/proto-C7zT0LnQ.js +1 -0
  26. package/dist/client/assets/python-B6aJPvgy.js +1 -0
  27. package/dist/client/assets/ruby-B13GW9FM.js +1 -0
  28. package/dist/client/assets/rust-B1yitclQ.js +1 -0
  29. package/dist/client/assets/scss-D5BDwBP9.js +1 -0
  30. package/dist/client/assets/shellscript-Yzrsuije.js +1 -0
  31. package/dist/client/assets/sql-CRqJ_cUM.js +1 -0
  32. package/dist/client/assets/swift-D82vCrfD.js +1 -0
  33. package/dist/client/assets/toml-vGWfd6FD.js +1 -0
  34. package/dist/client/assets/tsx-COt5Ahok.js +1 -0
  35. package/dist/client/assets/typescript-BPQ3VLAy.js +1 -0
  36. package/dist/client/assets/wasm-CG6Dc4jp.js +1 -0
  37. package/dist/client/assets/xml-sdJ4AIDG.js +1 -0
  38. package/dist/client/assets/{xterm-RfflDFod.js → xterm-CoGJTxj9.js} +1 -1
  39. package/dist/client/assets/yaml-Buea-lGh.js +1 -0
  40. package/dist/client/index.html +2 -2
  41. package/dist/main.mjs +887 -584
  42. package/dist/node/main.mjs +115 -1
  43. package/dist/pairing-runtime-controller.mjs +2525 -895
  44. package/dist/runtime/base-daemon.mjs +77 -20
  45. package/dist/runtime/broker-daemon.mjs +1403 -705
  46. package/dist/runtime/broker-process-manager.mjs +29 -0
  47. package/dist/runtime/mesh-discover.mjs +29 -0
  48. package/dist/scout-control-plane-web.mjs +2970 -1116
  49. package/dist/scout-web-server.mjs +2970 -1116
  50. package/package.json +1 -1
  51. package/dist/client/assets/index-CRkjiso5.js +0 -257
  52. package/dist/client/assets/index-D_RX2cRb.css +0 -1
package/dist/main.mjs CHANGED
@@ -119,6 +119,7 @@ var init_actors = __esm(() => {
119
119
  "claude",
120
120
  "grok",
121
121
  "grok-acp",
122
+ "kimi",
122
123
  "flue",
123
124
  "cursor",
124
125
  "native",
@@ -3548,6 +3549,13 @@ var init_codex_executable = () => {};
3548
3549
  import { existsSync, mkdirSync, rmSync, writeFileSync } from "fs";
3549
3550
  import { homedir } from "os";
3550
3551
  import { join as join2 } from "path";
3552
+ function assertTestIsolatedUserData(operation, isolationEnvKey) {
3553
+ if (true)
3554
+ return;
3555
+ if (process.env[isolationEnvKey]?.trim())
3556
+ return;
3557
+ throw new Error(`Refusing to ${operation} while NODE_ENV=test without ${isolationEnvKey} set. ` + "Tests must isolate OpenScout user data in a temp directory (see prepareHome in onboarding.test.ts).");
3558
+ }
3551
3559
  function resolveOpenScoutSupportPaths() {
3552
3560
  const home = homedir();
3553
3561
  const supportDirectory = process.env.OPENSCOUT_SUPPORT_DIRECTORY ?? join2(home, "Library", "Application Support", "OpenScout");
@@ -3592,6 +3600,7 @@ function relayAgentLogsDirectory(agentId) {
3592
3600
  return localAgentLogsDirectory(agentId);
3593
3601
  }
3594
3602
  function ensureOpenScoutCleanSlateSync() {
3603
+ assertTestIsolatedUserData("reset the OpenScout support directory", "OPENSCOUT_SUPPORT_DIRECTORY");
3595
3604
  const paths = resolveOpenScoutSupportPaths();
3596
3605
  if (existsSync(paths.cutoverMarkerPath)) {
3597
3606
  return;
@@ -3693,6 +3702,17 @@ function mergeLaunch(base, override) {
3693
3702
  args: override?.args ?? base?.args ?? []
3694
3703
  };
3695
3704
  }
3705
+ function mergeSessionDefaults(base, override) {
3706
+ const defaultTransport = override?.defaultTransport ?? base?.defaultTransport;
3707
+ if (!defaultTransport)
3708
+ return;
3709
+ return {
3710
+ ...base ?? {},
3711
+ ...override ?? {},
3712
+ defaultTransport,
3713
+ fallbackTransports: override?.fallbackTransports ? [...override.fallbackTransports] : base?.fallbackTransports ? [...base.fallbackTransports] : undefined
3714
+ };
3715
+ }
3696
3716
  function formatRequirement(requirement) {
3697
3717
  if (requirement.label?.trim())
3698
3718
  return requirement.label.trim();
@@ -3753,6 +3773,10 @@ function createBuiltInHarnessCatalog() {
3753
3773
  } : undefined,
3754
3774
  launch: entry.launch ? { ...entry.launch, args: [...entry.launch.args] } : undefined,
3755
3775
  resume: entry.resume ? { ...entry.resume } : undefined,
3776
+ sessionDefaults: entry.sessionDefaults ? {
3777
+ ...entry.sessionDefaults,
3778
+ fallbackTransports: entry.sessionDefaults.fallbackTransports ? [...entry.sessionDefaults.fallbackTransports] : undefined
3779
+ } : undefined,
3756
3780
  resolveEnv: entry.resolveEnv ? [...entry.resolveEnv] : undefined,
3757
3781
  capabilities: [...entry.capabilities],
3758
3782
  metadata: entry.metadata ? { ...entry.metadata } : undefined
@@ -3770,6 +3794,7 @@ function mergeHarnessCatalogEntries(baseEntries, overrides = {}) {
3770
3794
  install: mergeInstall(entry.install, override.install),
3771
3795
  readiness: mergeReadiness(entry.readiness, override.readiness),
3772
3796
  launch: mergeLaunch(entry.launch, override.launch),
3797
+ sessionDefaults: mergeSessionDefaults(entry.sessionDefaults, override.sessionDefaults),
3773
3798
  resume: override.resume && entry.resume ? { ...entry.resume, ...override.resume } : entry.resume,
3774
3799
  tags: override.tags ? [...override.tags] : entry.tags,
3775
3800
  capabilities: override.capabilities ? [...override.capabilities] : entry.capabilities,
@@ -3800,6 +3825,7 @@ function mergeHarnessCatalogEntries(baseEntries, overrides = {}) {
3800
3825
  readiness: mergeReadiness(undefined, override.readiness),
3801
3826
  launch: mergeLaunch(undefined, override.launch),
3802
3827
  resume: override.resume?.command && override.resume?.sessionFlag ? { command: override.resume.command, sessionFlag: override.resume.sessionFlag, cwdFlag: override.resume.cwdFlag } : undefined,
3828
+ sessionDefaults: mergeSessionDefaults(undefined, override.sessionDefaults),
3803
3829
  resolveEnv: override.resolveEnv ? [...override.resolveEnv] : undefined,
3804
3830
  capabilities: [...override.capabilities],
3805
3831
  metadata: override.metadata ? { ...override.metadata } : undefined
@@ -3961,6 +3987,10 @@ var init_harness_catalog = __esm(() => {
3961
3987
  command: "claude",
3962
3988
  sessionFlag: "--resume"
3963
3989
  },
3990
+ sessionDefaults: {
3991
+ defaultTransport: "tmux",
3992
+ fallbackTransports: ["claude_stream_json"]
3993
+ },
3964
3994
  capabilities: ["chat", "invoke", "deliver", "summarize", "review"]
3965
3995
  },
3966
3996
  {
@@ -3997,6 +4027,10 @@ var init_harness_catalog = __esm(() => {
3997
4027
  command: "grok",
3998
4028
  sessionFlag: "--resume"
3999
4029
  },
4030
+ sessionDefaults: {
4031
+ defaultHarness: "grok-acp",
4032
+ defaultTransport: "grok_acp"
4033
+ },
4000
4034
  capabilities: ["chat", "invoke", "deliver", "summarize", "review"],
4001
4035
  metadata: {
4002
4036
  invocationModel: "tmux_interactive"
@@ -4036,6 +4070,9 @@ var init_harness_catalog = __esm(() => {
4036
4070
  sessionFlag: "resume",
4037
4071
  cwdFlag: "-C"
4038
4072
  },
4073
+ sessionDefaults: {
4074
+ defaultTransport: "codex_app_server"
4075
+ },
4039
4076
  capabilities: ["chat", "invoke", "deliver", "review", "execute"]
4040
4077
  },
4041
4078
  {
@@ -4068,12 +4105,53 @@ var init_harness_catalog = __esm(() => {
4068
4105
  loginCommand: "grok login",
4069
4106
  notReadyMessage: "Grok ACP is installed but still needs a cached login or XAI_API_KEY."
4070
4107
  },
4108
+ sessionDefaults: {
4109
+ defaultTransport: "grok_acp"
4110
+ },
4071
4111
  capabilities: ["chat", "invoke", "deliver", "review", "execute"],
4072
4112
  metadata: {
4073
4113
  adapterType: "grok-acp",
4074
4114
  transport: "acp_stdio"
4075
4115
  }
4076
4116
  },
4117
+ {
4118
+ name: "kimi",
4119
+ harness: "kimi",
4120
+ label: "Kimi Code",
4121
+ description: "Kimi Code CLI coding agent over ACP",
4122
+ homepage: "https://www.kimi.com/code/docs/en/",
4123
+ tags: ["coding", "cli", "kimi", "moonshot", "acp"],
4124
+ featured: true,
4125
+ order: 4,
4126
+ support: {
4127
+ ...DEFAULT_SUPPORT,
4128
+ workspace: true,
4129
+ collaboration: true,
4130
+ files: true
4131
+ },
4132
+ install: {
4133
+ binary: "kimi",
4134
+ requires: ["curl"],
4135
+ macos: "curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash",
4136
+ linux: "curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash",
4137
+ windows: "irm https://code.kimi.com/kimi-code/install.ps1 | iex"
4138
+ },
4139
+ readiness: {
4140
+ anyOf: [
4141
+ { kind: "file", path: "~/.kimi-code/credentials", label: "~/.kimi-code/credentials", fileType: "directory" }
4142
+ ],
4143
+ loginCommand: "kimi login",
4144
+ notReadyMessage: "Kimi Code is installed but still needs a cached login from kimi login."
4145
+ },
4146
+ sessionDefaults: {
4147
+ defaultTransport: "kimi_acp"
4148
+ },
4149
+ capabilities: ["chat", "invoke", "deliver", "review", "execute"],
4150
+ metadata: {
4151
+ adapterType: "kimi-acp",
4152
+ transport: "acp_stdio"
4153
+ }
4154
+ },
4077
4155
  {
4078
4156
  name: "cursor",
4079
4157
  harness: "cursor",
@@ -5837,6 +5915,7 @@ function resolveOpenScoutSetupContextRoot(options = {}) {
5837
5915
  return normalizePath(process.cwd());
5838
5916
  }
5839
5917
  async function writeOpenScoutSettings(settings, options = {}) {
5918
+ assertTestIsolatedUserData("write OpenScout settings", "OPENSCOUT_SUPPORT_DIRECTORY");
5840
5919
  ensureOpenScoutCleanSlateSync();
5841
5920
  const current = await readOpenScoutSettings(options);
5842
5921
  const merged = {
@@ -9222,6 +9301,7 @@ function resolveHost() {
9222
9301
  return resolveEffectiveLocalConfig().host ?? DEFAULT_LOCAL_CONFIG.host;
9223
9302
  }
9224
9303
  function writeLocalConfig(config) {
9304
+ assertTestIsolatedUserData("write the OpenScout local config", "OPENSCOUT_HOME");
9225
9305
  const configPath = localConfigPath();
9226
9306
  mkdirSync2(dirname6(configPath), { recursive: true });
9227
9307
  const body = JSON.stringify({ ...config, version: LOCAL_CONFIG_VERSION }, null, 2) + `
@@ -9235,6 +9315,7 @@ function localConfigExists() {
9235
9315
  }
9236
9316
  var LOCAL_CONFIG_VERSION = 1, DEFAULT_SCOUT_WEB_PORTAL_HOST = "scout.local", DEFAULT_SCOUT_WEB_DEV_HOST, DEFAULT_SCOUT_WEB_VITE_HMR_PATH = "/ws/hmr", OPENSCOUT_PORTS, DEFAULT_LOCAL_CONFIG;
9237
9317
  var init_local_config = __esm(() => {
9318
+ init_support_paths();
9238
9319
  DEFAULT_SCOUT_WEB_DEV_HOST = `dev.${DEFAULT_SCOUT_WEB_PORTAL_HOST}`;
9239
9320
  OPENSCOUT_PORTS = {
9240
9321
  broker: 43110,
@@ -9906,6 +9987,29 @@ function readNumber2(value) {
9906
9987
  function readHealthTransport(value) {
9907
9988
  return value === "unix_socket" || value === "http" || value === "in_process" ? value : undefined;
9908
9989
  }
9990
+ function readRuntimeFreshness(value) {
9991
+ if (!isRecord4(value))
9992
+ return;
9993
+ const state = readString2(value.state);
9994
+ const basis = readString2(value.basis);
9995
+ const detail = readString2(value.detail);
9996
+ if (!state || !basis || !detail)
9997
+ return;
9998
+ return {
9999
+ state,
10000
+ intentional: readBoolean(value.intentional) ?? false,
10001
+ basis,
10002
+ artifactCommit: readString2(value.artifactCommit) ?? null,
10003
+ expectedCommit: readString2(value.expectedCommit) ?? null,
10004
+ pin: readString2(value.pin) ?? null,
10005
+ pinReason: readString2(value.pinReason) ?? null,
10006
+ manifestPath: readString2(value.manifestPath) ?? null,
10007
+ version: readString2(value.version) ?? null,
10008
+ builtAt: readString2(value.builtAt) ?? null,
10009
+ sourceDirty: readBoolean(value.sourceDirty) ?? null,
10010
+ detail
10011
+ };
10012
+ }
9909
10013
  function normalizeNativeServiceStatus(input, config) {
9910
10014
  const healthRecord = isRecord4(input.health) ? input.health : {};
9911
10015
  const healthReachable = readBoolean(healthRecord.reachable) ?? readBoolean(input.reachable) ?? false;
@@ -9921,6 +10025,7 @@ function normalizeNativeServiceStatus(input, config) {
9921
10025
  const stdoutLogPath = readString2(input.stdoutLogPath) ?? config.stdoutLogPath;
9922
10026
  const stderrLogPath = readString2(input.stderrLogPath) ?? config.stderrLogPath;
9923
10027
  const lastLogLine = readString2(input.lastLogLine) ?? (healthReachable ? readLastLogLine([stdoutLogPath, stderrLogPath]) : readLastLogLine([stderrLogPath, stdoutLogPath]));
10028
+ const runtimeFreshness = readRuntimeFreshness(input.runtimeFreshness);
9924
10029
  return {
9925
10030
  label: readString2(input.label) ?? config.label,
9926
10031
  mode: readString2(input.mode) ?? config.mode,
@@ -9955,6 +10060,7 @@ function normalizeNativeServiceStatus(input, config) {
9955
10060
  ...isRecord4(healthRecord.services) ? { services: healthRecord.services } : {},
9956
10061
  error: healthError
9957
10062
  },
10063
+ ...runtimeFreshness ? { runtimeFreshness } : {},
9958
10064
  lastLogLine
9959
10065
  };
9960
10066
  }
@@ -10256,8 +10362,12 @@ function formatBrokerServiceStatus(status) {
10256
10362
  `reachable: ${status.reachable ? "yes" : "no"}`,
10257
10363
  `health: ${status.health.ok ? "ok" : status.health.error ?? "unreachable"}`,
10258
10364
  `health transport: ${status.health.transport ?? "unknown"}`,
10365
+ `runtime freshness: ${status.runtimeFreshness?.state ?? "unavailable"}`,
10259
10366
  `logs: ${status.stdoutLogPath}`
10260
10367
  ];
10368
+ if (status.runtimeFreshness) {
10369
+ lines.push(`runtime freshness detail: ${status.runtimeFreshness.detail}`);
10370
+ }
10261
10371
  if (status.health.socketFallbackError) {
10262
10372
  lines.push(`socket fallback: ${status.health.socketFallbackError}`);
10263
10373
  }
@@ -11478,6 +11588,13 @@ async function readTmuxPaneLocal(key, ctx) {
11478
11588
  throw error;
11479
11589
  }
11480
11590
  }
11591
+ async function readTmuxSessionExists(sessionName, options = {}) {
11592
+ const name = sessionName.trim();
11593
+ if (!name)
11594
+ return false;
11595
+ const snapshot = await tmuxSessionsProbe.for({ env: options.env, socketPath: options.socketPath }).fresh({ maxAgeMs: options.maxAgeMs ?? TMUX_TTL_MS });
11596
+ return Boolean(snapshot.value?.some((session) => session.name === name));
11597
+ }
11481
11598
  function readTmuxSessionExistsSnapshot(sessionName, options = {}) {
11482
11599
  const name = sessionName.trim();
11483
11600
  if (!name)
@@ -14680,6 +14797,10 @@ function normalizeCodexModelValue(value) {
14680
14797
  if (!trimmed) {
14681
14798
  return null;
14682
14799
  }
14800
+ const lower = trimmed.toLowerCase();
14801
+ if (lower === "5.6" || lower === "gpt-5.6") {
14802
+ return "gpt-5.6-sol";
14803
+ }
14683
14804
  if (/^\d+(?:\.\d+)*(?:-[A-Za-z0-9][A-Za-z0-9._-]*)?$/.test(trimmed)) {
14684
14805
  return `gpt-${trimmed}`;
14685
14806
  }
@@ -18463,6 +18584,73 @@ var init_grok_acp = __esm(() => {
18463
18584
  init_adapter4();
18464
18585
  });
18465
18586
 
18587
+ // ../agent-sessions/src/adapters/kimi-acp/adapter.ts
18588
+ import { existsSync as existsSync17 } from "fs";
18589
+ import { homedir as homedir18 } from "os";
18590
+ import { join as join20 } from "path";
18591
+ function isRecord8(value) {
18592
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
18593
+ }
18594
+ function stringValue8(value) {
18595
+ return typeof value === "string" && value.trim() ? value.trim() : null;
18596
+ }
18597
+ function stringArray4(value) {
18598
+ if (!Array.isArray(value)) {
18599
+ return null;
18600
+ }
18601
+ const entries = value.filter((entry) => typeof entry === "string");
18602
+ return entries.length === value.length ? entries : null;
18603
+ }
18604
+ function firstNonEmptyString2(...values) {
18605
+ for (const value of values) {
18606
+ const trimmed = value?.trim();
18607
+ if (trimmed) {
18608
+ return trimmed;
18609
+ }
18610
+ }
18611
+ return null;
18612
+ }
18613
+ function defaultKimiCommand(env) {
18614
+ const override = firstNonEmptyString2(env?.KIMI_CLI_BIN, process.env.KIMI_CLI_BIN);
18615
+ if (override) {
18616
+ return override;
18617
+ }
18618
+ const installedCandidates = [
18619
+ join20(homedir18(), ".kimi-code", "bin", "kimi"),
18620
+ join20(homedir18(), ".local", "bin", "kimi")
18621
+ ];
18622
+ return installedCandidates.find((candidate) => existsSync17(candidate)) ?? "kimi";
18623
+ }
18624
+ var DEFAULT_KIMI_ARGS, DEFAULT_KIMI_STARTUP_TIMEOUT_MS = 60000, KIMI_ACP_ADAPTER_TYPE = "kimi-acp", createAdapter5 = (config) => {
18625
+ const rawOptions = isRecord8(config.options) ? config.options : {};
18626
+ const command = stringValue8(rawOptions.command) ?? defaultKimiCommand(config.env);
18627
+ const args = stringArray4(rawOptions.args) ?? DEFAULT_KIMI_ARGS;
18628
+ const authMethodPreference = stringArray4(rawOptions.authMethodPreference) ?? ["login"];
18629
+ return new AcpAdapter({
18630
+ ...config,
18631
+ options: {
18632
+ clientName: "openscout",
18633
+ clientTitle: "OpenScout",
18634
+ ...rawOptions,
18635
+ adapterType: KIMI_ACP_ADAPTER_TYPE,
18636
+ command,
18637
+ args,
18638
+ startupTimeoutMs: typeof rawOptions.startupTimeoutMs === "number" ? rawOptions.startupTimeoutMs : DEFAULT_KIMI_STARTUP_TIMEOUT_MS,
18639
+ requireAuth: typeof rawOptions.requireAuth === "boolean" ? rawOptions.requireAuth : true,
18640
+ authMethodPreference
18641
+ }
18642
+ });
18643
+ };
18644
+ var init_adapter5 = __esm(() => {
18645
+ init_adapter3();
18646
+ DEFAULT_KIMI_ARGS = ["acp"];
18647
+ });
18648
+
18649
+ // ../agent-sessions/src/adapters/kimi-acp/index.ts
18650
+ var init_kimi_acp = __esm(() => {
18651
+ init_adapter5();
18652
+ });
18653
+
18466
18654
  // ../agent-sessions/src/adapters/openai-compat/adapter.ts
18467
18655
  function parseOptions2(raw) {
18468
18656
  if (!raw) {
@@ -18481,8 +18669,8 @@ function parseOptions2(raw) {
18481
18669
  temperature: raw["temperature"]
18482
18670
  };
18483
18671
  }
18484
- var OpenAICompatAdapter, createAdapter5 = (config) => new OpenAICompatAdapter(config);
18485
- var init_adapter5 = __esm(() => {
18672
+ var OpenAICompatAdapter, createAdapter6 = (config) => new OpenAICompatAdapter(config);
18673
+ var init_adapter6 = __esm(() => {
18486
18674
  OpenAICompatAdapter = class OpenAICompatAdapter extends BaseAdapter {
18487
18675
  type = "openai";
18488
18676
  options;
@@ -18842,7 +19030,7 @@ Referenced files: ${prompt.files.join(", ")}`
18842
19030
 
18843
19031
  // ../agent-sessions/src/adapters/openai-compat/index.ts
18844
19032
  var init_openai_compat = __esm(() => {
18845
- init_adapter5();
19033
+ init_adapter6();
18846
19034
  });
18847
19035
 
18848
19036
  // ../agent-sessions/src/adapters/opencode/adapter.ts
@@ -18871,8 +19059,8 @@ function delay(ms, signal) {
18871
19059
  signal.addEventListener("abort", onAbort, { once: true });
18872
19060
  });
18873
19061
  }
18874
- var OpenCodeAdapter, createAdapter6 = (config) => new OpenCodeAdapter(config);
18875
- var init_adapter6 = __esm(() => {
19062
+ var OpenCodeAdapter, createAdapter7 = (config) => new OpenCodeAdapter(config);
19063
+ var init_adapter7 = __esm(() => {
18876
19064
  OpenCodeAdapter = class OpenCodeAdapter extends BaseAdapter {
18877
19065
  type = "opencode";
18878
19066
  serverProcess = null;
@@ -19326,7 +19514,7 @@ var init_adapter6 = __esm(() => {
19326
19514
 
19327
19515
  // ../agent-sessions/src/adapters/opencode/index.ts
19328
19516
  var init_opencode = __esm(() => {
19329
- init_adapter6();
19517
+ init_adapter7();
19330
19518
  });
19331
19519
 
19332
19520
  // ../agent-sessions/src/adapters/pi/adapter.ts
@@ -19423,8 +19611,8 @@ function buildPiProcessEnv(config, sourceEnv = process.env) {
19423
19611
  }
19424
19612
  return env;
19425
19613
  }
19426
- var BASE_PROCESS_ENV_KEYS, PROVIDER_CREDENTIAL_ENV, PiAdapter, createAdapter7 = (config) => new PiAdapter(config);
19427
- var init_adapter7 = __esm(() => {
19614
+ var BASE_PROCESS_ENV_KEYS, PROVIDER_CREDENTIAL_ENV, PiAdapter, createAdapter8 = (config) => new PiAdapter(config);
19615
+ var init_adapter8 = __esm(() => {
19428
19616
  BASE_PROCESS_ENV_KEYS = [
19429
19617
  "PATH",
19430
19618
  "HOME",
@@ -20289,7 +20477,7 @@ var init_adapter7 = __esm(() => {
20289
20477
 
20290
20478
  // ../agent-sessions/src/adapters/pi/index.ts
20291
20479
  var init_pi = __esm(() => {
20292
- init_adapter7();
20480
+ init_adapter8();
20293
20481
  });
20294
20482
 
20295
20483
  // ../agent-sessions/src/index.ts
@@ -20301,6 +20489,7 @@ var init_src2 = __esm(() => {
20301
20489
  init_codex();
20302
20490
  init_acp();
20303
20491
  init_grok_acp();
20492
+ init_kimi_acp();
20304
20493
  init_openai_compat();
20305
20494
  init_opencode();
20306
20495
  init_pi();
@@ -20323,11 +20512,21 @@ var init_requester_timeout = __esm(() => {
20323
20512
  };
20324
20513
  });
20325
20514
 
20515
+ // ../runtime/src/acp-agent-invocation.ts
20516
+ var DEFAULT_ACP_HARD_CEILING_MS;
20517
+ var init_acp_agent_invocation = __esm(() => {
20518
+ init_requester_timeout();
20519
+ DEFAULT_ACP_HARD_CEILING_MS = 30 * 60000;
20520
+ });
20521
+
20326
20522
  // ../runtime/src/grok-acp-invocation.ts
20327
- var GROK_ACP_HARD_CEILING_MS;
20328
20523
  var init_grok_acp_invocation = __esm(() => {
20329
- init_requester_timeout();
20330
- GROK_ACP_HARD_CEILING_MS = 30 * 60000;
20524
+ init_acp_agent_invocation();
20525
+ });
20526
+
20527
+ // ../runtime/src/kimi-acp-invocation.ts
20528
+ var init_kimi_acp_invocation = __esm(() => {
20529
+ init_acp_agent_invocation();
20331
20530
  });
20332
20531
 
20333
20532
  // ../runtime/src/managed-agent-environment.ts
@@ -20358,8 +20557,8 @@ function buildManagedAgentShellExports(options) {
20358
20557
  import { randomUUID } from "crypto";
20359
20558
  import { spawn as spawn5 } from "child_process";
20360
20559
  import { appendFile as appendFile3, mkdir as mkdir7, readFile as readFile10, writeFile as writeFile7 } from "fs/promises";
20361
- import { existsSync as existsSync17, readFileSync as readFileSync8 } from "fs";
20362
- import { join as join20 } from "path";
20560
+ import { existsSync as existsSync18, readFileSync as readFileSync8 } from "fs";
20561
+ import { join as join21 } from "path";
20363
20562
  function resolveRequesterTimeoutMs2(timeoutMs) {
20364
20563
  if (typeof timeoutMs === "number" && Number.isFinite(timeoutMs) && timeoutMs > 0) {
20365
20564
  return timeoutMs;
@@ -20410,11 +20609,11 @@ function errorMessage5(error) {
20410
20609
  return error instanceof Error ? error.message : String(error);
20411
20610
  }
20412
20611
  function readSessionCatalogSync(runtimeDirectory) {
20413
- const catalogPath = join20(runtimeDirectory, SESSION_CATALOG_FILENAME2);
20612
+ const catalogPath = join21(runtimeDirectory, SESSION_CATALOG_FILENAME2);
20414
20613
  try {
20415
- if (!existsSync17(catalogPath)) {
20416
- const legacyPath = join20(runtimeDirectory, "claude-session-id.txt");
20417
- if (existsSync17(legacyPath)) {
20614
+ if (!existsSync18(catalogPath)) {
20615
+ const legacyPath = join21(runtimeDirectory, "claude-session-id.txt");
20616
+ if (existsSync18(legacyPath)) {
20418
20617
  const legacyId = readFileSync8(legacyPath, "utf8").trim();
20419
20618
  if (legacyId) {
20420
20619
  return {
@@ -20441,7 +20640,7 @@ async function readSessionCatalog(runtimeDirectory) {
20441
20640
  return readSessionCatalogSync(runtimeDirectory);
20442
20641
  }
20443
20642
  async function writeSessionCatalog(runtimeDirectory, catalog) {
20444
- const catalogPath = join20(runtimeDirectory, SESSION_CATALOG_FILENAME2);
20643
+ const catalogPath = join21(runtimeDirectory, SESSION_CATALOG_FILENAME2);
20445
20644
  await mkdir7(runtimeDirectory, { recursive: true });
20446
20645
  await writeFile7(catalogPath, JSON.stringify(catalog, null, 2) + `
20447
20646
  `);
@@ -20474,8 +20673,8 @@ class ClaudeStreamJsonSession {
20474
20673
  constructor(options) {
20475
20674
  this.options = options;
20476
20675
  this.catalogDirectory = options.runtimeDirectory;
20477
- this.stdoutLogPath = join20(options.logsDirectory, "stdout.log");
20478
- this.stderrLogPath = join20(options.logsDirectory, "stderr.log");
20676
+ this.stdoutLogPath = join21(options.logsDirectory, "stdout.log");
20677
+ this.stderrLogPath = join21(options.logsDirectory, "stderr.log");
20479
20678
  this.lastConfigSignature = this.configSignature(options);
20480
20679
  }
20481
20680
  matches(options) {
@@ -20631,7 +20830,7 @@ class ClaudeStreamJsonSession {
20631
20830
  async startSession() {
20632
20831
  await mkdir7(this.options.runtimeDirectory, { recursive: true });
20633
20832
  await mkdir7(this.options.logsDirectory, { recursive: true });
20634
- await writeFile7(join20(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
20833
+ await writeFile7(join21(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
20635
20834
  const catalog = await readSessionCatalog(this.catalogDirectory);
20636
20835
  this.claudeSessionId = catalog.activeSessionId;
20637
20836
  this.resumedSessionId = this.claudeSessionId;
@@ -20881,11 +21080,11 @@ function buildCollaborationContractPrompt(agentId) {
20881
21080
  }
20882
21081
 
20883
21082
  // ../runtime/src/pi-rpc.ts
20884
- import { existsSync as existsSync18 } from "fs";
21083
+ import { existsSync as existsSync19 } from "fs";
20885
21084
  import { mkdir as mkdir8, writeFile as writeFile8 } from "fs/promises";
20886
21085
  import { execFileSync as execFileSync5 } from "child_process";
20887
- import { homedir as homedir18 } from "os";
20888
- import { join as join21 } from "path";
21086
+ import { homedir as homedir19 } from "os";
21087
+ import { join as join22 } from "path";
20889
21088
  function normalizeOptionalString2(value) {
20890
21089
  const trimmed = value?.trim();
20891
21090
  return trimmed ? trimmed : undefined;
@@ -20906,7 +21105,7 @@ function resolveDefaultPiScoutExtension() {
20906
21105
  return null;
20907
21106
  }
20908
21107
  for (const candidate of PI_SCOUT_EXTENSION_CANDIDATES) {
20909
- if (existsSync18(candidate)) {
21108
+ if (existsSync19(candidate)) {
20910
21109
  return candidate;
20911
21110
  }
20912
21111
  }
@@ -20986,7 +21185,7 @@ function parsePiRpcLaunchArgs(launchArgs, options) {
20986
21185
  const parsed = {
20987
21186
  extensions: [],
20988
21187
  extraArgs: [],
20989
- sessionDir: join21(options.runtimeDirectory, "pi-sessions")
21188
+ sessionDir: join22(options.runtimeDirectory, "pi-sessions")
20990
21189
  };
20991
21190
  for (let index = 0;index < launchArgs.length; index += 1) {
20992
21191
  const current = launchArgs[index] ?? "";
@@ -21098,11 +21297,11 @@ class PiRpcAgentSession {
21098
21297
  }
21099
21298
  await mkdir8(this.options.runtimeDirectory, { recursive: true });
21100
21299
  await mkdir8(this.options.logsDirectory, { recursive: true });
21101
- await writeFile8(join21(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
21300
+ await writeFile8(join22(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
21102
21301
  const launch = parsePiRpcLaunchArgs(this.options.launchArgs, {
21103
21302
  runtimeDirectory: this.options.runtimeDirectory
21104
21303
  });
21105
- const adapter2 = createAdapter7({
21304
+ const adapter2 = createAdapter8({
21106
21305
  sessionId: this.options.sessionId,
21107
21306
  name: `${this.options.agentName} Pi RPC`,
21108
21307
  cwd: this.options.cwd,
@@ -21258,8 +21457,8 @@ var init_pi_rpc = __esm(() => {
21258
21457
  init_src2();
21259
21458
  PI_SCOUT_EXTENSION_CANDIDATES = [
21260
21459
  process.env.OPENSCOUT_PI_SCOUT_EXTENSION_PATH,
21261
- join21(homedir18(), ".pi", "agent", "extensions", "pi-scout"),
21262
- join21(homedir18(), "dev", "pi-scout")
21460
+ join22(homedir19(), ".pi", "agent", "extensions", "pi-scout"),
21461
+ join22(homedir19(), "dev", "pi-scout")
21263
21462
  ].filter((candidate) => Boolean(candidate));
21264
21463
  PI_RPC_FLAGS_WITH_VALUES = new Set([
21265
21464
  "--model",
@@ -21360,15 +21559,15 @@ var init_permission_policy2 = __esm(() => {
21360
21559
  });
21361
21560
 
21362
21561
  // ../runtime/src/user-config.ts
21363
- import { existsSync as existsSync19, readFileSync as readFileSync9, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
21364
- import { homedir as homedir19 } from "os";
21365
- import { dirname as dirname14, join as join22 } from "path";
21562
+ import { existsSync as existsSync20, readFileSync as readFileSync9, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
21563
+ import { homedir as homedir20 } from "os";
21564
+ import { dirname as dirname14, join as join23 } from "path";
21366
21565
  function userConfigPath() {
21367
- return join22(process.env.OPENSCOUT_HOME ?? join22(homedir19(), ".openscout"), "user.json");
21566
+ return join23(process.env.OPENSCOUT_HOME ?? join23(homedir20(), ".openscout"), "user.json");
21368
21567
  }
21369
21568
  function loadUserConfig() {
21370
21569
  const configPath = userConfigPath();
21371
- if (!existsSync19(configPath))
21570
+ if (!existsSync20(configPath))
21372
21571
  return {};
21373
21572
  try {
21374
21573
  return JSON.parse(readFileSync9(configPath, "utf8"));
@@ -21384,7 +21583,7 @@ function saveUserConfig(config) {
21384
21583
  }
21385
21584
  function readSettingsOperatorName() {
21386
21585
  const settingsPath = resolveOpenScoutSupportPaths().settingsPath;
21387
- if (!existsSync19(settingsPath))
21586
+ if (!existsSync20(settingsPath))
21388
21587
  return "";
21389
21588
  try {
21390
21589
  const settings = JSON.parse(readFileSync9(settingsPath, "utf8"));
@@ -21410,9 +21609,9 @@ var init_user_config = __esm(() => {
21410
21609
  });
21411
21610
 
21412
21611
  // ../runtime/src/local-agents.ts
21413
- import { existsSync as existsSync20, readFileSync as readFileSync10 } from "fs";
21612
+ import { existsSync as existsSync21, readFileSync as readFileSync10 } from "fs";
21414
21613
  import { mkdir as mkdir9, rm as rm4, stat as stat5, writeFile as writeFile9 } from "fs/promises";
21415
- import { basename as basename8, dirname as dirname15, join as join23, resolve as resolve13 } from "path";
21614
+ import { basename as basename8, dirname as dirname15, join as join24, resolve as resolve13 } from "path";
21416
21615
  import { fileURLToPath as fileURLToPath6 } from "url";
21417
21616
  function resolveRelayHub() {
21418
21617
  return resolveOpenScoutSupportPaths().relayHubDirectory;
@@ -21423,7 +21622,7 @@ function resolveProjectsRoot(projectPath) {
21423
21622
  }
21424
21623
  try {
21425
21624
  const supportPaths = resolveOpenScoutSupportPaths();
21426
- if (!existsSync20(supportPaths.settingsPath)) {
21625
+ if (!existsSync21(supportPaths.settingsPath)) {
21427
21626
  return dirname15(projectPath);
21428
21627
  }
21429
21628
  const raw = JSON.parse(readFileSync10(supportPaths.settingsPath, "utf8"));
@@ -21444,7 +21643,7 @@ function parsePositiveInteger2(value, fallback) {
21444
21643
  return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
21445
21644
  }
21446
21645
  function scoutCliPath() {
21447
- return join23(OPENSCOUT_REPO_ROOT, "packages", "cli", "bin", "scout.mjs");
21646
+ return join24(OPENSCOUT_REPO_ROOT, "packages", "cli", "bin", "scout.mjs");
21448
21647
  }
21449
21648
  function legacyNodeBrokerRelayCommand() {
21450
21649
  return `node ${JSON.stringify(scoutCliPath())}`;
@@ -21457,13 +21656,13 @@ function titleCaseLocalAgentName(value) {
21457
21656
  }
21458
21657
  function resolveScoutSkillPath() {
21459
21658
  const candidatePaths = [
21460
- join23(OPENSCOUT_REPO_ROOT, ".agents", "skills", "scout", "SKILL.md"),
21461
- join23(process.env.HOME ?? "", ".agents", "skills", "scout", "SKILL.md"),
21462
- join23(OPENSCOUT_REPO_ROOT, ".agents", "skills", "relay-agent-comms", "SKILL.md"),
21463
- join23(process.env.HOME ?? "", ".agents", "skills", "relay-agent-comms", "SKILL.md")
21659
+ join24(OPENSCOUT_REPO_ROOT, ".agents", "skills", "scout", "SKILL.md"),
21660
+ join24(process.env.HOME ?? "", ".agents", "skills", "scout", "SKILL.md"),
21661
+ join24(OPENSCOUT_REPO_ROOT, ".agents", "skills", "relay-agent-comms", "SKILL.md"),
21662
+ join24(process.env.HOME ?? "", ".agents", "skills", "relay-agent-comms", "SKILL.md")
21464
21663
  ];
21465
21664
  for (const path of candidatePaths) {
21466
- if (existsSync20(path)) {
21665
+ if (existsSync21(path)) {
21467
21666
  return path;
21468
21667
  }
21469
21668
  }
@@ -21801,7 +22000,7 @@ function expandHomePath4(value) {
21801
22000
  return process.env.HOME ?? process.cwd();
21802
22001
  }
21803
22002
  if (value.startsWith("~/")) {
21804
- return join23(process.env.HOME ?? process.cwd(), value.slice(2));
22003
+ return join24(process.env.HOME ?? process.cwd(), value.slice(2));
21805
22004
  }
21806
22005
  return value;
21807
22006
  }
@@ -22076,6 +22275,23 @@ function stripLaunchReasoningEffortForHarness(harness, launchArgs) {
22076
22275
  }
22077
22276
  return next2;
22078
22277
  }
22278
+ if (harness === "claude" || harness === "grok") {
22279
+ const next2 = [];
22280
+ const normalized2 = normalizeLocalAgentLaunchArgs(launchArgs);
22281
+ const flags = ["--effort", "--reasoning-effort"];
22282
+ for (let index = 0;index < normalized2.length; index += 1) {
22283
+ const current = normalized2[index] ?? "";
22284
+ if (flags.includes(current)) {
22285
+ index += 1;
22286
+ continue;
22287
+ }
22288
+ if (flags.some((flag) => current.startsWith(`${flag}=`))) {
22289
+ continue;
22290
+ }
22291
+ next2.push(current);
22292
+ }
22293
+ return next2;
22294
+ }
22079
22295
  if (harness !== "codex") {
22080
22296
  return normalizeLaunchArgsForHarness(harness, launchArgs);
22081
22297
  }
@@ -22109,6 +22325,9 @@ function buildLaunchArgsForRequestedReasoningEffort(harness, reasoningEffort) {
22109
22325
  if (harness === "codex") {
22110
22326
  return normalizeCodexAppServerLaunchArgs(["--reasoning-effort", reasoningEffort]);
22111
22327
  }
22328
+ if (harness === "claude") {
22329
+ return ["--effort", reasoningEffort];
22330
+ }
22112
22331
  if (harness === "pi") {
22113
22332
  return ["--thinking", reasoningEffort.trim().toLowerCase() === "none" ? "off" : reasoningEffort];
22114
22333
  }
@@ -22714,6 +22933,9 @@ function isLocalAgentRecordOnline(agentName, record2) {
22714
22933
  function isLocalAgentSessionAlive(sessionName) {
22715
22934
  return readTmuxSessionExistsSnapshot(sessionName);
22716
22935
  }
22936
+ async function isLocalAgentSessionAliveAsync(sessionName) {
22937
+ return readTmuxSessionExists(sessionName, { maxAgeMs: 0 });
22938
+ }
22717
22939
  function buildLocalAgentSystemPrompt(agentName, projectName, projectPath, options = {}) {
22718
22940
  return renderLocalAgentSystemPromptTemplate(buildLocalAgentSystemPromptTemplate(), buildLocalAgentTemplateContext(agentName, projectName, projectPath), options);
22719
22941
  }
@@ -22721,7 +22943,7 @@ function buildLocalAgentInitialMessage(projectName, agentName) {
22721
22943
  return `You are now online as the ${agentName} relay agent for ${projectName}. Announce yourself on the relay with: ${brokerRelayCommand()} send --as ${agentName} "relay agent online \u2014 ready to assist with ${projectName}"`;
22722
22944
  }
22723
22945
  function scoutReplyContextPath(runtimeDirectory) {
22724
- return join23(runtimeDirectory, "scout-reply-context.json");
22946
+ return join24(runtimeDirectory, "scout-reply-context.json");
22725
22947
  }
22726
22948
  function withScoutReplyContextEnvironment(options) {
22727
22949
  return {
@@ -22829,10 +23051,10 @@ function buildLocalAgentLaunchCommand(agentName, record2, projectPath, promptFil
22829
23051
  const harness = normalizeLocalAgentHarness(record2.harness);
22830
23052
  const extraArgs = shellQuoteArguments(harness === "claude" ? normalizeClaudeRuntimeLaunchArgs(record2.launchArgs) : harness === "grok" ? normalizeGrokRuntimeLaunchArgs(record2.launchArgs) : normalizeLaunchArgsForHarness(harness, record2.launchArgs));
22831
23053
  if (harness === "codex") {
22832
- return `exec bash ${JSON.stringify(workerScript ?? join23(relayAgentRuntimeDirectory(agentName), "codex-worker.sh"))}`;
23054
+ return `exec bash ${JSON.stringify(workerScript ?? join24(relayAgentRuntimeDirectory(agentName), "codex-worker.sh"))}`;
22833
23055
  }
22834
23056
  if (harness === "pi") {
22835
- const sessionDir = join23(relayAgentRuntimeDirectory(agentName), "pi-sessions");
23057
+ const sessionDir = join24(relayAgentRuntimeDirectory(agentName), "pi-sessions");
22836
23058
  return [
22837
23059
  "pi",
22838
23060
  `--append-system-prompt "$(cat ${JSON.stringify(promptFile)})"`,
@@ -22871,12 +23093,12 @@ function isShellCommandAvailable(binary) {
22871
23093
  if (!binary.trim())
22872
23094
  return false;
22873
23095
  if (binary.includes("/"))
22874
- return existsSync20(binary);
23096
+ return existsSync21(binary);
22875
23097
  const pathValue = process.env.PATH ?? "";
22876
23098
  for (const directory of pathValue.split(":")) {
22877
23099
  if (!directory)
22878
23100
  continue;
22879
- if (existsSync20(join23(directory, binary)))
23101
+ if (existsSync21(join24(directory, binary)))
22880
23102
  return true;
22881
23103
  }
22882
23104
  return false;
@@ -22936,7 +23158,7 @@ async function ensureLocalAgentOnline(agentName, record2) {
22936
23158
  await mkdir9(agentRuntimeDir, { recursive: true });
22937
23159
  await mkdir9(logsDir, { recursive: true });
22938
23160
  if (normalizedRecord.transport === "codex_app_server") {
22939
- await writeFile9(join23(agentRuntimeDir, "prompt.txt"), systemPrompt);
23161
+ await writeFile9(join24(agentRuntimeDir, "prompt.txt"), systemPrompt);
22940
23162
  await ensureCodexAppServerAgentOnline(buildCodexAgentSessionOptions(agentName, normalizedRecord, systemPrompt));
22941
23163
  const registry3 = await readLocalAgentRegistry();
22942
23164
  registry3[agentName] = {
@@ -22948,7 +23170,7 @@ async function ensureLocalAgentOnline(agentName, record2) {
22948
23170
  return registry3[agentName];
22949
23171
  }
22950
23172
  if (normalizedRecord.transport === "claude_stream_json") {
22951
- await writeFile9(join23(agentRuntimeDir, "prompt.txt"), systemPrompt);
23173
+ await writeFile9(join24(agentRuntimeDir, "prompt.txt"), systemPrompt);
22952
23174
  await ensureClaudeStreamJsonAgentOnline(buildClaudeAgentSessionOptions(agentName, normalizedRecord, systemPrompt));
22953
23175
  const registry3 = await readLocalAgentRegistry();
22954
23176
  registry3[agentName] = {
@@ -22960,7 +23182,7 @@ async function ensureLocalAgentOnline(agentName, record2) {
22960
23182
  return registry3[agentName];
22961
23183
  }
22962
23184
  if (normalizedRecord.transport === "pi_rpc") {
22963
- await writeFile9(join23(agentRuntimeDir, "prompt.txt"), systemPrompt);
23185
+ await writeFile9(join24(agentRuntimeDir, "prompt.txt"), systemPrompt);
22964
23186
  await ensurePiRpcAgentOnline(buildPiAgentSessionOptions(agentName, normalizedRecord, systemPrompt));
22965
23187
  const registry3 = await readLocalAgentRegistry();
22966
23188
  registry3[agentName] = {
@@ -22973,17 +23195,17 @@ async function ensureLocalAgentOnline(agentName, record2) {
22973
23195
  }
22974
23196
  const initialMessage = buildLocalAgentInitialMessage(projectName, agentName);
22975
23197
  const bootstrapPrompt = buildLocalAgentBootstrapPrompt(normalizeLocalAgentHarness(normalizedRecord.harness), systemPrompt, initialMessage);
22976
- const queueDirectory = join23(agentRuntimeDir, "queue");
22977
- const processingDirectory = join23(queueDirectory, "processing");
22978
- const processedDirectory = join23(queueDirectory, "processed");
22979
- const promptFile = join23(agentRuntimeDir, "prompt.txt");
22980
- const initialFile = join23(agentRuntimeDir, "initial.txt");
22981
- const launchScript = join23(agentRuntimeDir, "launch.sh");
22982
- const workerScript = join23(agentRuntimeDir, "codex-worker.sh");
22983
- const codexSessionIdFile = join23(agentRuntimeDir, "codex-session-id.txt");
22984
- const stateFile = join23(agentRuntimeDir, "state.json");
22985
- const stdoutLogFile = join23(logsDir, "stdout.log");
22986
- const stderrLogFile = join23(logsDir, "stderr.log");
23198
+ const queueDirectory = join24(agentRuntimeDir, "queue");
23199
+ const processingDirectory = join24(queueDirectory, "processing");
23200
+ const processedDirectory = join24(queueDirectory, "processed");
23201
+ const promptFile = join24(agentRuntimeDir, "prompt.txt");
23202
+ const initialFile = join24(agentRuntimeDir, "initial.txt");
23203
+ const launchScript = join24(agentRuntimeDir, "launch.sh");
23204
+ const workerScript = join24(agentRuntimeDir, "codex-worker.sh");
23205
+ const codexSessionIdFile = join24(agentRuntimeDir, "codex-session-id.txt");
23206
+ const stateFile = join24(agentRuntimeDir, "state.json");
23207
+ const stdoutLogFile = join24(logsDir, "stdout.log");
23208
+ const stderrLogFile = join24(logsDir, "stderr.log");
22987
23209
  await writeFile9(promptFile, systemPrompt);
22988
23210
  await writeFile9(initialFile, bootstrapPrompt);
22989
23211
  await writeFile9(stderrLogFile, "");
@@ -23047,14 +23269,15 @@ async function ensureLocalAgentOnline(agentName, record2) {
23047
23269
  updatedAt: new Date().toISOString()
23048
23270
  }, null, 2) + `
23049
23271
  `);
23050
- for (let attempt = 0;attempt < 20; attempt += 1) {
23051
- if (isLocalAgentSessionAlive(normalizedRecord.tmuxSession)) {
23052
- break;
23272
+ let sessionOnline = false;
23273
+ for (let attempt = 0;attempt < 20 && !sessionOnline; attempt += 1) {
23274
+ sessionOnline = await isLocalAgentSessionAliveAsync(normalizedRecord.tmuxSession);
23275
+ if (!sessionOnline) {
23276
+ await new Promise((resolve14) => setTimeout(resolve14, 100));
23053
23277
  }
23054
- await new Promise((resolve14) => setTimeout(resolve14, 100));
23055
23278
  }
23056
- if (!isLocalAgentSessionAlive(normalizedRecord.tmuxSession)) {
23057
- const stderrTail = existsSync20(stderrLogFile) ? readFileSync10(stderrLogFile, "utf8").trim().split(/\r?\n/).slice(-10).join(`
23279
+ if (!sessionOnline) {
23280
+ const stderrTail = existsSync21(stderrLogFile) ? readFileSync10(stderrLogFile, "utf8").trim().split(/\r?\n/).slice(-10).join(`
23058
23281
  `).trim() : "";
23059
23282
  throw new Error(stderrTail ? `Relay agent ${agentName} failed to stay online:
23060
23283
  ${stderrTail}` : `Relay agent ${agentName} failed to stay online.`);
@@ -23546,8 +23769,8 @@ async function restartAllLocalAgents(options = {}) {
23546
23769
  }
23547
23770
  function readPersistedSessionCatalogId(runtimeDir) {
23548
23771
  try {
23549
- const catalogPath = join23(runtimeDir, "session-catalog.json");
23550
- if (existsSync20(catalogPath)) {
23772
+ const catalogPath = join24(runtimeDir, "session-catalog.json");
23773
+ if (existsSync21(catalogPath)) {
23551
23774
  const raw = readFileSync10(catalogPath, "utf8").trim();
23552
23775
  if (raw) {
23553
23776
  const catalog = JSON.parse(raw);
@@ -23563,8 +23786,8 @@ function readPersistedSessionCatalogId(runtimeDir) {
23563
23786
  }
23564
23787
  function readPersistedLegacySessionId(runtimeDir, filename) {
23565
23788
  try {
23566
- const legacyPath = join23(runtimeDir, filename);
23567
- if (existsSync20(legacyPath)) {
23789
+ const legacyPath = join24(runtimeDir, filename);
23790
+ if (existsSync21(legacyPath)) {
23568
23791
  const value = readFileSync10(legacyPath, "utf8").trim();
23569
23792
  return value || null;
23570
23793
  }
@@ -23822,6 +24045,7 @@ var init_local_agents = __esm(() => {
23822
24045
  init_dispatch_stalled();
23823
24046
  init_system_probes();
23824
24047
  init_grok_acp_invocation();
24048
+ init_kimi_acp_invocation();
23825
24049
  init_claude_stream_json();
23826
24050
  init_codex_app_server2();
23827
24051
  init_pi_rpc();
@@ -23841,6 +24065,7 @@ var init_local_agents = __esm(() => {
23841
24065
  SUPPORTED_SCOUT_HARNESSES = [
23842
24066
  ...SUPPORTED_LOCAL_AGENT_HARNESSES,
23843
24067
  "grok-acp",
24068
+ "kimi",
23844
24069
  "flue"
23845
24070
  ];
23846
24071
  DEFAULT_CLAUDE_SCOUT_ALLOWED_TOOLS = [
@@ -25945,7 +26170,7 @@ var init_sql = __esm(() => {
25945
26170
  return new SQL([new StringChunk(str)]);
25946
26171
  }
25947
26172
  sql2.raw = raw;
25948
- function join24(chunks, separator) {
26173
+ function join25(chunks, separator) {
25949
26174
  const result = [];
25950
26175
  for (const [i, chunk] of chunks.entries()) {
25951
26176
  if (i > 0 && separator !== undefined) {
@@ -25955,7 +26180,7 @@ var init_sql = __esm(() => {
25955
26180
  }
25956
26181
  return new SQL(result);
25957
26182
  }
25958
- sql2.join = join24;
26183
+ sql2.join = join25;
25959
26184
  function identifier(value) {
25960
26185
  return new Name(value);
25961
26186
  }
@@ -28471,7 +28696,7 @@ var init_select2 = __esm(() => {
28471
28696
  const tableName = getTableLikeName(table2);
28472
28697
  for (const item of extractUsedTable(table2))
28473
28698
  this.usedTables.add(item);
28474
- if (typeof tableName === "string" && this.config.joins?.some((join24) => join24.alias === tableName)) {
28699
+ if (typeof tableName === "string" && this.config.joins?.some((join25) => join25.alias === tableName)) {
28475
28700
  throw new Error(`Alias "${tableName}" is already used in this query`);
28476
28701
  }
28477
28702
  if (!this.isPartialSelect) {
@@ -28893,7 +29118,7 @@ var init_update = __esm(() => {
28893
29118
  createJoin(joinType) {
28894
29119
  return (table2, on) => {
28895
29120
  const tableName = getTableLikeName(table2);
28896
- if (typeof tableName === "string" && this.config.joins.some((join24) => join24.alias === tableName)) {
29121
+ if (typeof tableName === "string" && this.config.joins.some((join25) => join25.alias === tableName)) {
28897
29122
  throw new Error(`Alias "${tableName}" is already used in this query`);
28898
29123
  }
28899
29124
  if (typeof on === "function") {
@@ -30411,8 +30636,8 @@ function readMigrationFiles(config) {
30411
30636
  var init_migrator = () => {};
30412
30637
 
30413
30638
  // ../runtime/src/control-plane-migrations.ts
30414
- import { existsSync as existsSync21 } from "fs";
30415
- import { join as join24 } from "path";
30639
+ import { existsSync as existsSync22 } from "fs";
30640
+ import { join as join25 } from "path";
30416
30641
  import { fileURLToPath as fileURLToPath7 } from "url";
30417
30642
  function hasColumn(database, tableName, columnName) {
30418
30643
  const escapedTableName = tableName.replaceAll("'", "''");
@@ -30429,7 +30654,7 @@ function resolveControlPlaneDrizzleMigrationsFolder() {
30429
30654
  const candidates = ["../drizzle", "./drizzle"];
30430
30655
  for (const candidate of candidates) {
30431
30656
  const folder = fileURLToPath7(new URL(candidate, import.meta.url));
30432
- if (existsSync21(join24(folder, "meta", "_journal.json"))) {
30657
+ if (existsSync22(join25(folder, "meta", "_journal.json"))) {
30433
30658
  return folder;
30434
30659
  }
30435
30660
  }
@@ -30464,8 +30689,8 @@ function controlPlaneDatabaseFilename(database) {
30464
30689
  }
30465
30690
  function applyControlPlaneDrizzleMigrations(database) {
30466
30691
  const migrationsFolder = resolveControlPlaneDrizzleMigrationsFolder();
30467
- const journalPath = join24(migrationsFolder, "meta", "_journal.json");
30468
- if (!existsSync21(journalPath)) {
30692
+ const journalPath = join25(migrationsFolder, "meta", "_journal.json");
30693
+ if (!existsSync22(journalPath)) {
30469
30694
  return false;
30470
30695
  }
30471
30696
  const migrations = readMigrationFiles({ migrationsFolder });
@@ -30782,7 +31007,7 @@ function stableHash(value) {
30782
31007
  function metadataRecord3(value) {
30783
31008
  return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
30784
31009
  }
30785
- function stringValue8(value) {
31010
+ function stringValue9(value) {
30786
31011
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
30787
31012
  }
30788
31013
  function numberValue6(value) {
@@ -30832,7 +31057,7 @@ function budgetObservationsFromEndpoint(endpoint, now = Date.now()) {
30832
31057
  harness: endpoint.harness,
30833
31058
  transport: endpoint.transport,
30834
31059
  adapterType: endpoint.transport,
30835
- model: stringValue8(metadata?.model),
31060
+ model: stringValue9(metadata?.model),
30836
31061
  sessionId: endpoint.sessionId,
30837
31062
  projectRoot: endpoint.projectRoot,
30838
31063
  cwd: endpoint.cwd,
@@ -30961,29 +31186,29 @@ function isSqliteConstraintError(error) {
30961
31186
  function metadataValue(metadata, key) {
30962
31187
  return metadata?.[key];
30963
31188
  }
30964
- function stringValue9(metadata, key) {
31189
+ function stringValue10(metadata, key) {
30965
31190
  const value = metadataValue(metadata, key);
30966
31191
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
30967
31192
  }
30968
31193
  function invocationStringValue(invocation, key) {
30969
- const contextValue = stringValue9(invocation.context, key);
31194
+ const contextValue = stringValue10(invocation.context, key);
30970
31195
  if (contextValue) {
30971
31196
  return contextValue;
30972
31197
  }
30973
31198
  const nestedContext = metadataValue(invocation.context, "collaboration");
30974
31199
  if (nestedContext && typeof nestedContext === "object" && !Array.isArray(nestedContext)) {
30975
- const nestedValue = stringValue9(nestedContext, key);
31200
+ const nestedValue = stringValue10(nestedContext, key);
30976
31201
  if (nestedValue) {
30977
31202
  return nestedValue;
30978
31203
  }
30979
31204
  }
30980
- const metadataEntry = stringValue9(invocation.metadata, key);
31205
+ const metadataEntry = stringValue10(invocation.metadata, key);
30981
31206
  if (metadataEntry) {
30982
31207
  return metadataEntry;
30983
31208
  }
30984
31209
  const nestedMetadata = metadataValue(invocation.metadata, "collaboration");
30985
31210
  if (nestedMetadata && typeof nestedMetadata === "object" && !Array.isArray(nestedMetadata)) {
30986
- return stringValue9(nestedMetadata, key);
31211
+ return stringValue10(nestedMetadata, key);
30987
31212
  }
30988
31213
  return;
30989
31214
  }
@@ -33263,14 +33488,14 @@ var init_broker_core_service = __esm(() => {
33263
33488
  });
33264
33489
 
33265
33490
  // ../runtime/src/provisional-agent-names-config.ts
33266
- import { existsSync as existsSync22, readFileSync as readFileSync11, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5 } from "fs";
33267
- import { homedir as homedir20 } from "os";
33268
- import { isAbsolute as isAbsolute3, join as join25, resolve as resolve14 } from "path";
33491
+ import { existsSync as existsSync23, readFileSync as readFileSync11, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5 } from "fs";
33492
+ import { homedir as homedir21 } from "os";
33493
+ import { isAbsolute as isAbsolute3, join as join26, resolve as resolve14 } from "path";
33269
33494
  function openScoutHome() {
33270
- return process.env.OPENSCOUT_HOME ?? join25(homedir20(), ".openscout");
33495
+ return process.env.OPENSCOUT_HOME ?? join26(homedir21(), ".openscout");
33271
33496
  }
33272
33497
  function defaultProvisionalAgentNamesPath() {
33273
- return join25(openScoutHome(), "provisional-agent-names.json");
33498
+ return join26(openScoutHome(), "provisional-agent-names.json");
33274
33499
  }
33275
33500
  function resolveProvisionalAgentNamesMode(config) {
33276
33501
  return config.provisionalAgentNamesMode === "extend" ? "extend" : "replace";
@@ -33315,7 +33540,7 @@ function loadInlineProvisionalAgentNames(config) {
33315
33540
  }
33316
33541
  function loadFileProvisionalAgentNames(config = loadUserConfig()) {
33317
33542
  const envFile = process.env.OPENSCOUT_PROVISIONAL_AGENT_NAMES_FILE?.trim();
33318
- if (envFile && existsSync22(envFile)) {
33543
+ if (envFile && existsSync23(envFile)) {
33319
33544
  const names = readProvisionalAgentNamesJsonFile(envFile);
33320
33545
  if (names.length > 0) {
33321
33546
  return { names, source: "env-file", sourcePath: envFile };
@@ -33323,7 +33548,7 @@ function loadFileProvisionalAgentNames(config = loadUserConfig()) {
33323
33548
  }
33324
33549
  if (config.provisionalAgentNamesFile?.trim()) {
33325
33550
  const filePath = resolvePoolFilePath(config.provisionalAgentNamesFile);
33326
- if (existsSync22(filePath)) {
33551
+ if (existsSync23(filePath)) {
33327
33552
  const names = readProvisionalAgentNamesJsonFile(filePath);
33328
33553
  if (names.length > 0) {
33329
33554
  return { names, source: "user-config-file", sourcePath: filePath };
@@ -33331,7 +33556,7 @@ function loadFileProvisionalAgentNames(config = loadUserConfig()) {
33331
33556
  }
33332
33557
  }
33333
33558
  const homeJson = defaultProvisionalAgentNamesPath();
33334
- if (existsSync22(homeJson)) {
33559
+ if (existsSync23(homeJson)) {
33335
33560
  const names = readProvisionalAgentNamesJsonFile(homeJson);
33336
33561
  if (names.length > 0) {
33337
33562
  return { names, source: "home-json", sourcePath: homeJson };
@@ -33796,7 +34021,8 @@ var init_local_agent_transports = __esm(() => {
33796
34021
  "codex_app_server",
33797
34022
  "claude_stream_json",
33798
34023
  "pi_rpc",
33799
- "grok_acp"
34024
+ "grok_acp",
34025
+ "kimi_acp"
33800
34026
  ]);
33801
34027
  });
33802
34028
 
@@ -33955,20 +34181,20 @@ var init_openscout_discovery = __esm(() => {
33955
34181
  });
33956
34182
 
33957
34183
  // ../runtime/src/provider-telemetry-bootstrap.ts
33958
- import { existsSync as existsSync23 } from "fs";
34184
+ import { existsSync as existsSync24 } from "fs";
33959
34185
  import { readFile as readFile11 } from "fs/promises";
33960
- import { homedir as homedir21 } from "os";
33961
- import { join as join26 } from "path";
34186
+ import { homedir as homedir22 } from "os";
34187
+ import { join as join27 } from "path";
33962
34188
  function resolveHomeDirectory(env) {
33963
- return env.HOME?.trim() || homedir21();
34189
+ return env.HOME?.trim() || homedir22();
33964
34190
  }
33965
34191
  function resolveClaudeSettingsPath2(env) {
33966
- return join26(resolveHomeDirectory(env), ".claude", "settings.json");
34192
+ return join27(resolveHomeDirectory(env), ".claude", "settings.json");
33967
34193
  }
33968
- function isRecord8(value) {
34194
+ function isRecord9(value) {
33969
34195
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
33970
34196
  }
33971
- function stringValue10(value) {
34197
+ function stringValue11(value) {
33972
34198
  return typeof value === "string" && value.trim() ? value.trim() : undefined;
33973
34199
  }
33974
34200
  function numberValue7(value) {
@@ -33979,7 +34205,7 @@ function timestampMs(value) {
33979
34205
  if (numeric3 !== undefined) {
33980
34206
  return numeric3 < 10000000000 ? numeric3 * 1000 : numeric3;
33981
34207
  }
33982
- const text3 = stringValue10(value);
34208
+ const text3 = stringValue11(value);
33983
34209
  if (!text3)
33984
34210
  return;
33985
34211
  const parsed = Date.parse(text3);
@@ -33988,36 +34214,36 @@ function timestampMs(value) {
33988
34214
  async function readJsonRecord(path) {
33989
34215
  try {
33990
34216
  const parsed = JSON.parse(await readFile11(path, "utf8"));
33991
- return isRecord8(parsed) ? parsed : null;
34217
+ return isRecord9(parsed) ? parsed : null;
33992
34218
  } catch {
33993
34219
  return null;
33994
34220
  }
33995
34221
  }
33996
34222
  async function readClaudeStatuslineCommand(settingsPath) {
33997
34223
  const settings = await readJsonRecord(settingsPath);
33998
- const statusLine = isRecord8(settings?.statusLine) ? settings.statusLine : null;
33999
- return stringValue10(statusLine?.command);
34224
+ const statusLine = isRecord9(settings?.statusLine) ? settings.statusLine : null;
34225
+ return stringValue11(statusLine?.command);
34000
34226
  }
34001
34227
  async function readStatuslineLatest(freshnessMs) {
34002
34228
  const path = resolveClaudeStatuslineLatestPath();
34003
- if (!existsSync23(path)) {
34229
+ if (!existsSync24(path)) {
34004
34230
  return { path, status: "missing" };
34005
34231
  }
34006
34232
  const latest = await readJsonRecord(path);
34007
34233
  if (!latest) {
34008
34234
  return { path, status: "unreadable" };
34009
34235
  }
34010
- const workspace = isRecord8(latest.workspace) ? latest.workspace : null;
34236
+ const workspace = isRecord9(latest.workspace) ? latest.workspace : null;
34011
34237
  const capturedAt = timestampMs(latest.openscoutCapturedAt) ?? timestampMs(latest.capturedAt) ?? timestampMs(latest.timestamp);
34012
34238
  const ageMs = capturedAt === undefined ? undefined : Math.max(0, Date.now() - capturedAt);
34013
34239
  const status = ageMs !== undefined && ageMs <= freshnessMs ? "fresh" : "stale";
34014
- const cwd = stringValue10(latest.cwd) ?? stringValue10(workspace?.current_dir);
34240
+ const cwd = stringValue11(latest.cwd) ?? stringValue11(workspace?.current_dir);
34015
34241
  return {
34016
34242
  path,
34017
34243
  status,
34018
34244
  ...capturedAt === undefined ? {} : { capturedAt },
34019
34245
  ...ageMs === undefined ? {} : { ageMs },
34020
- ...stringValue10(latest.session_id) ? { sessionId: stringValue10(latest.session_id) } : {},
34246
+ ...stringValue11(latest.session_id) ? { sessionId: stringValue11(latest.session_id) } : {},
34021
34247
  ...cwd ? { cwd } : {}
34022
34248
  };
34023
34249
  }
@@ -34049,7 +34275,7 @@ async function ensureProviderTelemetryBootstrap(options = {}) {
34049
34275
  statuslineLatest: await readStatuslineLatest(freshnessMs)
34050
34276
  };
34051
34277
  }
34052
- if (!existsSync23(settingsPath)) {
34278
+ if (!existsSync24(settingsPath)) {
34053
34279
  return {
34054
34280
  skipped: false,
34055
34281
  claude: {
@@ -34062,7 +34288,7 @@ async function ensureProviderTelemetryBootstrap(options = {}) {
34062
34288
  };
34063
34289
  }
34064
34290
  const command = await readClaudeStatuslineCommand(settingsPath);
34065
- const alreadyInstalled = command ? isOpenScoutClaudeStatuslineCommand(command, wrapperPath) && existsSync23(wrapperPath) : false;
34291
+ const alreadyInstalled = command ? isOpenScoutClaudeStatuslineCommand(command, wrapperPath) && existsSync24(wrapperPath) : false;
34066
34292
  const claude = alreadyInstalled ? {
34067
34293
  settingsPath,
34068
34294
  wrapperPath,
@@ -34083,18 +34309,18 @@ var init_provider_telemetry_bootstrap = __esm(() => {
34083
34309
  });
34084
34310
 
34085
34311
  // ../runtime/src/onboarding.ts
34086
- import { existsSync as existsSync24 } from "fs";
34087
- import { homedir as homedir22 } from "os";
34088
- import { dirname as dirname17, join as join27, resolve as resolve15 } from "path";
34312
+ import { existsSync as existsSync25 } from "fs";
34313
+ import { homedir as homedir23 } from "os";
34314
+ import { dirname as dirname17, join as join28, resolve as resolve15 } from "path";
34089
34315
  function nowMs2() {
34090
34316
  return Date.now();
34091
34317
  }
34092
34318
  function expandHomePath5(value) {
34093
34319
  if (value === "~") {
34094
- return homedir22();
34320
+ return homedir23();
34095
34321
  }
34096
34322
  if (value.startsWith("~/")) {
34097
- return join27(homedir22(), value.slice(2));
34323
+ return join28(homedir23(), value.slice(2));
34098
34324
  }
34099
34325
  return value;
34100
34326
  }
@@ -34102,7 +34328,7 @@ function normalizePath2(value) {
34102
34328
  return resolve15(expandHomePath5(value.trim() || "."));
34103
34329
  }
34104
34330
  function projectConfigPath2(projectRoot) {
34105
- return join27(projectRoot, ".openscout", "project.json");
34331
+ return join28(projectRoot, ".openscout", "project.json");
34106
34332
  }
34107
34333
  function normalizeDefaultHarness(value) {
34108
34334
  return value === "codex" ? "codex" : value === "cursor" ? "cursor" : value === "pi" ? "pi" : "claude";
@@ -34123,7 +34349,7 @@ async function nearestProjectConfig(startDirectory) {
34123
34349
  let current = normalizePath2(trimmed);
34124
34350
  while (true) {
34125
34351
  const candidate = projectConfigPath2(current);
34126
- if (existsSync24(candidate)) {
34352
+ if (existsSync25(candidate)) {
34127
34353
  return {
34128
34354
  projectRoot: current,
34129
34355
  projectConfigPath: candidate
@@ -35039,9 +35265,9 @@ import { Database as Database2 } from "bun:sqlite";
35039
35265
  import { mkdirSync as mkdirSync6, readFileSync as readFileSync12 } from "fs";
35040
35266
  import { connect as connectHttp2 } from "http2";
35041
35267
  import { createPrivateKey, sign as signWithKey } from "crypto";
35042
- import { dirname as dirname18, join as join28 } from "path";
35268
+ import { dirname as dirname18, join as join29 } from "path";
35043
35269
  function resolveControlPlaneDbPath() {
35044
- return join28(resolveOpenScoutSupportPaths().controlHome, "control-plane.sqlite");
35270
+ return join29(resolveOpenScoutSupportPaths().controlHome, "control-plane.sqlite");
35045
35271
  }
35046
35272
  function ensureMobilePushSchema(database) {
35047
35273
  database.exec("PRAGMA busy_timeout = 5000;");
@@ -36264,7 +36490,7 @@ function endpointTmuxTarget(endpoint) {
36264
36490
  }
36265
36491
  function endpointDebugTransport(endpoint) {
36266
36492
  const value = endpoint.metadata?.debugTransport;
36267
- if (!isRecord9(value) || value.kind !== "tmux" || typeof value.sessionName !== "string" || value.sessionName.length === 0) {
36493
+ if (!isRecord10(value) || value.kind !== "tmux" || typeof value.sessionName !== "string" || value.sessionName.length === 0) {
36268
36494
  return null;
36269
36495
  }
36270
36496
  return {
@@ -36427,7 +36653,7 @@ function nativeSessionTitle(nativeSession) {
36427
36653
  function titleCase2(value) {
36428
36654
  return value ? `${value[0]?.toUpperCase()}${value.slice(1)}` : "Native";
36429
36655
  }
36430
- function isRecord9(value) {
36656
+ function isRecord10(value) {
36431
36657
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
36432
36658
  }
36433
36659
  var SCOUT_VANTAGE_PLAN_SCHEMA = "scout.vantage.plan.v1", HUDSON_VANTAGE_SETUP_KIND = "hudson.vantage.setup", HUDSON_VANTAGE_SCHEMA_VERSION = 1, NODE_WIDTH = 560, NODE_HEIGHT = 360, NODE_GAP_X = 40, NODE_GAP_Y = 40, NODES_PER_ROW = 2;
@@ -36611,7 +36837,7 @@ var init_sender = __esm(() => {
36611
36837
 
36612
36838
  // ../../apps/desktop/src/core/broker/service.ts
36613
36839
  import { mkdir as mkdir10, readFile as readFile12, unlink, writeFile as writeFile10 } from "fs/promises";
36614
- import { basename as basename10, join as join29, resolve as resolve16 } from "path";
36840
+ import { basename as basename10, join as join30, resolve as resolve16 } from "path";
36615
36841
  import { randomUUID as randomUUID3 } from "crypto";
36616
36842
  function relayHubDirectory() {
36617
36843
  return resolveOpenScoutSupportPaths().relayHubDirectory;
@@ -39431,7 +39657,7 @@ async function listScoutAgents(options = {}) {
39431
39657
  }
39432
39658
  async function loadScoutRelayConfig() {
39433
39659
  try {
39434
- const raw = await readFile12(join29(relayHubDirectory(), "config.json"), "utf8");
39660
+ const raw = await readFile12(join30(relayHubDirectory(), "config.json"), "utf8");
39435
39661
  return JSON.parse(raw);
39436
39662
  } catch {
39437
39663
  return {};
@@ -39453,7 +39679,7 @@ function applyPronunciations(text3, pronunciations) {
39453
39679
  async function acquireScoutOnAir(agent, timeoutMs = 30000) {
39454
39680
  const hub = relayHubDirectory();
39455
39681
  await mkdir10(hub, { recursive: true });
39456
- const lockPath = join29(hub, "on-air.lock");
39682
+ const lockPath = join30(hub, "on-air.lock");
39457
39683
  const deadline = Date.now() + timeoutMs;
39458
39684
  while (Date.now() < deadline) {
39459
39685
  try {
@@ -39471,7 +39697,7 @@ async function acquireScoutOnAir(agent, timeoutMs = 30000) {
39471
39697
  }
39472
39698
  async function releaseScoutOnAir() {
39473
39699
  try {
39474
- await unlink(join29(relayHubDirectory(), "on-air.lock"));
39700
+ await unlink(join30(relayHubDirectory(), "on-air.lock"));
39475
39701
  } catch {}
39476
39702
  }
39477
39703
  async function speakScoutText(text3, voice) {
@@ -40116,7 +40342,7 @@ var init_ask2 = __esm(() => {
40116
40342
  });
40117
40343
 
40118
40344
  // ../../apps/desktop/src/core/broker/attention.ts
40119
- import { existsSync as existsSync25 } from "fs";
40345
+ import { existsSync as existsSync26 } from "fs";
40120
40346
  import { basename as basename12, resolve as resolve18 } from "path";
40121
40347
  async function loadScoutAttentionReport(options) {
40122
40348
  const brokerUrl = options.brokerUrl ?? resolveScoutBrokerUrl();
@@ -40333,7 +40559,7 @@ async function findGitRoot(cwd) {
40333
40559
  }
40334
40560
  async function readGitAttentionState(projectRoot) {
40335
40561
  const normalizedRoot = resolve18(projectRoot);
40336
- if (!existsSync25(normalizedRoot)) {
40562
+ if (!existsSync26(normalizedRoot)) {
40337
40563
  return emptyGitState(normalizedRoot, "path does not exist");
40338
40564
  }
40339
40565
  const inside = await gitRevParse({ repoRoot: normalizedRoot, kind: "isInsideWorkTree" });
@@ -71138,9 +71364,9 @@ var init_runtime_service_client = __esm(() => {
71138
71364
  // ../../apps/desktop/src/core/setup/command-lock.ts
71139
71365
  import { mkdir as mkdir11, open, readFile as readFile13, rm as rm5 } from "fs/promises";
71140
71366
  import { hostname as hostname4 } from "os";
71141
- import { dirname as dirname20, join as join30 } from "path";
71367
+ import { dirname as dirname20, join as join31 } from "path";
71142
71368
  function scoutCoreCommandLockPath() {
71143
- return join30(resolveOpenScoutSupportPaths().runtimeDirectory, "locks", SCOUT_CORE_COMMAND_LOCK_FILE);
71369
+ return join31(resolveOpenScoutSupportPaths().runtimeDirectory, "locks", SCOUT_CORE_COMMAND_LOCK_FILE);
71144
71370
  }
71145
71371
  function isProcessAlive(pid) {
71146
71372
  if (!Number.isInteger(pid) || pid <= 0) {
@@ -71245,9 +71471,9 @@ var init_command_lock = __esm(() => {
71245
71471
 
71246
71472
  // ../../apps/desktop/src/core/setup/local-edge-dependencies.ts
71247
71473
  import { spawnSync as spawnSync3 } from "child_process";
71248
- import { existsSync as existsSync26 } from "fs";
71249
- import { homedir as homedir23 } from "os";
71250
- import { join as join31 } from "path";
71474
+ import { existsSync as existsSync27 } from "fs";
71475
+ import { homedir as homedir24 } from "os";
71476
+ import { join as join32 } from "path";
71251
71477
  function defaultRunCommand2(command, args, options) {
71252
71478
  const result = spawnSync3(command, args, options);
71253
71479
  return {
@@ -71286,7 +71512,7 @@ function readCaddyVersion(caddyPath, runCommand) {
71286
71512
  return firstNonEmptyLine(result.stdout) ?? firstNonEmptyLine(result.stderr);
71287
71513
  }
71288
71514
  function resolveCaddyLocalRootCertificatePath(env) {
71289
- return join31(env.HOME?.trim() || homedir23(), "Library", "Application Support", "Caddy", "pki", "authorities", "local", "root.crt");
71515
+ return join32(env.HOME?.trim() || homedir24(), "Library", "Application Support", "Caddy", "pki", "authorities", "local", "root.crt");
71290
71516
  }
71291
71517
  function shellQuote2(value) {
71292
71518
  return `'${value.replace(/'/g, "'\\''")}'`;
@@ -71307,7 +71533,7 @@ function renderMacosTrustScript(rootCertificatePath) {
71307
71533
  function inspectScoutLocalEdgeTrust(input) {
71308
71534
  const rootCertificatePath = resolveCaddyLocalRootCertificatePath(input.env);
71309
71535
  const trustCommand = input.platform === "darwin" ? MACOS_TRUST_COMMAND_LABEL : "caddy trust";
71310
- if (!existsSync26(rootCertificatePath)) {
71536
+ if (!existsSync27(rootCertificatePath)) {
71311
71537
  return {
71312
71538
  status: "unavailable",
71313
71539
  rootCertificatePath,
@@ -71477,7 +71703,7 @@ var init_local_edge_dependencies = __esm(() => {
71477
71703
  // ../../apps/desktop/src/core/setup/terminal-pty-dependencies.ts
71478
71704
  import { spawnSync as spawnSync4 } from "child_process";
71479
71705
  import { createRequire as createRequire2 } from "module";
71480
- import { dirname as dirname21, join as join32 } from "path";
71706
+ import { dirname as dirname21, join as join33 } from "path";
71481
71707
  import { fileURLToPath as fileURLToPath9 } from "url";
71482
71708
  function renderMissingBindingDetail(bindingPackage) {
71483
71709
  return `${bindingPackage} is not installed. Reinstall @openscout/scout and ensure optional dependencies are not disabled.`;
@@ -71504,7 +71730,7 @@ function defaultResolveModule(specifier, fromPath) {
71504
71730
  }
71505
71731
  function defaultRelayBundlePath() {
71506
71732
  const selfDir = dirname21(fileURLToPath9(import.meta.url));
71507
- return join32(selfDir, "openscout-terminal-relay.mjs");
71733
+ return join33(selfDir, "openscout-terminal-relay.mjs");
71508
71734
  }
71509
71735
  function firstNonEmptyLine2(value) {
71510
71736
  return value.split(/\r?\n/g).map((line) => line.trim()).find(Boolean) ?? null;
@@ -71638,8 +71864,8 @@ var init_terminal_pty_dependencies = __esm(() => {
71638
71864
 
71639
71865
  // ../../apps/desktop/src/core/setup/service.ts
71640
71866
  import { lookup } from "dns/promises";
71641
- import { homedir as homedir24 } from "os";
71642
- import { join as join33 } from "path";
71867
+ import { homedir as homedir25 } from "os";
71868
+ import { join as join34 } from "path";
71643
71869
  import { Socket as Socket3 } from "net";
71644
71870
  async function loadScoutDoctorReport(input) {
71645
71871
  return withScoutCoreCommandLock("doctor", async () => {
@@ -71700,7 +71926,7 @@ async function loadScoutLocalEdgeDoctorReport(env) {
71700
71926
  state,
71701
71927
  portalHost,
71702
71928
  nodeHost: localEdgeConfig.nodeHost,
71703
- caddyfilePath: join33(homedir24(), ".scout", "local-edge", "Caddyfile"),
71929
+ caddyfilePath: join34(homedir25(), ".scout", "local-edge", "Caddyfile"),
71704
71930
  dependency,
71705
71931
  dns: {
71706
71932
  portal: portalDns,
@@ -71810,12 +72036,12 @@ var init_service3 = __esm(() => {
71810
72036
  });
71811
72037
 
71812
72038
  // ../../apps/desktop/src/shared/paths.ts
71813
- import { existsSync as existsSync27, readFileSync as readFileSync13 } from "fs";
71814
- import { dirname as dirname22, join as join34, resolve as resolve22 } from "path";
72039
+ import { existsSync as existsSync28, readFileSync as readFileSync13 } from "fs";
72040
+ import { dirname as dirname22, join as join35, resolve as resolve22 } from "path";
71815
72041
  import { fileURLToPath as fileURLToPath10 } from "url";
71816
72042
  function looksLikeWorkspaceRoot(candidate) {
71817
- const packageJsonPath = join34(candidate, "package.json");
71818
- if (!existsSync27(packageJsonPath)) {
72043
+ const packageJsonPath = join35(candidate, "package.json");
72044
+ if (!existsSync28(packageJsonPath)) {
71819
72045
  return false;
71820
72046
  }
71821
72047
  try {
@@ -71826,8 +72052,8 @@ function looksLikeWorkspaceRoot(candidate) {
71826
72052
  }
71827
72053
  }
71828
72054
  function looksLikePackagedAppRoot(candidate) {
71829
- const packageJsonPath = join34(candidate, "package.json");
71830
- if (!existsSync27(packageJsonPath)) {
72055
+ const packageJsonPath = join35(candidate, "package.json");
72056
+ if (!existsSync28(packageJsonPath)) {
71831
72057
  return false;
71832
72058
  }
71833
72059
  try {
@@ -71838,7 +72064,7 @@ function looksLikePackagedAppRoot(candidate) {
71838
72064
  }
71839
72065
  }
71840
72066
  function looksLikeSourceAppRoot(candidate) {
71841
- return existsSync27(join34(candidate, "bin", "scout.ts"));
72067
+ return existsSync28(join35(candidate, "bin", "scout.ts"));
71842
72068
  }
71843
72069
  function findMatchingAncestor(startDirectory, predicate) {
71844
72070
  let current = resolve22(startDirectory);
@@ -71911,17 +72137,17 @@ function shouldRestartBrokerForCliMtime(currentMtimeMs, persistedMtimeMs) {
71911
72137
  function shouldEnsureBrokerUptodateForCommand(command) {
71912
72138
  return command !== "mcp" && command !== "statusline";
71913
72139
  }
71914
- function isRecord10(value) {
72140
+ function isRecord11(value) {
71915
72141
  return typeof value === "object" && value !== null && !Array.isArray(value);
71916
72142
  }
71917
72143
  function readNonEmptyString(value) {
71918
72144
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
71919
72145
  }
71920
- function firstNonEmptyString2(values) {
72146
+ function firstNonEmptyString3(values) {
71921
72147
  for (const value of values) {
71922
- const stringValue11 = readNonEmptyString(value);
71923
- if (stringValue11) {
71924
- return stringValue11;
72148
+ const stringValue12 = readNonEmptyString(value);
72149
+ if (stringValue12) {
72150
+ return stringValue12;
71925
72151
  }
71926
72152
  }
71927
72153
  return null;
@@ -71942,26 +72168,26 @@ function buildIdentityHasAnyValue(identity) {
71942
72168
  return Boolean(identity.display || buildIdentityHasComparableValue(identity));
71943
72169
  }
71944
72170
  function readBuildIdentityRecord(record4) {
71945
- const packageName = firstNonEmptyString2([record4.packageName, record4.name]);
71946
- const version3 = firstNonEmptyString2([
72171
+ const packageName = firstNonEmptyString3([record4.packageName, record4.name]);
72172
+ const version3 = firstNonEmptyString3([
71947
72173
  record4.version,
71948
72174
  record4.appVersion,
71949
72175
  record4.runtimeVersion,
71950
72176
  record4.cliVersion,
71951
72177
  record4.scoutVersion
71952
72178
  ]);
71953
- const commit = firstNonEmptyString2([
72179
+ const commit = firstNonEmptyString3([
71954
72180
  record4.commit,
71955
72181
  record4.gitSha,
71956
72182
  record4.gitSHA,
71957
72183
  record4.sha
71958
72184
  ]);
71959
- const buildId = firstNonEmptyString2([
72185
+ const buildId = firstNonEmptyString3([
71960
72186
  record4.buildId,
71961
72187
  record4.buildID,
71962
72188
  record4.id
71963
72189
  ]);
71964
- const display = firstNonEmptyString2([
72190
+ const display = firstNonEmptyString3([
71965
72191
  record4.identity,
71966
72192
  record4.buildIdentity,
71967
72193
  record4.runtimeBuild,
@@ -71987,7 +72213,7 @@ function readBuildIdentity(value) {
71987
72213
  version: direct
71988
72214
  };
71989
72215
  }
71990
- if (isRecord10(value)) {
72216
+ if (isRecord11(value)) {
71991
72217
  return readBuildIdentityRecord(value);
71992
72218
  }
71993
72219
  return emptyBuildIdentity();
@@ -72002,9 +72228,9 @@ function mergeBuildIdentity(primary, fallback) {
72002
72228
  };
72003
72229
  }
72004
72230
  function extractBuildIdentityFromRecord(record4) {
72005
- const healthRecord = isRecord10(record4.health) ? record4.health : null;
72006
- const statusRecord = isRecord10(record4.status) ? record4.status : null;
72007
- const healthBuild = healthRecord && isRecord10(healthRecord.build) ? readBuildIdentityRecord(healthRecord.build) : null;
72231
+ const healthRecord = isRecord11(record4.health) ? record4.health : null;
72232
+ const statusRecord = isRecord11(record4.status) ? record4.status : null;
72233
+ const healthBuild = healthRecord && isRecord11(healthRecord.build) ? readBuildIdentityRecord(healthRecord.build) : null;
72008
72234
  if (healthBuild && buildIdentityHasAnyValue(healthBuild)) {
72009
72235
  return healthBuild;
72010
72236
  }
@@ -72020,7 +72246,7 @@ function extractBuildIdentityFromRecord(record4) {
72020
72246
  return buildIdentityHasAnyValue(merged) ? merged : emptyBuildIdentity();
72021
72247
  }
72022
72248
  function extractBuildIdentityPartsFromScoutdPayload(payload) {
72023
- if (!isRecord10(payload)) {
72249
+ if (!isRecord11(payload)) {
72024
72250
  return emptyBuildIdentity();
72025
72251
  }
72026
72252
  return extractBuildIdentityFromRecord(payload);
@@ -72029,14 +72255,14 @@ function extractBuildIdentityFromScoutdPayload(payload) {
72029
72255
  return extractBuildIdentityPartsFromScoutdPayload(payload).display;
72030
72256
  }
72031
72257
  function resolveCurrentCliBuildIdentityParts(env, fallbackVersion) {
72032
- const buildId = firstNonEmptyString2([env.OPENSCOUT_BUILD_ID, env.SCOUT_BUILD_ID]);
72033
- const commit = firstNonEmptyString2([
72258
+ const buildId = firstNonEmptyString3([env.OPENSCOUT_BUILD_ID, env.SCOUT_BUILD_ID]);
72259
+ const commit = firstNonEmptyString3([
72034
72260
  env.OPENSCOUT_BUILD_COMMIT,
72035
72261
  env.OPENSCOUT_BUILD_SHA,
72036
72262
  env.GIT_COMMIT,
72037
72263
  env.GIT_SHA
72038
72264
  ]);
72039
- const version3 = firstNonEmptyString2([
72265
+ const version3 = firstNonEmptyString3([
72040
72266
  env.SCOUT_APP_VERSION,
72041
72267
  env.OPENSCOUT_VERSION,
72042
72268
  env.npm_package_version,
@@ -72218,7 +72444,7 @@ async function runNativeScoutdJson(command, options = {}) {
72218
72444
  });
72219
72445
  });
72220
72446
  }
72221
- function isRecord11(value) {
72447
+ function isRecord12(value) {
72222
72448
  return typeof value === "object" && value !== null && !Array.isArray(value);
72223
72449
  }
72224
72450
  function hasOwn(record4, key) {
@@ -72237,7 +72463,7 @@ function diagnosticText(value) {
72237
72463
  const direct = readString5(value);
72238
72464
  if (direct)
72239
72465
  return direct;
72240
- if (isRecord11(value)) {
72466
+ if (isRecord12(value)) {
72241
72467
  const message = readString5(value.message) ?? readString5(value.detail) ?? readString5(value.title) ?? readString5(value.id);
72242
72468
  if (message)
72243
72469
  return message;
@@ -72259,7 +72485,7 @@ function readProcesses(value) {
72259
72485
  return [];
72260
72486
  }
72261
72487
  return value.flatMap((entry) => {
72262
- if (!isRecord11(entry)) {
72488
+ if (!isRecord12(entry)) {
72263
72489
  return [];
72264
72490
  }
72265
72491
  const command = readString5(entry.command);
@@ -72287,7 +72513,7 @@ function normalizeFixEntry(value, fallbackId = null) {
72287
72513
  changed: null
72288
72514
  };
72289
72515
  }
72290
- if (!isRecord11(value)) {
72516
+ if (!isRecord12(value)) {
72291
72517
  return null;
72292
72518
  }
72293
72519
  const id = readString5(value.id) ?? fallbackId;
@@ -72306,13 +72532,13 @@ function readFixEntries(value) {
72306
72532
  if (Array.isArray(value)) {
72307
72533
  return value.map((entry) => normalizeFixEntry(entry)).filter((entry) => Boolean(entry));
72308
72534
  }
72309
- if (!isRecord11(value)) {
72535
+ if (!isRecord12(value)) {
72310
72536
  return [];
72311
72537
  }
72312
72538
  return Object.entries(value).map(([key, entry]) => normalizeFixEntry(entry, key)).filter((entry) => Boolean(entry));
72313
72539
  }
72314
72540
  function readFixReport(raw) {
72315
- if (!isRecord11(raw)) {
72541
+ if (!isRecord12(raw)) {
72316
72542
  return { supported: false, entries: [], raw: null };
72317
72543
  }
72318
72544
  for (const key of ["fixes", "repairs", "repairActions", "actions"]) {
@@ -72326,7 +72552,7 @@ function readFixReport(raw) {
72326
72552
  }
72327
72553
  if (hasOwn(raw, "fix")) {
72328
72554
  const fix = raw.fix;
72329
- if (isRecord11(fix)) {
72555
+ if (isRecord12(fix)) {
72330
72556
  const entries = readFixEntries(fix.actions).concat(readFixEntries(fix.fixes)).concat(readFixEntries(fix.repairs));
72331
72557
  return {
72332
72558
  supported: readBoolean2(fix.supported) ?? true,
@@ -72343,11 +72569,12 @@ function readFixReport(raw) {
72343
72569
  return { supported: false, entries: [], raw: null };
72344
72570
  }
72345
72571
  function readStatus(raw) {
72346
- if (!isRecord11(raw)) {
72572
+ if (!isRecord12(raw)) {
72347
72573
  return null;
72348
72574
  }
72349
- const status = isRecord11(raw.status) ? raw.status : raw;
72350
- const health = isRecord11(status.health) ? status.health : {};
72575
+ const status = isRecord12(raw.status) ? raw.status : raw;
72576
+ const health = isRecord12(status.health) ? status.health : {};
72577
+ const runtimeFreshness = isRecord12(status.runtimeFreshness) ? status.runtimeFreshness : null;
72351
72578
  return {
72352
72579
  label: readString5(status.label),
72353
72580
  loaded: readBoolean2(status.loaded),
@@ -72360,20 +72587,26 @@ function readStatus(raw) {
72360
72587
  healthError: readString5(health.error),
72361
72588
  brokerUrl: readString5(status.brokerUrl),
72362
72589
  brokerSocketPath: readString5(status.brokerSocketPath),
72363
- scoutdStatePath: readString5(status.scoutdStatePath)
72590
+ scoutdStatePath: readString5(status.scoutdStatePath),
72591
+ runtimeFreshness: runtimeFreshness && readString5(runtimeFreshness.state) ? {
72592
+ state: readString5(runtimeFreshness.state),
72593
+ intentional: readBoolean2(runtimeFreshness.intentional),
72594
+ basis: readString5(runtimeFreshness.basis),
72595
+ detail: readString5(runtimeFreshness.detail)
72596
+ } : null
72364
72597
  };
72365
72598
  }
72366
72599
  function readProbeStatus(raw) {
72367
- if (!isRecord11(raw)) {
72600
+ if (!isRecord12(raw)) {
72368
72601
  return null;
72369
72602
  }
72370
- const status = isRecord11(raw.status) ? raw.status : raw;
72371
- const probes = isRecord11(status.probes) ? status.probes : isRecord11(raw.probes) ? raw.probes : null;
72603
+ const status = isRecord12(raw.status) ? raw.status : raw;
72604
+ const probes = isRecord12(status.probes) ? status.probes : isRecord12(raw.probes) ? raw.probes : null;
72372
72605
  if (!probes) {
72373
72606
  return null;
72374
72607
  }
72375
72608
  const families = Array.isArray(probes.families) ? probes.families.flatMap((entry) => {
72376
- if (!isRecord11(entry))
72609
+ if (!isRecord12(entry))
72377
72610
  return [];
72378
72611
  const probeId = readString5(entry.probeId);
72379
72612
  if (!probeId)
@@ -72395,7 +72628,7 @@ function readProbeStatus(raw) {
72395
72628
  }
72396
72629
  function normalizeNativeScoutdDoctorReport(input) {
72397
72630
  const raw = input.raw;
72398
- const record4 = isRecord11(raw) ? raw : {};
72631
+ const record4 = isRecord12(raw) ? raw : {};
72399
72632
  return {
72400
72633
  available: input.available ?? true,
72401
72634
  scoutdPath: input.scoutdPath,
@@ -72506,6 +72739,12 @@ function renderNativeScoutdDoctorSection(report) {
72506
72739
  if (status.scoutdStatePath) {
72507
72740
  lines.push(` State file: ${status.scoutdStatePath}`);
72508
72741
  }
72742
+ if (status.runtimeFreshness) {
72743
+ lines.push(` Runtime freshness: ${status.runtimeFreshness.state}${status.runtimeFreshness.intentional ? " (intentional)" : ""}`);
72744
+ if (status.runtimeFreshness.detail) {
72745
+ lines.push(` Runtime detail: ${status.runtimeFreshness.detail}`);
72746
+ }
72747
+ }
72509
72748
  }
72510
72749
  if (report.probes) {
72511
72750
  lines.push(" Probes:", ` Socket: ${report.probes.socketPath ?? "-"}`, ` Reachable: ${yesNo(report.probes.reachable)}`, ` Daemon version: ${report.probes.daemonVersion ?? "-"}`);
@@ -72972,8 +73211,8 @@ var exports_env = {};
72972
73211
  __export(exports_env, {
72973
73212
  runEnvCommand: () => runEnvCommand
72974
73213
  });
72975
- import { existsSync as existsSync28 } from "fs";
72976
- import { join as join35 } from "path";
73214
+ import { existsSync as existsSync29 } from "fs";
73215
+ import { join as join36 } from "path";
72977
73216
  function resolveCommandOnPath(command, env) {
72978
73217
  const pathValue = env.PATH ?? "";
72979
73218
  for (const directory of pathValue.split(":")) {
@@ -72981,8 +73220,8 @@ function resolveCommandOnPath(command, env) {
72981
73220
  if (!trimmed) {
72982
73221
  continue;
72983
73222
  }
72984
- const candidate = join35(trimmed, command);
72985
- if (existsSync28(candidate)) {
73223
+ const candidate = join36(trimmed, command);
73224
+ if (existsSync29(candidate)) {
72986
73225
  return candidate;
72987
73226
  }
72988
73227
  }
@@ -72990,11 +73229,11 @@ function resolveCommandOnPath(command, env) {
72990
73229
  }
72991
73230
  function resolveScoutBinPath(appRoot) {
72992
73231
  const candidates = [
72993
- join35(appRoot, "bin", "scout.ts"),
72994
- join35(appRoot, "bin", "scout.mjs")
73232
+ join36(appRoot, "bin", "scout.ts"),
73233
+ join36(appRoot, "bin", "scout.mjs")
72995
73234
  ];
72996
73235
  for (const candidate of candidates) {
72997
- if (existsSync28(candidate)) {
73236
+ if (existsSync29(candidate)) {
72998
73237
  return candidate;
72999
73238
  }
73000
73239
  }
@@ -73531,9 +73770,9 @@ __export(exports_install, {
73531
73770
  findAppDmgAsset: () => findAppDmgAsset
73532
73771
  });
73533
73772
  import { spawnSync as spawnSync5 } from "child_process";
73534
- import { existsSync as existsSync29, mkdtempSync, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "fs";
73773
+ import { existsSync as existsSync30, mkdtempSync, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "fs";
73535
73774
  import { tmpdir } from "os";
73536
- import { join as join36 } from "path";
73775
+ import { join as join37 } from "path";
73537
73776
  function renderInstallCommandHelp() {
73538
73777
  return [
73539
73778
  "scout install \u2014 download and install the OpenScout macOS app",
@@ -73612,7 +73851,7 @@ function formatBytes(bytes) {
73612
73851
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
73613
73852
  }
73614
73853
  function getInstalledVersion() {
73615
- if (!existsSync29(INFO_PLIST_PATH))
73854
+ if (!existsSync30(INFO_PLIST_PATH))
73616
73855
  return null;
73617
73856
  const result = spawnSync5("defaults", ["read", INFO_PLIST_PATH, "CFBundleShortVersionString"], { encoding: "utf8" });
73618
73857
  if ((result.status ?? 1) !== 0)
@@ -73690,8 +73929,8 @@ function copyAppFromMount(mountPoint) {
73690
73929
  if (!appEntry) {
73691
73930
  throw new ScoutCliError(`no ${APP_NAME} found in the mounted DMG at ${mountPoint}`);
73692
73931
  }
73693
- const source = join36(mountPoint, appEntry);
73694
- if (existsSync29(APP_PATH)) {
73932
+ const source = join37(mountPoint, appEntry);
73933
+ if (existsSync30(APP_PATH)) {
73695
73934
  const removed = spawnSync5("rm", ["-rf", APP_PATH], { encoding: "utf8" });
73696
73935
  if ((removed.status ?? 1) !== 0) {
73697
73936
  throw new ScoutCliError(`could not replace ${APP_PATH} (permission denied?). Try: sudo scout install`);
@@ -73779,8 +74018,8 @@ async function runInstallCommand(context, args) {
73779
74018
  }
73780
74019
  const asset = findAppDmgAsset(release);
73781
74020
  const wasRunning = isAppRunning();
73782
- const workDir = mkdtempSync(join36(tmpdir(), "scout-install-"));
73783
- const dmgPath = join36(workDir, asset.name);
74021
+ const workDir = mkdtempSync(join37(tmpdir(), "scout-install-"));
74022
+ const dmgPath = join37(workDir, asset.name);
73784
74023
  let mountPoint = null;
73785
74024
  try {
73786
74025
  await downloadDmg(asset, dmgPath, context);
@@ -81074,9 +81313,9 @@ var init_scout_mcp = __esm(() => {
81074
81313
 
81075
81314
  // ../../apps/desktop/src/cli/commands/mcp-install.ts
81076
81315
  import { spawnSync as spawnSync6 } from "child_process";
81077
- import { accessSync as accessSync4, constants as constants4, existsSync as existsSync30 } from "fs";
81078
- import { homedir as homedir25 } from "os";
81079
- import { delimiter as delimiter4, join as join37, resolve as resolve24 } from "path";
81316
+ import { accessSync as accessSync4, constants as constants4, existsSync as existsSync31 } from "fs";
81317
+ import { homedir as homedir26 } from "os";
81318
+ import { delimiter as delimiter4, join as join38, resolve as resolve24 } from "path";
81080
81319
  function isExecutable3(filePath) {
81081
81320
  if (!filePath) {
81082
81321
  return false;
@@ -81091,15 +81330,15 @@ function isExecutable3(filePath) {
81091
81330
  function resolveExecutableFromSearchPath2(names, env) {
81092
81331
  const pathEntries = (env.PATH ?? "").split(delimiter4).filter(Boolean);
81093
81332
  const commonDirectories = [
81094
- join37(homedir25(), ".local", "bin"),
81095
- join37(homedir25(), ".bun", "bin"),
81333
+ join38(homedir26(), ".local", "bin"),
81334
+ join38(homedir26(), ".bun", "bin"),
81096
81335
  "/opt/homebrew/bin",
81097
81336
  "/usr/local/bin",
81098
81337
  "/Applications/Codex.app/Contents/Resources"
81099
81338
  ];
81100
81339
  for (const directory of [...pathEntries, ...commonDirectories]) {
81101
81340
  for (const name of names) {
81102
- const candidate = join37(directory, name);
81341
+ const candidate = join38(directory, name);
81103
81342
  if (isExecutable3(candidate)) {
81104
81343
  return candidate;
81105
81344
  }
@@ -81115,7 +81354,7 @@ function resolveHostExecutable(host, env) {
81115
81354
  }
81116
81355
  function resolveCurrentScoutMcpLaunchCommand(env) {
81117
81356
  const currentScript = process.argv[1];
81118
- if (currentScript && existsSync30(currentScript) && isExecutable3(process.execPath)) {
81357
+ if (currentScript && existsSync31(currentScript) && isExecutable3(process.execPath)) {
81119
81358
  return {
81120
81359
  command: process.execPath,
81121
81360
  args: [resolve24(currentScript), "mcp"]
@@ -81486,9 +81725,9 @@ __export(exports_menu, {
81486
81725
  parseMenuCommand: () => parseMenuCommand
81487
81726
  });
81488
81727
  import { spawnSync as spawnSync7 } from "child_process";
81489
- import { existsSync as existsSync31 } from "fs";
81490
- import { homedir as homedir26 } from "os";
81491
- import { dirname as dirname23, join as join38, resolve as resolve25 } from "path";
81728
+ import { existsSync as existsSync32 } from "fs";
81729
+ import { homedir as homedir27 } from "os";
81730
+ import { dirname as dirname23, join as join39, resolve as resolve25 } from "path";
81492
81731
  import { fileURLToPath as fileURLToPath11 } from "url";
81493
81732
  function renderMenuCommandHelp() {
81494
81733
  return [
@@ -81575,8 +81814,8 @@ function runProcess(command, args, options) {
81575
81814
  function findRepoMenuHelper(startDirectory) {
81576
81815
  let current = resolve25(startDirectory);
81577
81816
  while (true) {
81578
- const candidate = join38(current, "apps", "macos", "bin", "openscout-menu.ts");
81579
- if (existsSync31(candidate)) {
81817
+ const candidate = join39(current, "apps", "macos", "bin", "openscout-menu.ts");
81818
+ if (existsSync32(candidate)) {
81580
81819
  return candidate;
81581
81820
  }
81582
81821
  const parent = dirname23(current);
@@ -81586,7 +81825,7 @@ function findRepoMenuHelper(startDirectory) {
81586
81825
  current = parent;
81587
81826
  }
81588
81827
  const sourceRelativeCandidate = fileURLToPath11(new URL("../../../../macos/bin/openscout-menu.ts", import.meta.url).toString());
81589
- return existsSync31(sourceRelativeCandidate) ? sourceRelativeCandidate : null;
81828
+ return existsSync32(sourceRelativeCandidate) ? sourceRelativeCandidate : null;
81590
81829
  }
81591
81830
  function resolveRepoBundlePath(helperPath) {
81592
81831
  return resolve25(dirname23(helperPath), "..", "dist", MENU_BUNDLE_NAME);
@@ -81605,14 +81844,14 @@ function resolveInstalledAppBundlePath(env) {
81605
81844
  return indexedPath;
81606
81845
  }
81607
81846
  for (const candidate of COMMON_APP_BUNDLE_PATHS) {
81608
- if (existsSync31(candidate)) {
81847
+ if (existsSync32(candidate)) {
81609
81848
  return candidate;
81610
81849
  }
81611
81850
  }
81612
81851
  return null;
81613
81852
  }
81614
81853
  function resolveEmbeddedMenuBundlePath(appBundlePath) {
81615
- return join38(appBundlePath, EMBEDDED_MENU_RELATIVE_PATH);
81854
+ return join39(appBundlePath, EMBEDDED_MENU_RELATIVE_PATH);
81616
81855
  }
81617
81856
  function openInstalledMenuApp(helperPath, env) {
81618
81857
  const bundleAttempts = [
@@ -81688,7 +81927,7 @@ function runWithRepoHelper(context, helperPath, command) {
81688
81927
  });
81689
81928
  const bundlePath = resolveRepoBundlePath(helperPath);
81690
81929
  const running = command.action === "quit" ? false : isMenuRunning(context.env);
81691
- const installed = existsSync31(bundlePath) || running;
81930
+ const installed = existsSync32(bundlePath) || running;
81692
81931
  return {
81693
81932
  action: command.action,
81694
81933
  mode: "repo-helper",
@@ -81759,11 +81998,11 @@ var init_menu = __esm(() => {
81759
81998
  init_src3();
81760
81999
  init_context();
81761
82000
  init_errors();
81762
- EMBEDDED_MENU_RELATIVE_PATH = join38("Contents", "Library", "LoginItems", "ScoutMenu.app");
82001
+ EMBEDDED_MENU_RELATIVE_PATH = join39("Contents", "Library", "LoginItems", "ScoutMenu.app");
81763
82002
  HELP_FLAGS11 = new Set(["help", "--help", "-h"]);
81764
82003
  COMMON_APP_BUNDLE_PATHS = [
81765
- join38("/Applications", APP_BUNDLE_NAME),
81766
- join38(homedir26(), "Applications", APP_BUNDLE_NAME)
82004
+ join39("/Applications", APP_BUNDLE_NAME),
82005
+ join39(homedir27(), "Applications", APP_BUNDLE_NAME)
81767
82006
  ];
81768
82007
  });
81769
82008
 
@@ -82201,11 +82440,11 @@ var init_mesh = __esm(() => {
82201
82440
  });
82202
82441
 
82203
82442
  // ../../apps/desktop/src/core/pairing/runtime/config.ts
82204
- import { existsSync as existsSync32, mkdirSync as mkdirSync7, readFileSync as readFileSync15, writeFileSync as writeFileSync6 } from "fs";
82205
- import { homedir as homedir27 } from "os";
82443
+ import { existsSync as existsSync33, mkdirSync as mkdirSync7, readFileSync as readFileSync15, writeFileSync as writeFileSync6 } from "fs";
82444
+ import { homedir as homedir28 } from "os";
82206
82445
  import path from "path";
82207
82446
  function pairingPaths() {
82208
- const rootDir = path.join(homedir27(), ".scout/pairing");
82447
+ const rootDir = path.join(homedir28(), ".scout/pairing");
82209
82448
  return {
82210
82449
  rootDir,
82211
82450
  configPath: path.join(rootDir, "config.json"),
@@ -82218,7 +82457,7 @@ function pairingPaths() {
82218
82457
  }
82219
82458
  function loadPairingConfig() {
82220
82459
  const { configPath } = pairingPaths();
82221
- if (!existsSync32(configPath)) {
82460
+ if (!existsSync33(configPath)) {
82222
82461
  return {};
82223
82462
  }
82224
82463
  try {
@@ -84322,11 +84561,11 @@ var init_noise = __esm(() => {
84322
84561
  });
84323
84562
 
84324
84563
  // ../../apps/desktop/src/core/pairing/runtime/security/identity.ts
84325
- import { existsSync as existsSync33, mkdirSync as mkdirSync8, readFileSync as readFileSync16, writeFileSync as writeFileSync7 } from "fs";
84326
- import { join as join39 } from "path";
84327
- import { homedir as homedir28 } from "os";
84564
+ import { existsSync as existsSync34, mkdirSync as mkdirSync8, readFileSync as readFileSync16, writeFileSync as writeFileSync7 } from "fs";
84565
+ import { join as join40 } from "path";
84566
+ import { homedir as homedir29 } from "os";
84328
84567
  function loadOrCreateIdentity() {
84329
- if (existsSync33(IDENTITY_FILE)) {
84568
+ if (existsSync34(IDENTITY_FILE)) {
84330
84569
  return loadIdentity();
84331
84570
  }
84332
84571
  return createAndSaveIdentity();
@@ -84350,7 +84589,7 @@ function createAndSaveIdentity() {
84350
84589
  return keyPair;
84351
84590
  }
84352
84591
  function loadTrustedPeers() {
84353
- if (!existsSync33(TRUSTED_PEERS_FILE))
84592
+ if (!existsSync34(TRUSTED_PEERS_FILE))
84354
84593
  return new Map;
84355
84594
  const data = JSON.parse(readFileSync16(TRUSTED_PEERS_FILE, "utf8"));
84356
84595
  return new Map(data.map((p) => [p.publicKey, p]));
@@ -84401,9 +84640,9 @@ function hexToBytes2(hex3) {
84401
84640
  var PAIRING_DIR, IDENTITY_FILE, TRUSTED_PEERS_FILE, QR_VERSION = 1, QR_EXPIRY_MS;
84402
84641
  var init_identity = __esm(() => {
84403
84642
  init_noise();
84404
- PAIRING_DIR = join39(homedir28(), ".scout/pairing");
84405
- IDENTITY_FILE = join39(PAIRING_DIR, "identity.json");
84406
- TRUSTED_PEERS_FILE = join39(PAIRING_DIR, "trusted-peers.json");
84643
+ PAIRING_DIR = join40(homedir29(), ".scout/pairing");
84644
+ IDENTITY_FILE = join40(PAIRING_DIR, "identity.json");
84645
+ TRUSTED_PEERS_FILE = join40(PAIRING_DIR, "trusted-peers.json");
84407
84646
  QR_EXPIRY_MS = 5 * 60 * 1000;
84408
84647
  });
84409
84648
 
@@ -84564,10 +84803,10 @@ var init_security2 = __esm(() => {
84564
84803
  });
84565
84804
 
84566
84805
  // ../../apps/desktop/src/core/pairing/runtime/runtime-state.ts
84567
- import { existsSync as existsSync34, mkdirSync as mkdirSync9, readFileSync as readFileSync17, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync8 } from "fs";
84806
+ import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync17, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync8 } from "fs";
84568
84807
  function readPairingRuntimeSnapshot() {
84569
84808
  const { runtimeStatePath } = pairingPaths();
84570
- if (!existsSync34(runtimeStatePath)) {
84809
+ if (!existsSync35(runtimeStatePath)) {
84571
84810
  return null;
84572
84811
  }
84573
84812
  try {
@@ -84595,8 +84834,8 @@ var init_runtime_state = __esm(() => {
84595
84834
 
84596
84835
  // ../../apps/desktop/src/core/pairing/runtime/bridge/log.ts
84597
84836
  import { appendFileSync, mkdirSync as mkdirSync10 } from "fs";
84598
- import { join as join40 } from "path";
84599
- import { homedir as homedir29 } from "os";
84837
+ import { join as join41 } from "path";
84838
+ import { homedir as homedir30 } from "os";
84600
84839
  function write(level, category, message, data) {
84601
84840
  const ts = new Date().toISOString().slice(11, 23);
84602
84841
  const lvl = level.toUpperCase().padEnd(5);
@@ -84612,8 +84851,8 @@ function write(level, category, message, data) {
84612
84851
  }
84613
84852
  var LOG_DIR, LOG_FILE, log;
84614
84853
  var init_log = __esm(() => {
84615
- LOG_DIR = join40(homedir29(), ".scout/pairing");
84616
- LOG_FILE = join40(LOG_DIR, "bridge.log");
84854
+ LOG_DIR = join41(homedir30(), ".scout/pairing");
84855
+ LOG_FILE = join41(LOG_DIR, "bridge.log");
84617
84856
  mkdirSync10(LOG_DIR, { recursive: true });
84618
84857
  log = {
84619
84858
  debug: (cat, msg, data) => write("debug", cat, msg, data),
@@ -84689,11 +84928,11 @@ var init_bridge = __esm(() => {
84689
84928
  });
84690
84929
 
84691
84930
  // ../../apps/desktop/src/core/pairing/runtime/bridge/config.ts
84692
- import { existsSync as existsSync35, readFileSync as readFileSync18 } from "fs";
84693
- import { join as join41 } from "path";
84694
- import { homedir as homedir30 } from "os";
84931
+ import { existsSync as existsSync36, readFileSync as readFileSync18 } from "fs";
84932
+ import { join as join42 } from "path";
84933
+ import { homedir as homedir31 } from "os";
84695
84934
  function loadConfigFile() {
84696
- if (!existsSync35(CONFIG_FILE)) {
84935
+ if (!existsSync36(CONFIG_FILE)) {
84697
84936
  return {};
84698
84937
  }
84699
84938
  try {
@@ -84767,8 +85006,8 @@ var init_config3 = __esm(() => {
84767
85006
  port: 43130,
84768
85007
  secure: true
84769
85008
  };
84770
- CONFIG_DIR = join41(homedir30(), ".scout/pairing");
84771
- CONFIG_FILE = join41(CONFIG_DIR, "config.json");
85009
+ CONFIG_DIR = join42(homedir31(), ".scout/pairing");
85010
+ CONFIG_FILE = join42(CONFIG_DIR, "config.json");
84772
85011
  });
84773
85012
 
84774
85013
  // ../../apps/desktop/src/core/pairing/runtime/bridge/web-handoff.ts
@@ -84836,9 +85075,9 @@ var init_web_handoff = __esm(() => {
84836
85075
 
84837
85076
  // ../../apps/desktop/src/core/pairing/runtime/bridge/fileserver.ts
84838
85077
  import { randomUUID as randomUUID4 } from "crypto";
84839
- import { existsSync as existsSync36, mkdirSync as mkdirSync11, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
84840
- import { isAbsolute as isAbsolute4, join as join42 } from "path";
84841
- import { homedir as homedir31 } from "os";
85078
+ import { existsSync as existsSync37, mkdirSync as mkdirSync11, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
85079
+ import { isAbsolute as isAbsolute4, join as join43 } from "path";
85080
+ import { homedir as homedir32 } from "os";
84842
85081
  function pairingFileServerOrigin(port, host = "127.0.0.1") {
84843
85082
  return `http://${host}:${port}`;
84844
85083
  }
@@ -84857,7 +85096,7 @@ function storePairingAttachmentBlob(input, options) {
84857
85096
  mkdirSync11(PAIRING_ATTACHMENT_ROOT, { recursive: true, mode: 448 });
84858
85097
  purgeExpiredPairingAttachments(options.now);
84859
85098
  const id = `att-${randomUUID4()}`;
84860
- const path2 = join42(PAIRING_ATTACHMENT_ROOT, id);
85099
+ const path2 = join43(PAIRING_ATTACHMENT_ROOT, id);
84861
85100
  writeFileSync9(path2, data, { mode: 384 });
84862
85101
  const now = options.now ?? Date.now();
84863
85102
  const entry = {
@@ -84886,7 +85125,7 @@ function isTrustedLoopbackHostname(hostname5) {
84886
85125
  function isAllowedPath(filePath) {
84887
85126
  if (!isAbsolute4(filePath))
84888
85127
  return false;
84889
- const relToHome = filePath.slice(homedir31().length + 1);
85128
+ const relToHome = filePath.slice(homedir32().length + 1);
84890
85129
  if (relToHome.startsWith(".") && !relToHome.startsWith(".claude") && !relToHome.startsWith(".scout/pairing")) {
84891
85130
  return false;
84892
85131
  }
@@ -84960,7 +85199,7 @@ function servePairingAttachment(url2) {
84960
85199
  return new Response("Missing attachment id", { status: 400 });
84961
85200
  }
84962
85201
  const entry = attachmentBlobs.get(id);
84963
- if (!entry || entry.expiresAt <= Date.now() || !existsSync36(entry.path)) {
85202
+ if (!entry || entry.expiresAt <= Date.now() || !existsSync37(entry.path)) {
84964
85203
  if (entry) {
84965
85204
  attachmentBlobs.delete(entry.id);
84966
85205
  }
@@ -85519,18 +85758,18 @@ function formatTimestamp(value) {
85519
85758
  var ALLOWED_ROOTS, LOOPBACK_IPV4_HOST_PATTERN, PAIRING_ATTACHMENT_ROOT, PAIRING_ATTACHMENT_TTL_MS, PAIRING_ATTACHMENT_MAX_BYTES, PAIRING_ATTACHMENT_PATH_PREFIX = "/attachments/", attachmentBlobs;
85520
85759
  var init_fileserver = __esm(() => {
85521
85760
  init_web_handoff();
85522
- ALLOWED_ROOTS = [homedir31(), "/tmp"];
85761
+ ALLOWED_ROOTS = [homedir32(), "/tmp"];
85523
85762
  LOOPBACK_IPV4_HOST_PATTERN = /^127(?:\.\d{1,3}){3}$/;
85524
- PAIRING_ATTACHMENT_ROOT = join42(homedir31(), ".scout", "pairing", "attachments");
85763
+ PAIRING_ATTACHMENT_ROOT = join43(homedir32(), ".scout", "pairing", "attachments");
85525
85764
  PAIRING_ATTACHMENT_TTL_MS = 6 * 60 * 60 * 1000;
85526
85765
  PAIRING_ATTACHMENT_MAX_BYTES = 25 * 1024 * 1024;
85527
85766
  attachmentBlobs = new Map;
85528
85767
  });
85529
85768
 
85530
85769
  // ../runtime/src/agent-workspace.ts
85531
- import { existsSync as existsSync37 } from "fs";
85770
+ import { existsSync as existsSync38 } from "fs";
85532
85771
  import { mkdir as mkdir12 } from "fs/promises";
85533
- import { join as join43 } from "path";
85772
+ import { join as join44 } from "path";
85534
85773
  async function isGitRepo(projectRoot) {
85535
85774
  try {
85536
85775
  await execSystemFile("git", ["rev-parse", "--git-dir"], { cwd: projectRoot, timeoutMs: 2000 });
@@ -85550,9 +85789,9 @@ async function createAgentWorkspace(projectRoot, agentName, requestedBranch) {
85550
85789
  }
85551
85790
  const branch = requestedBranch?.trim() || `scout/${agentName}`;
85552
85791
  validateWorktreeBranch(branch);
85553
- const workspaceDir = join43(projectRoot, SCOUT_WORKSPACES_DIRNAME);
85554
- const workspacePath = join43(workspaceDir, agentName);
85555
- if (existsSync37(workspacePath)) {
85792
+ const workspaceDir = join44(projectRoot, SCOUT_WORKSPACES_DIRNAME);
85793
+ const workspacePath = join44(workspaceDir, agentName);
85794
+ if (existsSync38(workspacePath)) {
85556
85795
  return { path: workspacePath, branch };
85557
85796
  }
85558
85797
  await mkdir12(workspaceDir, { recursive: true });
@@ -85575,11 +85814,11 @@ var init_agent_workspace = __esm(() => {
85575
85814
 
85576
85815
  // ../../apps/desktop/src/server/db-queries.ts
85577
85816
  import { Database as Database3 } from "bun:sqlite";
85578
- import { homedir as homedir32 } from "os";
85579
- import { join as join44 } from "path";
85817
+ import { homedir as homedir33 } from "os";
85818
+ import { join as join45 } from "path";
85580
85819
  function resolveDbPath() {
85581
- const controlHome = process.env.OPENSCOUT_CONTROL_HOME ?? join44(homedir32(), ".openscout", "control-plane");
85582
- return join44(controlHome, "control-plane.sqlite");
85820
+ const controlHome = process.env.OPENSCOUT_CONTROL_HOME ?? join45(homedir33(), ".openscout", "control-plane");
85821
+ return join45(controlHome, "control-plane.sqlite");
85583
85822
  }
85584
85823
  function db2() {
85585
85824
  if (!_db) {
@@ -85600,14 +85839,6 @@ function sqlQuoteLiteral(value) {
85600
85839
  function sqlStringList(values) {
85601
85840
  return `(${values.map(sqlQuoteLiteral).join(",")})`;
85602
85841
  }
85603
- function sqlTimestampMsExpression(valueExpression) {
85604
- return `CASE
85605
- WHEN ${valueExpression} IS NULL THEN NULL
85606
- WHEN CAST(${valueExpression} AS REAL) < ${EPOCH_MILLISECONDS_FLOOR}
85607
- THEN CAST(CAST(${valueExpression} AS REAL) * 1000 AS INTEGER)
85608
- ELSE CAST(${valueExpression} AS INTEGER)
85609
- END`;
85610
- }
85611
85842
  function queryExecutingAgentIds() {
85612
85843
  return new Set(db2().prepare(`SELECT DISTINCT target_agent_id FROM flights
85613
85844
  WHERE state = 'running'`).all().map((row) => row.target_agent_id));
@@ -85631,155 +85862,6 @@ function summarizeAgentStatusLabel(rawState, isWorking) {
85631
85862
  function conversationIdForAgent(agentId) {
85632
85863
  return `dm.operator.${agentId}`;
85633
85864
  }
85634
- function queryMobileAgents(limit = 50) {
85635
- const executingAgentIds = queryExecutingAgentIds();
85636
- const lastMessageAt = new Map(db2().prepare(`SELECT actor_id, MAX(created_at) AS last_at FROM messages GROUP BY actor_id`).all().map((r) => [r.actor_id, r.last_at]));
85637
- const rows = db2().prepare(`SELECT
85638
- a.id,
85639
- ac.display_name,
85640
- a.default_selector,
85641
- a.metadata_json,
85642
- ep.harness,
85643
- ep.transport,
85644
- ep.state,
85645
- ep.project_root,
85646
- ep.session_id,
85647
- ep.updated_at,
85648
- COALESCE(ep.node_id, a.authority_node_id, a.home_node_id) AS node_id,
85649
- n.name AS node_name
85650
- FROM agents a
85651
- JOIN actors ac ON ac.id = a.id
85652
- ${LATEST_AGENT_ENDPOINT_JOIN}
85653
- LEFT JOIN nodes n ON n.id = COALESCE(ep.node_id, a.authority_node_id, a.home_node_id)
85654
- ORDER BY COALESCE(ep.updated_at, 0) DESC, ac.display_name ASC
85655
- LIMIT ?`).all(limit);
85656
- return rows.map((r) => {
85657
- let meta3 = {};
85658
- try {
85659
- meta3 = r.metadata_json ? JSON.parse(r.metadata_json) : {};
85660
- } catch {}
85661
- const isWorking = executingAgentIds.has(r.id);
85662
- const state = summarizeAgentState(r.state, isWorking);
85663
- const statusLabel = summarizeAgentStatusLabel(r.state, isWorking);
85664
- return {
85665
- id: r.id,
85666
- title: r.display_name,
85667
- selector: meta3.selector ?? null,
85668
- defaultSelector: r.default_selector,
85669
- nodeId: compact(r.node_id),
85670
- nodeName: compact(r.node_name),
85671
- workspaceRoot: compact(r.project_root),
85672
- harness: r.harness,
85673
- transport: r.transport,
85674
- state,
85675
- statusLabel,
85676
- sessionId: conversationIdForAgent(r.id),
85677
- lastActiveAt: lastMessageAt.get(r.id) ?? null
85678
- };
85679
- });
85680
- }
85681
- function queryMobileSessions(limit = 50) {
85682
- const conversationCreatedAtExpression = sqlTimestampMsExpression("c.created_at");
85683
- const messageCreatedAtExpression = sqlTimestampMsExpression("created_at");
85684
- const previewMessageCreatedAtExpression = sqlTimestampMsExpression("created_at");
85685
- const rows = db2().prepare(`SELECT
85686
- c.id,
85687
- c.kind,
85688
- c.title,
85689
- c.metadata_json
85690
- FROM conversations c
85691
- WHERE c.kind = 'direct'
85692
- ORDER BY ${conversationCreatedAtExpression} DESC
85693
- LIMIT ?`).all(limit);
85694
- const memberStmt = db2().prepare(`SELECT actor_id FROM conversation_members WHERE conversation_id = ?`);
85695
- const statsStmt = db2().prepare(`SELECT COUNT(*) AS cnt, MAX(${messageCreatedAtExpression}) AS last_at FROM messages WHERE conversation_id = ?`);
85696
- const previewStmt = db2().prepare(`SELECT body FROM messages WHERE conversation_id = ? AND actor_id != 'operator'
85697
- ORDER BY ${previewMessageCreatedAtExpression} DESC LIMIT 1`);
85698
- return rows.map((r) => {
85699
- const participants = memberStmt.all(r.id).map((m) => m.actor_id);
85700
- const agentId = participants.find((p) => p !== "operator") ?? null;
85701
- const stats = statsStmt.get(r.id);
85702
- let agentName = null;
85703
- let harness = null;
85704
- let branch = null;
85705
- let workspaceRoot = null;
85706
- if (agentId) {
85707
- const agentRow = db2().prepare(`SELECT ac.display_name, ep.harness, ep.project_root, a.metadata_json
85708
- FROM agents a
85709
- JOIN actors ac ON ac.id = a.id
85710
- LEFT JOIN agent_endpoints ep ON ep.agent_id = a.id
85711
- WHERE a.id = ?`).get(agentId);
85712
- if (agentRow) {
85713
- agentName = agentRow.display_name;
85714
- harness = agentRow.harness;
85715
- workspaceRoot = compact(agentRow.project_root);
85716
- try {
85717
- const meta3 = agentRow.metadata_json ? JSON.parse(agentRow.metadata_json) : {};
85718
- branch = meta3.branch ?? meta3.workspaceQualifier ?? null;
85719
- } catch {}
85720
- }
85721
- }
85722
- const preview = previewStmt.get(r.id)?.body ?? null;
85723
- return {
85724
- id: r.id,
85725
- kind: r.kind,
85726
- title: agentName ?? r.title,
85727
- participantIds: participants,
85728
- agentId,
85729
- agentName,
85730
- harness,
85731
- currentBranch: branch,
85732
- preview: preview ? preview.slice(0, 200) : null,
85733
- messageCount: stats?.cnt ?? 0,
85734
- lastMessageAt: stats?.last_at ?? null,
85735
- workspaceRoot
85736
- };
85737
- });
85738
- }
85739
- function queryMobileWorkspaces(limit = 50) {
85740
- const rows = db2().prepare(`SELECT DISTINCT
85741
- ep.project_root,
85742
- ac.display_name,
85743
- a.metadata_json,
85744
- ep.harness
85745
- FROM agents a
85746
- JOIN actors ac ON ac.id = a.id
85747
- LEFT JOIN agent_endpoints ep ON ep.agent_id = a.id
85748
- WHERE ep.project_root IS NOT NULL
85749
- ORDER BY ep.updated_at DESC NULLS LAST
85750
- LIMIT ?`).all(limit);
85751
- const seen = new Set;
85752
- const results = [];
85753
- for (const r of rows) {
85754
- if (seen.has(r.project_root))
85755
- continue;
85756
- seen.add(r.project_root);
85757
- let meta3 = {};
85758
- try {
85759
- meta3 = r.metadata_json ? JSON.parse(r.metadata_json) : {};
85760
- } catch {}
85761
- const projectName = meta3.project ?? r.project_root.split("/").pop() ?? "unknown";
85762
- const relativePath = r.project_root.replace(HOME + "/", "");
85763
- results.push({
85764
- id: r.project_root,
85765
- title: projectName,
85766
- projectName,
85767
- root: r.project_root,
85768
- sourceRoot: r.project_root,
85769
- relativePath,
85770
- registrationKind: "agent",
85771
- defaultHarness: r.harness ?? "claude",
85772
- harnesses: r.harness ? [{
85773
- harness: r.harness,
85774
- source: "default",
85775
- detail: "Current endpoint",
85776
- readinessState: "ready",
85777
- readinessDetail: null
85778
- }] : []
85779
- });
85780
- }
85781
- return results;
85782
- }
85783
85865
  function queryMobileAgentDetail(agentId) {
85784
85866
  const row = db2().prepare(`SELECT
85785
85867
  a.id,
@@ -85872,8 +85954,7 @@ var _db = null, HOME, LATEST_AGENT_ENDPOINT_JOIN = `LEFT JOIN agent_endpoints ep
85872
85954
  LIMIT 1
85873
85955
  )`, ACTIVE_FLIGHT_STATES_SQL, ACTIVE_FLIGHT_MAX_AGE_MS, ACTIVE_WORK_STATES_SQL;
85874
85956
  var init_db_queries = __esm(() => {
85875
- init_src();
85876
- HOME = homedir32();
85957
+ HOME = homedir33();
85877
85958
  ACTIVE_FLIGHT_STATES_SQL = sqlStringList(["running", "waking", "waiting", "queued"]);
85878
85959
  ACTIVE_FLIGHT_MAX_AGE_MS = 24 * 60 * 60 * 1000;
85879
85960
  ACTIVE_WORK_STATES_SQL = sqlStringList(["open", "working", "waiting", "review"]);
@@ -85881,6 +85962,7 @@ var init_db_queries = __esm(() => {
85881
85962
 
85882
85963
  // ../../apps/desktop/src/core/mobile/service.ts
85883
85964
  import { basename as basename14, resolve as resolve26 } from "path";
85965
+ import { statSync as statSync6 } from "fs";
85884
85966
  function mobileLifecycleStateForFlight(flight) {
85885
85967
  switch (flight?.state) {
85886
85968
  case "queued":
@@ -85920,10 +86002,16 @@ function normalizeTimestamp(value) {
85920
86002
  function normalizeTimestampMs2(value) {
85921
86003
  return epochMs(value);
85922
86004
  }
86005
+ function requireTimestampMs(value) {
86006
+ return normalizeTimestampMs2(value) ?? 0;
86007
+ }
85923
86008
  function metadataString7(metadata, key) {
85924
86009
  const value = metadata?.[key];
85925
86010
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
85926
86011
  }
86012
+ function metadataTimestampMs(metadata, key) {
86013
+ return normalizeTimestampMs2(metadata?.[key]);
86014
+ }
85927
86015
  function metadataBoolean2(metadata, key) {
85928
86016
  return metadata?.[key] === true;
85929
86017
  }
@@ -85996,6 +86084,37 @@ async function loadMobileWorkspaceInventory(currentDirectory) {
85996
86084
  })
85997
86085
  })).sort((left, right) => left.relativePath.localeCompare(right.relativePath) || left.title.localeCompare(right.title));
85998
86086
  }
86087
+ function isDirectory2(path2) {
86088
+ try {
86089
+ return statSync6(path2).isDirectory();
86090
+ } catch {
86091
+ return false;
86092
+ }
86093
+ }
86094
+ function rehomeScoutMobileWorkspacePath(requestedPath, currentHome) {
86095
+ const requested = resolve26(requestedPath);
86096
+ const home = resolve26(currentHome);
86097
+ const requestedMatch = requested.match(/^\/Users\/[^/]+(\/.*)?$/);
86098
+ if (!requestedMatch || !/^\/Users\/[^/]+$/.test(home))
86099
+ return null;
86100
+ const suffix = requestedMatch[1] ?? "";
86101
+ return resolve26(home, `.${suffix || "/"}`);
86102
+ }
86103
+ async function resolveMobileWorkspaceRoot(rawWorkspaceId, currentDirectory) {
86104
+ const requested = resolve26(rawWorkspaceId);
86105
+ if (isDirectory2(requested))
86106
+ return requested;
86107
+ const currentHome = process.env.HOME?.trim();
86108
+ const rehomed = currentHome ? rehomeScoutMobileWorkspacePath(requested, currentHome) : null;
86109
+ if (rehomed && isDirectory2(rehomed))
86110
+ return rehomed;
86111
+ const requestedName = basename14(requested).toLowerCase();
86112
+ const inventory = await loadMobileWorkspaceInventory(currentDirectory);
86113
+ const matches = inventory.filter((workspace) => isDirectory2(workspace.root) && [basename14(workspace.root), workspace.projectName, workspace.title].some((value) => value.toLowerCase() === requestedName));
86114
+ if (matches.length === 1)
86115
+ return resolve26(matches[0].root);
86116
+ throw new Error(`Workspace is not available on this Mac: ${rawWorkspaceId}. Choose a project from the current workspace list.`);
86117
+ }
85999
86118
  function latestMessageByConversation(snapshot) {
86000
86119
  const buckets = new Map;
86001
86120
  for (const message of Object.values(snapshot.messages)) {
@@ -86039,18 +86158,66 @@ function mobileConversationTitle(snapshot, conversation, directAgentId = null) {
86039
86158
  const title = rawConversationTitle(conversation) ?? conversationIdTitle(conversation.id);
86040
86159
  return conversation.kind === "channel" && title.startsWith("channel.") ? title.slice("channel.".length) : title;
86041
86160
  }
86161
+ function endpointsForAgent(snapshot, agentId) {
86162
+ const stateRank = (state) => {
86163
+ switch (state) {
86164
+ case "active":
86165
+ return 0;
86166
+ case "idle":
86167
+ return 1;
86168
+ case "waiting":
86169
+ return 2;
86170
+ case "offline":
86171
+ return 4;
86172
+ default:
86173
+ return 3;
86174
+ }
86175
+ };
86176
+ return Object.values(snapshot.endpoints).filter((endpoint) => endpoint.agentId === agentId && !isInactiveEndpoint(snapshot, endpoint)).sort((left, right) => Number(right.preferred === true) - Number(left.preferred === true) || stateRank(left.state) - stateRank(right.state) || (endpointActivityAt(right) ?? 0) - (endpointActivityAt(left) ?? 0) || left.id.localeCompare(right.id));
86177
+ }
86042
86178
  function endpointForAgent(snapshot, agentId) {
86043
- return Object.values(snapshot.endpoints).find((endpoint) => endpoint.agentId === agentId && !isInactiveEndpoint(snapshot, endpoint)) ?? null;
86179
+ return endpointsForAgent(snapshot, agentId)[0] ?? null;
86180
+ }
86181
+ function maxTimestampMs(values) {
86182
+ const timestamps = values.filter((value) => typeof value === "number" && Number.isFinite(value));
86183
+ return timestamps.length > 0 ? Math.max(...timestamps) : null;
86184
+ }
86185
+ function endpointActivityAt(endpoint) {
86186
+ if (!endpoint)
86187
+ return null;
86188
+ return maxTimestampMs([
86189
+ metadataTimestampMs(endpoint.metadata, "lastSeenAt"),
86190
+ metadataTimestampMs(endpoint.metadata, "lastEnsuredAt"),
86191
+ metadataTimestampMs(endpoint.metadata, "lastStartedAt"),
86192
+ metadataTimestampMs(endpoint.metadata, "lastCompletedAt"),
86193
+ metadataTimestampMs(endpoint.metadata, "lastFailedAt"),
86194
+ metadataTimestampMs(endpoint.metadata, "startedAt")
86195
+ ]);
86196
+ }
86197
+ function flightActivityAt2(flight) {
86198
+ return maxTimestampMs([
86199
+ normalizeTimestampMs2(flight.completedAt),
86200
+ normalizeTimestampMs2(flight.startedAt)
86201
+ ]);
86202
+ }
86203
+ function isActiveMobileFlight(flight) {
86204
+ return flight.state === "running" || flight.state === "waiting" || flight.state === "queued" || flight.state === "waking";
86044
86205
  }
86045
86206
  function buildMobileAgentSummary(snapshot, agent) {
86046
- const endpoint = endpointForAgent(snapshot, agent.id);
86207
+ const endpoints = endpointsForAgent(snapshot, agent.id);
86208
+ const endpoint = endpoints[0] ?? null;
86047
86209
  const flights = Object.values(snapshot.flights).filter((flight) => flight.targetAgentId === agent.id);
86048
- const hasWorkingFlight = flights.some((flight) => flight.state === "running");
86210
+ const hasActiveFlight = flights.some(isActiveMobileFlight);
86049
86211
  const lastAuthoredMessageAt = Object.values(snapshot.messages).filter((message) => message.actorId === agent.id).reduce((latest, message) => {
86050
86212
  const createdAt = normalizeTimestampMs2(message.createdAt);
86051
86213
  return typeof createdAt === "number" && (!latest || createdAt > latest) ? createdAt : latest;
86052
86214
  }, null);
86053
- const state = hasWorkingFlight ? "working" : endpoint && endpoint.state !== "offline" ? "available" : "offline";
86215
+ const lastActiveAt = maxTimestampMs([
86216
+ lastAuthoredMessageAt,
86217
+ ...endpoints.map(endpointActivityAt),
86218
+ ...flights.map(flightActivityAt2)
86219
+ ]);
86220
+ const state = hasActiveFlight ? "working" : endpoints.some((candidate) => candidate.state !== "offline") ? "available" : agent.wakePolicy !== "manual" ? "available" : "offline";
86054
86221
  return {
86055
86222
  id: agent.id,
86056
86223
  title: agent.displayName,
@@ -86064,7 +86231,7 @@ function buildMobileAgentSummary(snapshot, agent) {
86064
86231
  state,
86065
86232
  statusLabel: state === "working" ? "Working" : state === "available" ? "Available" : "Offline",
86066
86233
  sessionId: endpoint?.sessionId ?? null,
86067
- lastActiveAt: lastAuthoredMessageAt
86234
+ lastActiveAt
86068
86235
  };
86069
86236
  }
86070
86237
  function buildMobileSessionSummaries(snapshot) {
@@ -86378,7 +86545,7 @@ async function createScoutSession(input, currentDirectory, deviceId) {
86378
86545
  if (!rawWorkspaceId) {
86379
86546
  throw new Error(`Invalid workspaceId.`);
86380
86547
  }
86381
- const workspaceRoot = resolve26(rawWorkspaceId);
86548
+ const workspaceRoot = await resolveMobileWorkspaceRoot(rawWorkspaceId, currentDirectory);
86382
86549
  const projectName = basename14(workspaceRoot) || workspaceRoot;
86383
86550
  const workspace = {
86384
86551
  id: workspaceRoot,
@@ -86595,8 +86762,49 @@ async function requireMobileRelayContext() {
86595
86762
  return broker2;
86596
86763
  }
86597
86764
  async function getScoutMobileActivity(filters = {}) {
86598
- const home = await readScoutBrokerHome();
86599
- return (home?.activity ?? []).slice(0, filters.limit ?? 100);
86765
+ const broker2 = await loadScoutBrokerContext();
86766
+ if (!broker2) {
86767
+ const home = await readScoutBrokerHome();
86768
+ return (home?.activity ?? []).slice(0, filters.limit ?? 100);
86769
+ }
86770
+ const { snapshot } = broker2;
86771
+ const selfIds = operatorActorIds();
86772
+ const mediatedKinds = new Set(["channel", "direct", "group_direct", "thread"]);
86773
+ const rows = Object.values(snapshot.messages ?? {}).filter((message) => {
86774
+ const conversation = snapshot.conversations?.[message.conversationId];
86775
+ if (!conversation || !mediatedKinds.has(conversation.kind))
86776
+ return false;
86777
+ if (filters.agentId && message.actorId !== filters.agentId)
86778
+ return false;
86779
+ if (filters.actorId && message.actorId !== filters.actorId)
86780
+ return false;
86781
+ if (filters.conversationId && message.conversationId !== filters.conversationId)
86782
+ return false;
86783
+ return true;
86784
+ }).sort((left, right) => requireTimestampMs(right.createdAt) - requireTimestampMs(left.createdAt)).map((message) => {
86785
+ const conversation = snapshot.conversations[message.conversationId];
86786
+ const actorName = commsActorLabel(snapshot, message.actorId, selfIds);
86787
+ const channel = conversation.kind === "channel" ? channelNaturalKeyFromMetadata(conversation.metadata) ?? conversation.title ?? null : null;
86788
+ return {
86789
+ id: message.id,
86790
+ kind: message.class === "status" || message.actorId === "system" ? "system" : "message",
86791
+ actorId: message.actorId,
86792
+ actorName,
86793
+ title: actorName,
86794
+ detail: message.body,
86795
+ conversationId: message.conversationId,
86796
+ channel,
86797
+ timestamp: requireTimestampMs(message.createdAt)
86798
+ };
86799
+ });
86800
+ const limit = filters.limit && filters.limit > 0 ? Math.floor(filters.limit) : 100;
86801
+ return rows.slice(0, limit);
86802
+ }
86803
+ async function getScoutMobileServiceBudgets() {
86804
+ return { budgets: [] };
86805
+ }
86806
+ async function getScoutMobileTerminals() {
86807
+ return { terminals: [] };
86600
86808
  }
86601
86809
  function operatorActorIds() {
86602
86810
  const ids = new Set([MOBILE_OPERATOR_ID]);
@@ -86970,7 +87178,7 @@ import { createHash as createHash5 } from "crypto";
86970
87178
  import {
86971
87179
  chmodSync,
86972
87180
  closeSync,
86973
- existsSync as existsSync38,
87181
+ existsSync as existsSync39,
86974
87182
  mkdirSync as mkdirSync12,
86975
87183
  openSync,
86976
87184
  readFileSync as readFileSync19,
@@ -86978,8 +87186,8 @@ import {
86978
87186
  unlinkSync as unlinkSync3,
86979
87187
  writeFileSync as writeFileSync10
86980
87188
  } from "fs";
86981
- import { homedir as homedir33, hostname as hostname5, userInfo as userInfo2 } from "os";
86982
- import { join as join45 } from "path";
87189
+ import { homedir as homedir34, hostname as hostname5, userInfo as userInfo2 } from "os";
87190
+ import { join as join46 } from "path";
86983
87191
  async function readMobileTerminalStatus() {
86984
87192
  const base = {
86985
87193
  shellExecutable: process.env.SHELL?.trim() || "/bin/zsh",
@@ -87049,17 +87257,17 @@ async function readMobileTerminalStatus() {
87049
87257
  }
87050
87258
  async function provisionMobileTerminalAccess(sshPublicKey, deviceId) {
87051
87259
  const id = deviceId?.trim() || "scout-ios-device";
87052
- const sshDir = join45(homedir33(), ".ssh");
87053
- const authorizedKeysPath = join45(sshDir, "authorized_keys");
87260
+ const sshDir = join46(homedir34(), ".ssh");
87261
+ const authorizedKeysPath = join46(sshDir, "authorized_keys");
87054
87262
  const hostKeyFingerprint = readRequiredHostKeyFingerprint();
87055
87263
  const result = withAuthorizedKeysLock(sshDir, () => {
87056
- if (!existsSync38(sshDir)) {
87264
+ if (!existsSync39(sshDir)) {
87057
87265
  mkdirSync12(sshDir, { recursive: true, mode: 448 });
87058
87266
  }
87059
87267
  try {
87060
87268
  chmodSync(sshDir, 448);
87061
87269
  } catch {}
87062
- const existing = existsSync38(authorizedKeysPath) ? readFileSync19(authorizedKeysPath, "utf8") : "";
87270
+ const existing = existsSync39(authorizedKeysPath) ? readFileSync19(authorizedKeysPath, "utf8") : "";
87063
87271
  const result2 = provisionSshTerminalAccess({
87064
87272
  authorizedKeys: existing,
87065
87273
  deviceId: id,
@@ -87113,10 +87321,10 @@ function writeAuthorizedKeysAtomically(path2, contents) {
87113
87321
  }
87114
87322
  }
87115
87323
  function withAuthorizedKeysLock(sshDir, action) {
87116
- if (!existsSync38(sshDir)) {
87324
+ if (!existsSync39(sshDir)) {
87117
87325
  mkdirSync12(sshDir, { recursive: true, mode: 448 });
87118
87326
  }
87119
- const lockPath = join45(sshDir, ".scout-authorized-keys.lock");
87327
+ const lockPath = join46(sshDir, ".scout-authorized-keys.lock");
87120
87328
  const deadline = Date.now() + 5000;
87121
87329
  let fd = null;
87122
87330
  while (fd === null) {
@@ -87157,9 +87365,9 @@ var init_mobile_terminal_provision = __esm(() => {
87157
87365
  });
87158
87366
 
87159
87367
  // ../../apps/desktop/src/core/pairing/runtime/bridge/server.ts
87160
- import { readdirSync as readdirSync4, readFileSync as readFileSync20, realpathSync as realpathSync3, statSync as statSync6 } from "fs";
87161
- import { basename as basename15, isAbsolute as isAbsolute5, join as join46, relative as relative4 } from "path";
87162
- import { homedir as homedir34 } from "os";
87368
+ import { readdirSync as readdirSync4, readFileSync as readFileSync20, realpathSync as realpathSync3, statSync as statSync7 } from "fs";
87369
+ import { basename as basename15, isAbsolute as isAbsolute5, join as join47, relative as relative4 } from "path";
87370
+ import { homedir as homedir35 } from "os";
87163
87371
  function replaySyncEvents(bridge, sessionId, lastSeq) {
87164
87372
  return bridge.replay(sessionId, lastSeq);
87165
87373
  }
@@ -87346,7 +87554,7 @@ async function handleRPCInner(bridge, req, rpcContext = {}) {
87346
87554
  if (dirName.startsWith("-")) {
87347
87555
  const candidate = "/" + dirName.slice(1).replace(/-/g, "/");
87348
87556
  try {
87349
- statSync6(candidate);
87557
+ statSync7(candidate);
87350
87558
  cwd = candidate;
87351
87559
  } catch {
87352
87560
  const config2 = resolveConfig();
@@ -87403,7 +87611,7 @@ async function handleRPCInner(bridge, req, rpcContext = {}) {
87403
87611
  }
87404
87612
  const root = resolveWorkspaceRoot(configuredRoot);
87405
87613
  const projectPath = resolveWorkspacePath(root, p.path);
87406
- const stat6 = statSync6(projectPath);
87614
+ const stat6 = statSync7(projectPath);
87407
87615
  if (!stat6.isDirectory()) {
87408
87616
  return { id: req.id, error: { code: -32000, message: "Workspace target is not a directory" } };
87409
87617
  }
@@ -87483,6 +87691,18 @@ async function handleRPCInner(bridge, req, rpcContext = {}) {
87483
87691
  result: await getScoutMobileActivity(p)
87484
87692
  };
87485
87693
  }
87694
+ case "mobile/service-budgets": {
87695
+ return {
87696
+ id: req.id,
87697
+ result: await getScoutMobileServiceBudgets()
87698
+ };
87699
+ }
87700
+ case "mobile/terminal-sessions": {
87701
+ return {
87702
+ id: req.id,
87703
+ result: await getScoutMobileTerminals()
87704
+ };
87705
+ }
87486
87706
  case "mobile/comms/conversations": {
87487
87707
  const p = req.params;
87488
87708
  return {
@@ -87591,7 +87811,7 @@ async function handleRPCInner(bridge, req, rpcContext = {}) {
87591
87811
  const config2 = resolveConfig();
87592
87812
  const workspaceRoot = config2.workspace?.root ? resolveWorkspaceRoot(config2.workspace.root) : null;
87593
87813
  const matches = await readSessionSearch({
87594
- home: homedir34(),
87814
+ home: homedir35(),
87595
87815
  workspaceRoot,
87596
87816
  maxAgeDays: maxAge,
87597
87817
  limit,
@@ -87724,13 +87944,13 @@ function resolveMobileCurrentDirectory() {
87724
87944
  }
87725
87945
  }
87726
87946
  function resolveWorkspaceRoot(root) {
87727
- const expandedRoot = root.replace(/^~/, homedir34());
87947
+ const expandedRoot = root.replace(/^~/, homedir35());
87728
87948
  return realpathSync3(expandedRoot);
87729
87949
  }
87730
87950
  function resolveWorkspacePath(root, requestedPath) {
87731
87951
  const normalizedRoot = resolveWorkspaceRoot(root);
87732
- const expandedPath = requestedPath?.replace(/^~/, homedir34());
87733
- const candidate = expandedPath ? isAbsolute5(expandedPath) ? expandedPath : join46(normalizedRoot, expandedPath) : normalizedRoot;
87952
+ const expandedPath = requestedPath?.replace(/^~/, homedir35());
87953
+ const candidate = expandedPath ? isAbsolute5(expandedPath) ? expandedPath : join47(normalizedRoot, expandedPath) : normalizedRoot;
87734
87954
  const resolvedCandidate = realpathSync3(candidate);
87735
87955
  const rel = relative4(normalizedRoot, resolvedCandidate);
87736
87956
  if (rel === "" || !rel.startsWith("..") && !isAbsolute5(rel)) {
@@ -87745,9 +87965,9 @@ function listDirectories(dirPath) {
87745
87965
  continue;
87746
87966
  if (name === "node_modules" || name === ".build" || name === "target")
87747
87967
  continue;
87748
- const fullPath = join46(dirPath, name);
87968
+ const fullPath = join47(dirPath, name);
87749
87969
  try {
87750
- const stat6 = statSync6(fullPath);
87970
+ const stat6 = statSync7(fullPath);
87751
87971
  if (!stat6.isDirectory())
87752
87972
  continue;
87753
87973
  const children = new Set(readdirSync4(fullPath));
@@ -87771,7 +87991,7 @@ async function discoverSessionFiles(maxAgeDays, limit) {
87771
87991
  const config2 = resolveConfig();
87772
87992
  const workspaceRoot = config2.workspace?.root ? resolveWorkspaceRoot(config2.workspace.root) : null;
87773
87993
  const sessions4 = await readSessionFileScan({
87774
- home: homedir34(),
87994
+ home: homedir35(),
87775
87995
  workspaceRoot,
87776
87996
  maxAgeDays,
87777
87997
  limit
@@ -87883,9 +88103,9 @@ var init_tail_fanout = __esm(() => {
87883
88103
  });
87884
88104
 
87885
88105
  // ../../apps/desktop/src/core/pairing/runtime/bridge/router.ts
87886
- import { readFileSync as readFileSync21, readdirSync as readdirSync5, realpathSync as realpathSync4, statSync as statSync7 } from "fs";
87887
- import { basename as basename16, isAbsolute as isAbsolute6, join as join47, relative as relative5 } from "path";
87888
- import { homedir as homedir35 } from "os";
88106
+ import { readFileSync as readFileSync21, readdirSync as readdirSync5, realpathSync as realpathSync4, statSync as statSync8 } from "fs";
88107
+ import { basename as basename16, isAbsolute as isAbsolute6, join as join48, relative as relative5 } from "path";
88108
+ import { homedir as homedir36 } from "os";
87889
88109
  function resolveMobileCurrentDirectory2() {
87890
88110
  const config2 = resolveConfig();
87891
88111
  const configuredRoot = config2.workspace?.root;
@@ -87898,13 +88118,13 @@ function resolveMobileCurrentDirectory2() {
87898
88118
  }
87899
88119
  }
87900
88120
  function resolveWorkspaceRoot2(root) {
87901
- const expandedRoot = root.replace(/^~/, homedir35());
88121
+ const expandedRoot = root.replace(/^~/, homedir36());
87902
88122
  return realpathSync4(expandedRoot);
87903
88123
  }
87904
88124
  function resolveWorkspacePath2(root, requestedPath) {
87905
88125
  const normalizedRoot = resolveWorkspaceRoot2(root);
87906
- const expandedPath = requestedPath?.replace(/^~/, homedir35());
87907
- const candidate = expandedPath ? isAbsolute6(expandedPath) ? expandedPath : join47(normalizedRoot, expandedPath) : normalizedRoot;
88126
+ const expandedPath = requestedPath?.replace(/^~/, homedir36());
88127
+ const candidate = expandedPath ? isAbsolute6(expandedPath) ? expandedPath : join48(normalizedRoot, expandedPath) : normalizedRoot;
87908
88128
  const resolvedCandidate = realpathSync4(candidate);
87909
88129
  const rel = relative5(normalizedRoot, resolvedCandidate);
87910
88130
  if (rel === "" || !rel.startsWith("..") && !isAbsolute6(rel)) {
@@ -87919,9 +88139,9 @@ function listDirectories2(dirPath) {
87919
88139
  continue;
87920
88140
  if (name === "node_modules" || name === ".build" || name === "target")
87921
88141
  continue;
87922
- const fullPath = join47(dirPath, name);
88142
+ const fullPath = join48(dirPath, name);
87923
88143
  try {
87924
- const stat6 = statSync7(fullPath);
88144
+ const stat6 = statSync8(fullPath);
87925
88145
  if (!stat6.isDirectory())
87926
88146
  continue;
87927
88147
  const children = new Set(readdirSync5(fullPath));
@@ -87952,7 +88172,7 @@ async function discoverSessionFiles2(maxAgeDays, limit) {
87952
88172
  const config2 = resolveConfig();
87953
88173
  const workspaceRoot = config2.workspace?.root ? resolveWorkspaceRoot2(config2.workspace.root) : null;
87954
88174
  const sessions4 = await readSessionFileScan({
87955
- home: homedir35(),
88175
+ home: homedir36(),
87956
88176
  workspaceRoot,
87957
88177
  maxAgeDays,
87958
88178
  limit
@@ -88297,7 +88517,7 @@ var init_router = __esm(() => {
88297
88517
  if (dirName.startsWith("-")) {
88298
88518
  const candidate = "/" + dirName.slice(1).replace(/-/g, "/");
88299
88519
  try {
88300
- statSync7(candidate);
88520
+ statSync8(candidate);
88301
88521
  cwd = candidate;
88302
88522
  } catch {
88303
88523
  const config2 = resolveConfig();
@@ -88358,56 +88578,31 @@ var init_router = __esm(() => {
88358
88578
  workspaceLimit: exports_external.number().optional(),
88359
88579
  agentLimit: exports_external.number().optional(),
88360
88580
  sessionLimit: exports_external.number().optional()
88361
- }).optional()).query(({ input }) => {
88362
- const workspaceLimit = input?.workspaceLimit ?? 6;
88363
- const agentLimit = input?.agentLimit ?? 6;
88364
- const sessionLimit = input?.sessionLimit ?? 6;
88365
- const workspaces = queryMobileWorkspaces(workspaceLimit);
88366
- const agents = queryMobileAgents(agentLimit);
88367
- const sessions4 = queryMobileSessions(sessionLimit);
88368
- return {
88369
- workspaces,
88370
- agents,
88371
- sessions: sessions4,
88372
- totals: {
88373
- workspaces: workspaces.length,
88374
- agents: agents.length,
88375
- sessions: sessions4.length
88376
- }
88377
- };
88581
+ }).optional()).query(async ({ input }) => {
88582
+ return getScoutMobileHome({
88583
+ currentDirectory: resolveMobileCurrentDirectory2(),
88584
+ workspaceLimit: input?.workspaceLimit,
88585
+ agentLimit: input?.agentLimit,
88586
+ sessionLimit: input?.sessionLimit
88587
+ });
88378
88588
  }),
88379
88589
  workspaces: procedure.input(exports_external.object({
88380
88590
  query: exports_external.string().optional(),
88381
88591
  limit: exports_external.number().optional()
88382
- }).optional()).query(({ input }) => {
88383
- let results = queryMobileWorkspaces(input?.limit ?? 50);
88384
- if (input?.query) {
88385
- const q = input.query.toLowerCase();
88386
- results = results.filter((w) => w.title.toLowerCase().includes(q) || w.root.toLowerCase().includes(q));
88387
- }
88388
- return results;
88592
+ }).optional()).query(async ({ input }) => {
88593
+ return getScoutMobileWorkspaces(input, resolveMobileCurrentDirectory2());
88389
88594
  }),
88390
88595
  agents: procedure.input(exports_external.object({
88391
88596
  query: exports_external.string().optional(),
88392
88597
  limit: exports_external.number().optional()
88393
- }).optional()).query(({ input }) => {
88394
- let results = queryMobileAgents(input?.limit ?? 50);
88395
- if (input?.query) {
88396
- const q = input.query.toLowerCase();
88397
- results = results.filter((a) => a.title.toLowerCase().includes(q) || a.id.toLowerCase().includes(q) || (a.workspaceRoot ?? "").toLowerCase().includes(q));
88398
- }
88399
- return results;
88598
+ }).optional()).query(async ({ input }) => {
88599
+ return getScoutMobileAgents(input, resolveMobileCurrentDirectory2());
88400
88600
  }),
88401
88601
  sessions: procedure.input(exports_external.object({
88402
88602
  query: exports_external.string().optional(),
88403
88603
  limit: exports_external.number().optional()
88404
- }).optional()).query(({ input }) => {
88405
- let results = queryMobileSessions(input?.limit ?? 50);
88406
- if (input?.query) {
88407
- const q = input.query.toLowerCase();
88408
- results = results.filter((s) => s.title.toLowerCase().includes(q) || (s.agentName ?? "").toLowerCase().includes(q) || (s.preview ?? "").toLowerCase().includes(q));
88409
- }
88410
- return results;
88604
+ }).optional()).query(async ({ input }) => {
88605
+ return getScoutMobileSessions(input, resolveMobileCurrentDirectory2());
88411
88606
  }),
88412
88607
  sessionSnapshot: procedure.input(exports_external.object({
88413
88608
  conversationId: exports_external.string().optional(),
@@ -88527,6 +88722,8 @@ var init_router = __esm(() => {
88527
88722
  }).optional()).query(async ({ input }) => {
88528
88723
  return getScoutMobileActivity(input);
88529
88724
  }),
88725
+ serviceBudgets: procedure.input(exports_external.object({}).optional()).query(async () => getScoutMobileServiceBudgets()),
88726
+ terminalSessions: procedure.input(exports_external.object({}).optional()).query(async () => getScoutMobileTerminals()),
88530
88727
  agentDetail: procedure.input(exports_external.object({ agentId: exports_external.string() })).query(async ({ input }) => {
88531
88728
  return queryMobileAgentDetail(input.agentId);
88532
88729
  }),
@@ -88656,7 +88853,7 @@ var init_router = __esm(() => {
88656
88853
  }
88657
88854
  const root = resolveWorkspaceRoot2(configuredRoot);
88658
88855
  const projectPath = resolveWorkspacePath2(root, input.path);
88659
- const stat6 = statSync7(projectPath);
88856
+ const stat6 = statSync8(projectPath);
88660
88857
  if (!stat6.isDirectory()) {
88661
88858
  throw new TRPCError({
88662
88859
  code: "BAD_REQUEST",
@@ -88698,7 +88895,7 @@ var init_router = __esm(() => {
88698
88895
  const config2 = resolveConfig();
88699
88896
  const workspaceRoot = config2.workspace?.root ? resolveWorkspaceRoot2(config2.workspace.root) : null;
88700
88897
  const matches = await readSessionSearch({
88701
- home: homedir35(),
88898
+ home: homedir36(),
88702
88899
  workspaceRoot,
88703
88900
  maxAgeDays: maxAge,
88704
88901
  limit,
@@ -88902,8 +89099,8 @@ function mobileConversationLifecycleEvent(lifecycle) {
88902
89099
  }
88903
89100
  function connectToRelay(relayUrl, identity2, bridge, options = {}) {
88904
89101
  const { secure = true, events: events2 } = options;
88905
- const publicRelayUrl = options.publicRelayUrl?.trim() || relayUrl;
88906
- const qrPayload = createQRPayload(identity2.publicKey, publicRelayUrl, options.fallbackRelayUrls);
89102
+ const eventRelayUrl = options.publicRelayUrl?.trim() || relayUrl;
89103
+ const qrPayload = options.qrPayload ?? createQRPayload(identity2.publicKey, eventRelayUrl, options.fallbackRelayUrls);
88907
89104
  let ws = null;
88908
89105
  let eventUnsub = null;
88909
89106
  let brokerWatchAbort = null;
@@ -88918,12 +89115,12 @@ function connectToRelay(relayUrl, identity2, bridge, options = {}) {
88918
89115
  const bridgeKeyHex = bytesToHex2(identity2.publicKey);
88919
89116
  const url2 = buildRelayUrl(relayUrl, qrPayload.room, bridgeKeyHex);
88920
89117
  console.log(`[relay-client] connecting to relay (room: ${qrPayload.room})`);
88921
- events2?.onConnecting?.({ relayUrl: publicRelayUrl, room: qrPayload.room });
89118
+ events2?.onConnecting?.({ relayUrl: eventRelayUrl, room: qrPayload.room });
88922
89119
  ws = new WebSocket(url2, relayWebSocketOptions(relayUrl));
88923
89120
  ws.addEventListener("open", () => {
88924
89121
  console.log(`[relay-client] connected to relay (room: ${qrPayload.room})`);
88925
89122
  backoff = INITIAL_BACKOFF_MS;
88926
- events2?.onConnected?.({ relayUrl: publicRelayUrl, room: qrPayload.room });
89123
+ events2?.onConnected?.({ relayUrl: eventRelayUrl, room: qrPayload.room });
88927
89124
  });
88928
89125
  ws.addEventListener("message", (event) => {
88929
89126
  handleRelaySocketMessage(event.data);
@@ -88931,7 +89128,7 @@ function connectToRelay(relayUrl, identity2, bridge, options = {}) {
88931
89128
  ws.addEventListener("close", (event) => {
88932
89129
  console.log(`[relay-client] disconnected (code: ${event.code}, reason: ${event.reason})`);
88933
89130
  events2?.onClosed?.({
88934
- relayUrl: publicRelayUrl,
89131
+ relayUrl: eventRelayUrl,
88935
89132
  room: qrPayload.room,
88936
89133
  code: event.code,
88937
89134
  reason: event.reason
@@ -88942,7 +89139,7 @@ function connectToRelay(relayUrl, identity2, bridge, options = {}) {
88942
89139
  ws.addEventListener("error", () => {
88943
89140
  const error48 = new Error("Relay websocket error");
88944
89141
  console.error("[relay-client] connection error");
88945
- events2?.onError?.({ relayUrl: publicRelayUrl, room: qrPayload.room, error: error48 });
89142
+ events2?.onError?.({ relayUrl: eventRelayUrl, room: qrPayload.room, error: error48 });
88946
89143
  });
88947
89144
  }
88948
89145
  function handleRelaySocketMessage(raw) {
@@ -88999,7 +89196,7 @@ function connectToRelay(relayUrl, identity2, bridge, options = {}) {
88999
89196
  ensureBridgeEventSubscription();
89000
89197
  ensureBrokerMessageSubscription();
89001
89198
  console.log(`[relay-client] secure handshake complete (peer: ${pubHex.slice(0, 12)}..., trusted: ${peer.trustedPeer}, device: ${peer.deviceId}, client: ${clientId})`);
89002
- events2?.onPaired?.({ relayUrl: publicRelayUrl, room: qrPayload.room, remotePublicKey });
89199
+ events2?.onPaired?.({ relayUrl: eventRelayUrl, room: qrPayload.room, remotePublicKey });
89003
89200
  sendExistingSessions((json2) => {
89004
89201
  if (peer.transport.isReady()) {
89005
89202
  peer.transport.send(json2);
@@ -89012,7 +89209,7 @@ function connectToRelay(relayUrl, identity2, bridge, options = {}) {
89012
89209
  onError: (err) => {
89013
89210
  console.error("[relay-client] secure transport error:", err.message);
89014
89211
  log.error("trns:cry", `decrypt failed for ${clientId} \u2014 resetting handshake: ${err.message}`);
89015
- events2?.onError?.({ relayUrl: publicRelayUrl, room: qrPayload.room, error: err });
89212
+ events2?.onError?.({ relayUrl: eventRelayUrl, room: qrPayload.room, error: err });
89016
89213
  sendRelayClose(clientId, 4002, "Transport reset");
89017
89214
  teardownSecurePeer(clientId);
89018
89215
  },
@@ -89249,7 +89446,7 @@ function connectToRelay(relayUrl, identity2, bridge, options = {}) {
89249
89446
  if (stopped)
89250
89447
  return;
89251
89448
  console.log(`[relay-client] reconnecting in ${backoff}ms...`);
89252
- events2?.onReconnectScheduled?.({ relayUrl: publicRelayUrl, room: qrPayload.room, delayMs: backoff });
89449
+ events2?.onReconnectScheduled?.({ relayUrl: eventRelayUrl, room: qrPayload.room, delayMs: backoff });
89253
89450
  reconnectTimer = setTimeout(() => {
89254
89451
  reconnectTimer = null;
89255
89452
  connect();
@@ -90954,14 +91151,14 @@ var init_dist4 = __esm(() => {
90954
91151
 
90955
91152
  // ../../apps/desktop/src/core/pairing/runtime/bridge/server-trpc.ts
90956
91153
  import { realpathSync as realpathSync5 } from "fs";
90957
- import { homedir as homedir36 } from "os";
91154
+ import { homedir as homedir37 } from "os";
90958
91155
  function resolveCurrentDirectory() {
90959
91156
  try {
90960
91157
  const config2 = resolveConfig();
90961
91158
  const configuredRoot = config2.workspace?.root;
90962
91159
  if (!configuredRoot)
90963
91160
  return process.cwd();
90964
- const expanded = configuredRoot.replace(/^~/, homedir36());
91161
+ const expanded = configuredRoot.replace(/^~/, homedir37());
90965
91162
  return realpathSync5(expanded);
90966
91163
  } catch {
90967
91164
  return process.cwd();
@@ -91469,16 +91666,17 @@ var init_server_trpc = __esm(() => {
91469
91666
  });
91470
91667
 
91471
91668
  // ../../apps/desktop/src/core/pairing/runtime/runtime.ts
91472
- import { homedir as homedir37 } from "os";
91669
+ import { homedir as homedir38 } from "os";
91473
91670
  function createPairingAdapterRegistry(configAdapters) {
91474
91671
  const adapters = {
91475
91672
  "claude-code": createAdapter,
91476
91673
  acp: createAdapter3,
91477
91674
  codex: createAdapter2,
91478
91675
  "grok-acp": createAdapter4,
91479
- pi: createAdapter7,
91480
- opencode: createAdapter6,
91481
- openai: createAdapter5
91676
+ "kimi-acp": createAdapter5,
91677
+ pi: createAdapter8,
91678
+ opencode: createAdapter7,
91679
+ openai: createAdapter6
91482
91680
  };
91483
91681
  if (configAdapters) {
91484
91682
  for (const [name, entry] of Object.entries(configAdapters)) {
@@ -91513,34 +91711,105 @@ async function startPairingRuntime(options) {
91513
91711
  identity: config2.secure ? identity2 : undefined
91514
91712
  });
91515
91713
  const fileServer = startFileServer({ port: config2.port + 2, bridge });
91516
- const relayUrl = options?.relayUrl?.trim() || config2.relay || null;
91517
- if (!relayUrl) {
91714
+ const relayEndpoints = resolveRelayEndpoints(config2, options);
91715
+ const advertisedRelayUrls = dedupeRelayUrls(relayEndpoints.flatMap((endpoint) => [
91716
+ advertisedRelayUrl(endpoint),
91717
+ ...endpoint.fallbackRelayUrls ?? []
91718
+ ]));
91719
+ const primaryRelayUrl = advertisedRelayUrls[0] ?? null;
91720
+ if (!primaryRelayUrl) {
91518
91721
  fileServer.stop();
91519
91722
  server.stop();
91520
91723
  throw new Error("Pairing relay URL is not configured.");
91521
91724
  }
91522
- const relayConnection = connectToRelay(relayUrl, identity2, bridge, {
91523
- secure: true,
91524
- publicRelayUrl: options?.advertisedRelayUrl ?? undefined,
91525
- fallbackRelayUrls: options?.fallbackRelayUrls,
91526
- events: options?.relayEvents
91527
- });
91725
+ const qrPayload = createQRPayload(identity2.publicKey, primaryRelayUrl, advertisedRelayUrls.slice(1));
91726
+ let relayConnections = [];
91727
+ try {
91728
+ relayConnections = relayEndpoints.map((endpoint) => connectToRelay(endpoint.relayUrl.trim(), identity2, bridge, {
91729
+ secure: true,
91730
+ publicRelayUrl: advertisedRelayUrl(endpoint),
91731
+ qrPayload,
91732
+ events: options?.relayEvents
91733
+ }));
91734
+ } catch (error48) {
91735
+ for (const relayConnection of relayConnections) {
91736
+ relayConnection.disconnect();
91737
+ }
91738
+ fileServer.stop();
91739
+ server.stop();
91740
+ throw error48;
91741
+ }
91528
91742
  await autoStartConfiguredSessions(bridge, config2.sessions);
91529
91743
  return {
91530
91744
  bridge,
91531
91745
  fileServer,
91532
91746
  identity: identity2,
91533
91747
  config: config2,
91534
- relayConnection,
91535
- qrPayload: relayConnection.qrPayload,
91748
+ relayConnection: relayConnections[0] ?? null,
91749
+ relayConnections,
91750
+ qrPayload,
91536
91751
  async stop() {
91537
- relayConnection.disconnect();
91752
+ for (const relayConnection of relayConnections) {
91753
+ relayConnection.disconnect();
91754
+ }
91538
91755
  fileServer.stop();
91539
91756
  await bridge.shutdown();
91540
91757
  server.stop();
91541
91758
  }
91542
91759
  };
91543
91760
  }
91761
+ function resolveRelayEndpoints(config2, options) {
91762
+ const explicit = options?.relayEndpoints?.map((endpoint) => ({
91763
+ relayUrl: endpoint.relayUrl.trim(),
91764
+ advertisedRelayUrl: endpoint.advertisedRelayUrl?.trim() || endpoint.relayUrl.trim(),
91765
+ fallbackRelayUrls: endpoint.fallbackRelayUrls
91766
+ })).filter((endpoint) => endpoint.relayUrl.length > 0) ?? [];
91767
+ if (explicit.length > 0) {
91768
+ return dedupeRelayEndpoints(explicit);
91769
+ }
91770
+ const relayUrl = options?.relayUrl?.trim() || config2.relay || null;
91771
+ if (!relayUrl) {
91772
+ return [];
91773
+ }
91774
+ return [{
91775
+ relayUrl,
91776
+ advertisedRelayUrl: options?.advertisedRelayUrl?.trim() || relayUrl,
91777
+ fallbackRelayUrls: options?.fallbackRelayUrls
91778
+ }];
91779
+ }
91780
+ function advertisedRelayUrl(endpoint) {
91781
+ return endpoint.advertisedRelayUrl?.trim() || endpoint.relayUrl.trim();
91782
+ }
91783
+ function dedupeRelayEndpoints(endpoints) {
91784
+ const seen = new Set;
91785
+ const out = [];
91786
+ for (const endpoint of endpoints) {
91787
+ const relayUrl = endpoint.relayUrl.trim();
91788
+ if (!relayUrl || seen.has(relayUrl)) {
91789
+ continue;
91790
+ }
91791
+ seen.add(relayUrl);
91792
+ out.push({
91793
+ relayUrl,
91794
+ advertisedRelayUrl: advertisedRelayUrl(endpoint),
91795
+ fallbackRelayUrls: dedupeRelayUrls(endpoint.fallbackRelayUrls ?? [])
91796
+ });
91797
+ }
91798
+ return out;
91799
+ }
91800
+ function dedupeRelayUrls(urls) {
91801
+ const seen = new Set;
91802
+ const out = [];
91803
+ for (const url2 of urls) {
91804
+ const trimmed = url2.trim();
91805
+ if (!trimmed || seen.has(trimmed)) {
91806
+ continue;
91807
+ }
91808
+ seen.add(trimmed);
91809
+ out.push(trimmed);
91810
+ }
91811
+ return out;
91812
+ }
91544
91813
  async function autoStartConfiguredSessions(bridge, sessions4) {
91545
91814
  if (!sessions4?.length) {
91546
91815
  return;
@@ -91550,7 +91819,7 @@ async function autoStartConfiguredSessions(bridge, sessions4) {
91550
91819
  try {
91551
91820
  const session3 = await bridge.createSession(entry.adapter, {
91552
91821
  name: entry.name,
91553
- cwd: entry.cwd?.replace(/^~/, homedir37()),
91822
+ cwd: entry.cwd?.replace(/^~/, homedir38()),
91554
91823
  options: entry.options
91555
91824
  });
91556
91825
  console.log(`[bridge] session started: ${session3.name} (${entry.adapter})`);
@@ -91819,16 +92088,16 @@ function parseRelayEnvelope2(data) {
91819
92088
  var BRIDGE_ABSENCE_GRACE_MS = 30000, ROOM_IDLE_TIMEOUT_MS = 60000;
91820
92089
 
91821
92090
  // ../../apps/desktop/src/core/pairing/runtime/relay-runtime.ts
91822
- import { existsSync as existsSync39, mkdirSync as mkdirSync14 } from "fs";
91823
- import { homedir as homedir38, networkInterfaces } from "os";
91824
- import { join as join48 } from "path";
92091
+ import { existsSync as existsSync40, mkdirSync as mkdirSync14 } from "fs";
92092
+ import { homedir as homedir39, networkInterfaces } from "os";
92093
+ import { join as join49 } from "path";
91825
92094
  async function findStoredTailscaleCert(hostname6) {
91826
- if (!existsSync39(PAIRING_DIR2)) {
92095
+ if (!existsSync40(PAIRING_DIR2)) {
91827
92096
  return null;
91828
92097
  }
91829
- const certPath = join48(PAIRING_DIR2, `${hostname6}.crt`);
91830
- const keyPath = join48(PAIRING_DIR2, `${hostname6}.key`);
91831
- if (!existsSync39(certPath) || !existsSync39(keyPath)) {
92098
+ const certPath = join49(PAIRING_DIR2, `${hostname6}.crt`);
92099
+ const keyPath = join49(PAIRING_DIR2, `${hostname6}.key`);
92100
+ if (!existsSync40(certPath) || !existsSync40(keyPath)) {
91832
92101
  return null;
91833
92102
  }
91834
92103
  if (!await storedCertificateLooksPubliclyTrusted(certPath)) {
@@ -91912,8 +92181,8 @@ function resolveRelayEndpointForTailscaleStatus(port, tailscale2, options = {})
91912
92181
  }
91913
92182
  async function generateTailscaleCerts(hostname6) {
91914
92183
  mkdirSync14(PAIRING_DIR2, { recursive: true });
91915
- const certPath = join48(PAIRING_DIR2, `${hostname6}.crt`);
91916
- const keyPath = join48(PAIRING_DIR2, `${hostname6}.key`);
92184
+ const certPath = join49(PAIRING_DIR2, `${hostname6}.crt`);
92185
+ const keyPath = join49(PAIRING_DIR2, `${hostname6}.key`);
91917
92186
  try {
91918
92187
  pairingLog.info("relay", "generating tailscale TLS cert", { hostname: hostname6 });
91919
92188
  await execSystemFile("tailscale", ["cert", "--cert-file", certPath, "--key-file", keyPath, hostname6], {
@@ -92040,7 +92309,7 @@ var PAIRING_DIR2;
92040
92309
  var init_relay_runtime = __esm(() => {
92041
92310
  init_system_probes();
92042
92311
  init_log2();
92043
- PAIRING_DIR2 = join48(homedir38(), ".scout/pairing");
92312
+ PAIRING_DIR2 = join49(homedir39(), ".scout/pairing");
92044
92313
  });
92045
92314
 
92046
92315
  // ../../node_modules/.bun/uqr@0.1.3/node_modules/uqr/dist/index.mjs
@@ -92740,20 +93009,41 @@ async function startScoutPairingSession(input) {
92740
93009
  };
92741
93010
  const resolvedRelayUrl = input.forceManagedRelay ? null : input.relayUrl?.trim() || config3.relay;
92742
93011
  try {
92743
- const managedRelay = resolvedRelayUrl ? null : await startManagedRelay(config3.port + 1);
93012
+ let managedRelay = null;
93013
+ try {
93014
+ managedRelay = await startManagedRelay(config3.port + 1);
93015
+ } catch (error48) {
93016
+ if (!resolvedRelayUrl) {
93017
+ throw error48;
93018
+ }
93019
+ const detail = error48 instanceof Error ? error48.message : String(error48);
93020
+ console.warn(`[pairing] managed relay unavailable; continuing with configured relay: ${detail}`);
93021
+ }
92744
93022
  relay = managedRelay;
92745
- const activeRelayUrl = resolvedRelayUrl ?? managedRelay?.relayUrl;
92746
- const connectRelayUrl = resolvedRelayUrl ?? managedRelay?.connectUrl ?? managedRelay?.relayUrl;
92747
- if (!activeRelayUrl || !connectRelayUrl) {
93023
+ const relayEndpoints = [
93024
+ ...resolvedRelayUrl ? [{
93025
+ relayUrl: resolvedRelayUrl,
93026
+ advertisedRelayUrl: resolvedRelayUrl
93027
+ }] : [],
93028
+ ...managedRelay ? [{
93029
+ relayUrl: managedRelay.connectUrl ?? managedRelay.relayUrl,
93030
+ advertisedRelayUrl: managedRelay.relayUrl,
93031
+ fallbackRelayUrls: managedRelay.fallbackRelayUrls
93032
+ }] : []
93033
+ ];
93034
+ const advertisedRelayUrls = dedupeRelayUrls2(relayEndpoints.flatMap((endpoint) => [
93035
+ endpoint.advertisedRelayUrl ?? endpoint.relayUrl,
93036
+ ...endpoint.fallbackRelayUrls ?? []
93037
+ ]));
93038
+ const activeRelayUrl = advertisedRelayUrls[0] ?? null;
93039
+ if (!activeRelayUrl || relayEndpoints.length === 0) {
92748
93040
  throw new Error("Scout pairing relay URL is not configured.");
92749
93041
  }
92750
93042
  runtime2 = await startPairingRuntime({
92751
- relayUrl: connectRelayUrl,
92752
- advertisedRelayUrl: activeRelayUrl,
92753
- fallbackRelayUrls: managedRelay?.fallbackRelayUrls,
93043
+ relayEndpoints,
92754
93044
  relayEvents: {
92755
- onConnecting() {
92756
- emitOrQueue(createStatusEvent("connecting", `Connecting to ${activeRelayUrl}`));
93045
+ onConnecting(detail) {
93046
+ emitOrQueue(createStatusEvent("connecting", `Connecting to ${detail?.relayUrl ?? activeRelayUrl}`));
92757
93047
  },
92758
93048
  onConnected({ room }) {
92759
93049
  emitOrQueue(createStatusEvent("connected", `Relay room ${room} is ready`));
@@ -92818,6 +93108,19 @@ function freshPairingPayload(pairing) {
92818
93108
  expiresAt: Date.now() + PAIRING_QR_TTL_MS
92819
93109
  };
92820
93110
  }
93111
+ function dedupeRelayUrls2(relayUrls) {
93112
+ const seen = new Set;
93113
+ const result = [];
93114
+ for (const relayUrl of relayUrls) {
93115
+ const trimmed = relayUrl.trim();
93116
+ if (!trimmed || seen.has(trimmed)) {
93117
+ continue;
93118
+ }
93119
+ seen.add(trimmed);
93120
+ result.push(trimmed);
93121
+ }
93122
+ return result;
93123
+ }
92821
93124
  var init_service7 = __esm(() => {
92822
93125
  init_runtime2();
92823
93126
  });
@@ -92989,8 +93292,8 @@ __export(exports_session, {
92989
93292
  import { spawnSync as spawnSync8 } from "child_process";
92990
93293
  import { createHash as createHash6 } from "crypto";
92991
93294
  import { mkdirSync as mkdirSync15 } from "fs";
92992
- import { homedir as homedir39 } from "os";
92993
- import { basename as basename17, join as join49, resolve as resolve27 } from "path";
93295
+ import { homedir as homedir40 } from "os";
93296
+ import { basename as basename17, join as join50, resolve as resolve27 } from "path";
92994
93297
  async function runSessionCommand(context, args) {
92995
93298
  const action = args[0];
92996
93299
  if (!action || action === "help" || action === "--help" || action === "-h") {
@@ -93282,7 +93585,7 @@ function readOptionValue(args, index2, flag) {
93282
93585
  }
93283
93586
  function resolveProjectPath2(context, projectPath) {
93284
93587
  const rawPath = projectPath?.trim() || context.cwd;
93285
- const expanded = rawPath === "~" ? context.env.HOME?.trim() || homedir39() : rawPath.startsWith("~/") ? resolve27(context.env.HOME?.trim() || homedir39(), rawPath.slice(2)) : rawPath;
93588
+ const expanded = rawPath === "~" ? context.env.HOME?.trim() || homedir40() : rawPath.startsWith("~/") ? resolve27(context.env.HOME?.trim() || homedir40(), rawPath.slice(2)) : rawPath;
93286
93589
  return resolve27(context.cwd, expanded);
93287
93590
  }
93288
93591
  function resolveControlPlaneDbPath2(context) {
@@ -93290,8 +93593,8 @@ function resolveControlPlaneDbPath2(context) {
93290
93593
  if (explicitPath) {
93291
93594
  return explicitPath;
93292
93595
  }
93293
- const controlHome = context.env.OPENSCOUT_CONTROL_HOME?.trim() || join49(context.env.HOME?.trim() || homedir39(), ".openscout", "control-plane");
93294
- return join49(controlHome, "control-plane.sqlite");
93596
+ const controlHome = context.env.OPENSCOUT_CONTROL_HOME?.trim() || join50(context.env.HOME?.trim() || homedir40(), ".openscout", "control-plane");
93597
+ return join50(controlHome, "control-plane.sqlite");
93295
93598
  }
93296
93599
  function openTerminalSessionStore(context) {
93297
93600
  return new SQLiteControlPlaneStore(resolveControlPlaneDbPath2(context));
@@ -93415,7 +93718,7 @@ function assertZellijAvailable(context) {
93415
93718
  }
93416
93719
  function resolveZellijSocketDir(context) {
93417
93720
  const configured = context.env.ZELLIJ_SOCKET_DIR?.trim() || context.env.OPENSCOUT_ZELLIJ_SOCKET_DIR?.trim();
93418
- return configured || join49(context.env.HOME?.trim() || homedir39(), ".openscout", "zellij-sockets");
93721
+ return configured || join50(context.env.HOME?.trim() || homedir40(), ".openscout", "zellij-sockets");
93419
93722
  }
93420
93723
  function zellijEnv(context) {
93421
93724
  const socketDir = resolveZellijSocketDir(context);
@@ -93720,9 +94023,9 @@ __export(exports_server, {
93720
94023
  normalizeServerOpenPath: () => normalizeServerOpenPath
93721
94024
  });
93722
94025
  import { spawn as spawn8 } from "child_process";
93723
- import { existsSync as existsSync40, mkdirSync as mkdirSync16, openSync as openSync2, writeFileSync as writeFileSync11 } from "fs";
93724
- import { homedir as homedir40 } from "os";
93725
- import { dirname as dirname24, join as join50, resolve as resolve28 } from "path";
94026
+ import { existsSync as existsSync41, mkdirSync as mkdirSync16, openSync as openSync2, writeFileSync as writeFileSync11 } from "fs";
94027
+ import { homedir as homedir41 } from "os";
94028
+ import { dirname as dirname24, join as join51, resolve as resolve28 } from "path";
93726
94029
  import { fileURLToPath as fileURLToPath12 } from "url";
93727
94030
  function renderServerCommandHelp() {
93728
94031
  return [
@@ -93966,17 +94269,17 @@ function appendEnvListValues(input, values) {
93966
94269
  }
93967
94270
  function resolveBundledStaticClientRoot(entry, _mode) {
93968
94271
  const entryDir = dirname24(entry);
93969
- const clientDirectory = join50(entryDir, "client");
93970
- const indexPath = join50(clientDirectory, "index.html");
93971
- return existsSync40(indexPath) ? clientDirectory : null;
94272
+ const clientDirectory = join51(entryDir, "client");
94273
+ const indexPath = join51(clientDirectory, "index.html");
94274
+ return existsSync41(indexPath) ? clientDirectory : null;
93972
94275
  }
93973
94276
  function resolveDevCheckoutWebClientRoot(env) {
93974
94277
  const setupCwd = env.OPENSCOUT_SETUP_CWD?.trim();
93975
94278
  if (!setupCwd)
93976
94279
  return null;
93977
- const clientDirectory = join50(setupCwd, "packages/web/dist/client");
93978
- const indexPath = join50(clientDirectory, "index.html");
93979
- return existsSync40(indexPath) ? clientDirectory : null;
94280
+ const clientDirectory = join51(setupCwd, "packages/web/dist/client");
94281
+ const indexPath = join51(clientDirectory, "index.html");
94282
+ return existsSync41(indexPath) ? clientDirectory : null;
93980
94283
  }
93981
94284
  function resolveBunExecutable4(env) {
93982
94285
  const bun = resolveBunExecutable(env);
@@ -94273,14 +94576,14 @@ async function openBrowser(url2) {
94273
94576
  });
94274
94577
  }
94275
94578
  function resolveScoutWebServerLogPath() {
94276
- const dir = join50(homedir40(), ".scout", "logs");
94579
+ const dir = join51(homedir41(), ".scout", "logs");
94277
94580
  mkdirSync16(dir, { recursive: true });
94278
- return join50(dir, "web-server.log");
94581
+ return join51(dir, "web-server.log");
94279
94582
  }
94280
94583
  function resolveScoutLocalEdgeCaddyfilePath() {
94281
- const dir = join50(homedir40(), ".scout", "local-edge");
94584
+ const dir = join51(homedir41(), ".scout", "local-edge");
94282
94585
  mkdirSync16(dir, { recursive: true });
94283
- return join50(dir, "Caddyfile");
94586
+ return join51(dir, "Caddyfile");
94284
94587
  }
94285
94588
  function resolveCaddyExecutable2(env) {
94286
94589
  return env.OPENSCOUT_CADDY_BIN?.trim() || "caddy";
@@ -95120,8 +95423,8 @@ import { EventEmitter as EventEmitter2 } from "events";
95120
95423
  import { resolve as resolve29, dirname as dirname25 } from "path";
95121
95424
  import { fileURLToPath as fileURLToPath13 } from "url";
95122
95425
  import { resolve as resolve210, isAbsolute as isAbsolute7, parse as parse7 } from "path";
95123
- import { existsSync as existsSync41 } from "fs";
95124
- import { basename as basename18, join as join51 } from "path";
95426
+ import { existsSync as existsSync42 } from "fs";
95427
+ import { basename as basename18, join as join52 } from "path";
95125
95428
  import os from "os";
95126
95429
  import path2 from "path";
95127
95430
  import { EventEmitter as EventEmitter3 } from "events";
@@ -98412,7 +98715,7 @@ function getBunfsRootPath() {
98412
98715
  return process.platform === "win32" ? "B:\\~BUN\\root" : "/$bunfs/root";
98413
98716
  }
98414
98717
  function normalizeBunfsPath(fileName) {
98415
- return join51(getBunfsRootPath(), basename18(fileName));
98718
+ return join52(getBunfsRootPath(), basename18(fileName));
98416
98719
  }
98417
98720
  function addDefaultParsers(parsers) {
98418
98721
  for (const parser of parsers) {
@@ -109334,7 +109637,7 @@ var init_index_vy1rm1x3 = __esm(async () => {
109334
109637
  worker_path = this.options.workerPath;
109335
109638
  } else {
109336
109639
  worker_path = new URL("./parser.worker.js", import.meta.url).href;
109337
- if (!existsSync41(resolve210(import.meta.dirname, "parser.worker.js"))) {
109640
+ if (!existsSync42(resolve210(import.meta.dirname, "parser.worker.js"))) {
109338
109641
  worker_path = new URL("./parser.worker.ts", import.meta.url).href;
109339
109642
  }
109340
109643
  }
@@ -156626,7 +156929,7 @@ var exports_up = {};
156626
156929
  __export(exports_up, {
156627
156930
  runUpCommand: () => runUpCommand
156628
156931
  });
156629
- import { existsSync as existsSync42 } from "fs";
156932
+ import { existsSync as existsSync43 } from "fs";
156630
156933
  import { resolve as resolve31 } from "path";
156631
156934
  function looksLikePath(value) {
156632
156935
  return value.includes("/") || value.startsWith(".") || value.startsWith("~");
@@ -156735,7 +157038,7 @@ async function runUpCommand(context, args) {
156735
157038
  throw new ScoutCliError(`usage: scout up <name|path> [--name <alias>] [--harness <claude|codex|grok|pi>] [--provider <provider>] [--model <model>] [--reasoning-effort <effort>] [--permission-profile <${formatScoutPermissionProfiles()}>]`);
156736
157039
  }
156737
157040
  let projectPath;
156738
- if (looksLikePath(target) || existsSync42(resolve31(target))) {
157041
+ if (looksLikePath(target) || existsSync43(resolve31(target))) {
156739
157042
  projectPath = resolve31(target);
156740
157043
  } else {
156741
157044
  const resolved = await resolveLocalAgentByName(target);
@@ -157193,13 +157496,13 @@ __export(exports_whoami, {
157193
157496
  renderWhoAmICommandHelp: () => renderWhoAmICommandHelp
157194
157497
  });
157195
157498
  import { access as access2 } from "fs/promises";
157196
- import { join as join54 } from "path";
157499
+ import { join as join55 } from "path";
157197
157500
  async function resolveProjectAgentsMd(projectRoot) {
157198
157501
  if (!projectRoot) {
157199
157502
  return null;
157200
157503
  }
157201
157504
  for (const candidate of PROJECT_AGENT_INSTRUCTION_CANDIDATES) {
157202
- const path6 = join54(projectRoot, candidate);
157505
+ const path6 = join55(projectRoot, candidate);
157203
157506
  try {
157204
157507
  await access2(path6);
157205
157508
  return path6;
@@ -157279,10 +157582,10 @@ var init_whoami = __esm(() => {
157279
157582
  });
157280
157583
 
157281
157584
  // ../../apps/desktop/src/cli/main.ts
157282
- import { existsSync as existsSync43, readFileSync as readFileSync22, writeFileSync as writeFileSync13, statSync as statSync8, mkdirSync as mkdirSync17, unlinkSync as unlinkSync4 } from "fs";
157283
- import { join as join55 } from "path";
157585
+ import { existsSync as existsSync44, readFileSync as readFileSync22, writeFileSync as writeFileSync13, statSync as statSync9, mkdirSync as mkdirSync17, unlinkSync as unlinkSync4 } from "fs";
157586
+ import { join as join56 } from "path";
157284
157587
  import { spawnSync as spawnSync9 } from "child_process";
157285
- import { homedir as homedir41 } from "os";
157588
+ import { homedir as homedir42 } from "os";
157286
157589
 
157287
157590
  // ../../apps/desktop/src/cli/argv.ts
157288
157591
  function parseScoutArgv(argv) {
@@ -157648,8 +157951,8 @@ var _scoutBinPath = null;
157648
157951
  function getScoutBinPath() {
157649
157952
  if (_scoutBinPath)
157650
157953
  return _scoutBinPath;
157651
- _scoutBinPath = join55(homedir41(), ".bun", "bin", "scout");
157652
- if (!existsSync43(_scoutBinPath)) {
157954
+ _scoutBinPath = join56(homedir42(), ".bun", "bin", "scout");
157955
+ if (!existsSync44(_scoutBinPath)) {
157653
157956
  _scoutBinPath = spawnSync9("which", ["scout"], { encoding: "utf8" }).stdout.trim();
157654
157957
  }
157655
157958
  return _scoutBinPath;
@@ -157692,7 +157995,7 @@ async function ensureBrokerUptodate(report = () => {
157692
157995
  return;
157693
157996
  }
157694
157997
  const mtimePath = cliMtimeCheckpointPath();
157695
- const lastMtime = existsSync43(mtimePath) ? Number(readFileSync22(mtimePath, "utf8").trim()) : 0;
157998
+ const lastMtime = existsSync44(mtimePath) ? Number(readFileSync22(mtimePath, "utf8").trim()) : 0;
157696
157999
  if (shouldRestartBrokerForCliMtime(mtime, lastMtime)) {
157697
158000
  report("Scout CLI changed on disk; restarting the broker service to load the updated runtime.");
157698
158001
  await restartBrokerServiceWithLaunchctl();
@@ -157702,17 +158005,17 @@ async function ensureBrokerUptodate(report = () => {
157702
158005
  }
157703
158006
  function readCurrentCliMtime() {
157704
158007
  try {
157705
- return normalizeCliBinaryMtimeMs(statSync8(getScoutBinPath()).mtimeMs);
158008
+ return normalizeCliBinaryMtimeMs(statSync9(getScoutBinPath()).mtimeMs);
157706
158009
  } catch {
157707
158010
  return null;
157708
158011
  }
157709
158012
  }
157710
158013
  function cliMtimeCheckpointPath() {
157711
- return join55(homedir41(), ".scout", "cli-mtime");
158014
+ return join56(homedir42(), ".scout", "cli-mtime");
157712
158015
  }
157713
158016
  function writeCliMtimeCheckpoint(mtime) {
157714
- const checkpointDir = join55(homedir41(), ".scout");
157715
- if (!existsSync43(checkpointDir)) {
158017
+ const checkpointDir = join56(homedir42(), ".scout");
158018
+ if (!existsSync44(checkpointDir)) {
157716
158019
  mkdirSync17(checkpointDir, { recursive: true });
157717
158020
  }
157718
158021
  writeFileSync13(cliMtimeCheckpointPath(), String(mtime), { encoding: "utf8", flag: "w" });
@@ -157735,7 +158038,7 @@ async function restartBrokerServiceWithLaunchctl() {
157735
158038
  for (const legacyLabel of legacyBrokerServiceLabels(config3.mode)) {
157736
158039
  spawnSync9("launchctl", ["bootout", `gui/${uid}/${legacyLabel}`], { stdio: "ignore" });
157737
158040
  try {
157738
- unlinkSync4(join55(homedir41(), "Library", "LaunchAgents", `${legacyLabel}.plist`));
158041
+ unlinkSync4(join56(homedir42(), "Library", "LaunchAgents", `${legacyLabel}.plist`));
157739
158042
  } catch {}
157740
158043
  }
157741
158044
  spawnSync9("launchctl", ["bootout", `gui/${uid}/${config3.label}`], { stdio: "ignore" });