@openscout/scout 0.2.51 → 0.2.53

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.
@@ -3376,7 +3376,7 @@ function writeJsonAtomically(filePath, value) {
3376
3376
  }
3377
3377
 
3378
3378
  // ../../apps/desktop/src/core/pairing/runtime/runtime.ts
3379
- import { homedir as homedir17 } from "os";
3379
+ import { homedir as homedir18 } from "os";
3380
3380
  // ../agent-sessions/src/protocol/adapter.ts
3381
3381
  class BaseAdapter {
3382
3382
  config;
@@ -4436,9 +4436,144 @@ function decodeClaudeProjectsSlug(slug) {
4436
4436
  }
4437
4437
  // ../agent-sessions/src/adapters/codex.ts
4438
4438
  import { spawn } from "child_process";
4439
- import { access, appendFile, constants, mkdir, readFile, rm, writeFile } from "fs/promises";
4440
- import { delimiter, join as join4 } from "path";
4439
+ import { access, appendFile, constants as constants2, mkdir, readFile, rm, writeFile } from "fs/promises";
4440
+ import { delimiter as delimiter2, join as join5 } from "path";
4441
+ import { homedir as homedir6 } from "os";
4442
+
4443
+ // ../agent-sessions/src/codex-launch-config.ts
4444
+ import { accessSync, constants, existsSync as existsSync6 } from "fs";
4441
4445
  import { homedir as homedir5 } from "os";
4446
+ import { basename, delimiter, dirname, join as join4, resolve } from "path";
4447
+ import { fileURLToPath } from "url";
4448
+ function isExecutable(filePath) {
4449
+ if (!filePath) {
4450
+ return false;
4451
+ }
4452
+ try {
4453
+ accessSync(filePath, constants.X_OK);
4454
+ return true;
4455
+ } catch {
4456
+ return false;
4457
+ }
4458
+ }
4459
+ function uniquePaths(values) {
4460
+ return [...new Set(values.filter((value) => typeof value === "string" && value.trim().length > 0).map((value) => resolve(value)))];
4461
+ }
4462
+ function ancestorChain(start) {
4463
+ const chain = [];
4464
+ let current = resolve(start);
4465
+ while (true) {
4466
+ chain.push(current);
4467
+ const parent = dirname(current);
4468
+ if (parent === current) {
4469
+ return chain;
4470
+ }
4471
+ current = parent;
4472
+ }
4473
+ }
4474
+ function resolveExecutableFromSearchPath(names, env) {
4475
+ const pathEntries = (env.PATH ?? "").split(delimiter).filter(Boolean);
4476
+ const commonDirectories = [
4477
+ join4(homedir5(), ".local", "bin"),
4478
+ join4(homedir5(), ".bun", "bin"),
4479
+ "/opt/homebrew/bin",
4480
+ "/usr/local/bin"
4481
+ ];
4482
+ for (const directory of [...pathEntries, ...commonDirectories]) {
4483
+ for (const name of names) {
4484
+ const candidate = join4(directory, name);
4485
+ if (isExecutable(candidate)) {
4486
+ return candidate;
4487
+ }
4488
+ }
4489
+ }
4490
+ return null;
4491
+ }
4492
+ function resolveBunExecutable(env) {
4493
+ const explicitCandidates = [
4494
+ env.OPENSCOUT_BUN_BIN,
4495
+ env.SCOUT_BUN_BIN,
4496
+ env.BUN_BIN
4497
+ ];
4498
+ for (const candidate of explicitCandidates) {
4499
+ if (isExecutable(candidate)) {
4500
+ return candidate;
4501
+ }
4502
+ }
4503
+ if (basename(process.execPath).startsWith("bun") && isExecutable(process.execPath)) {
4504
+ return process.execPath;
4505
+ }
4506
+ return resolveExecutableFromSearchPath(["bun"], env);
4507
+ }
4508
+ function resolveScoutExecutable(env) {
4509
+ const explicitCandidates = [
4510
+ env.OPENSCOUT_CLI_BIN,
4511
+ env.SCOUT_CLI_BIN,
4512
+ env.OPENSCOUT_SCOUT_BIN,
4513
+ env.SCOUT_BIN
4514
+ ];
4515
+ for (const candidate of explicitCandidates) {
4516
+ if (isExecutable(candidate)) {
4517
+ return candidate;
4518
+ }
4519
+ }
4520
+ return resolveExecutableFromSearchPath(["scout"], env);
4521
+ }
4522
+ function resolveRepoScoutScript(currentDirectory) {
4523
+ const moduleDirectory = dirname(fileURLToPath(import.meta.url));
4524
+ const starts = uniquePaths([currentDirectory, moduleDirectory]);
4525
+ for (const start of starts) {
4526
+ for (const candidate of ancestorChain(start)) {
4527
+ const scriptPath = join4(candidate, "apps", "desktop", "bin", "scout.ts");
4528
+ if (existsSync6(scriptPath)) {
4529
+ return scriptPath;
4530
+ }
4531
+ }
4532
+ }
4533
+ return null;
4534
+ }
4535
+ function resolveContextRoot(currentDirectory, env) {
4536
+ const configured = env.OPENSCOUT_SETUP_CWD?.trim();
4537
+ return resolve(configured || currentDirectory);
4538
+ }
4539
+ function resolveScoutMcpCommand(options) {
4540
+ const env = options.env ?? process.env;
4541
+ const contextRoot = resolveContextRoot(options.currentDirectory, env);
4542
+ const scoutExecutable = resolveScoutExecutable(env);
4543
+ if (scoutExecutable) {
4544
+ return {
4545
+ command: scoutExecutable,
4546
+ args: ["mcp", "--context-root", contextRoot],
4547
+ cwd: contextRoot
4548
+ };
4549
+ }
4550
+ const scoutScript = resolveRepoScoutScript(options.currentDirectory);
4551
+ const bunExecutable = resolveBunExecutable(env);
4552
+ if (scoutScript && bunExecutable) {
4553
+ return {
4554
+ command: bunExecutable,
4555
+ args: [scoutScript, "mcp", "--context-root", contextRoot],
4556
+ cwd: contextRoot
4557
+ };
4558
+ }
4559
+ return null;
4560
+ }
4561
+ function buildScoutMcpCodexLaunchArgs(options) {
4562
+ const resolved = resolveScoutMcpCommand(options);
4563
+ if (!resolved) {
4564
+ return [];
4565
+ }
4566
+ return [
4567
+ "-c",
4568
+ `mcp_servers.scout.command=${JSON.stringify(resolved.command)}`,
4569
+ "-c",
4570
+ `mcp_servers.scout.args=${JSON.stringify(resolved.args)}`,
4571
+ "-c",
4572
+ `mcp_servers.scout.cwd=${JSON.stringify(resolved.cwd)}`
4573
+ ];
4574
+ }
4575
+
4576
+ // ../agent-sessions/src/adapters/codex.ts
4442
4577
  function parseJsonLine(line) {
4443
4578
  try {
4444
4579
  return JSON.parse(line);
@@ -4559,12 +4694,12 @@ function renderActionOutput(item) {
4559
4694
  function isMissingCodexRolloutError(error) {
4560
4695
  return errorMessage(error).toLowerCase().includes("no rollout found for thread id");
4561
4696
  }
4562
- async function isExecutable(filePath) {
4697
+ async function isExecutable2(filePath) {
4563
4698
  if (!filePath) {
4564
4699
  return false;
4565
4700
  }
4566
4701
  try {
4567
- await access(filePath, constants.X_OK);
4702
+ await access(filePath, constants2.X_OK);
4568
4703
  return true;
4569
4704
  } catch {
4570
4705
  return false;
@@ -4576,11 +4711,11 @@ async function resolveCodexExecutable() {
4576
4711
  process.env.CODEX_BIN
4577
4712
  ].filter(Boolean);
4578
4713
  for (const candidate of explicitCandidates) {
4579
- if (await isExecutable(candidate)) {
4714
+ if (await isExecutable2(candidate)) {
4580
4715
  return candidate;
4581
4716
  }
4582
4717
  }
4583
- const pathEntries = (process.env.PATH ?? "").split(delimiter).filter(Boolean);
4718
+ const pathEntries = (process.env.PATH ?? "").split(delimiter2).filter(Boolean);
4584
4719
  const commonDirectories = [
4585
4720
  `${process.env.HOME ?? ""}/.local/bin`,
4586
4721
  `${process.env.HOME ?? ""}/.bun/bin`,
@@ -4588,8 +4723,8 @@ async function resolveCodexExecutable() {
4588
4723
  "/usr/local/bin"
4589
4724
  ].filter(Boolean);
4590
4725
  for (const directory of [...pathEntries, ...commonDirectories]) {
4591
- const candidate = join4(directory, "codex");
4592
- if (await isExecutable(candidate)) {
4726
+ const candidate = join5(directory, "codex");
4727
+ if (await isExecutable2(candidate)) {
4593
4728
  return candidate;
4594
4729
  }
4595
4730
  }
@@ -4691,7 +4826,7 @@ class CodexAdapter extends BaseAdapter {
4691
4826
  this.pendingRequests.clear();
4692
4827
  if (child && child.exitCode === null && !child.killed) {
4693
4828
  child.kill("SIGTERM");
4694
- await new Promise((resolve) => setTimeout(resolve, 250));
4829
+ await new Promise((resolve2) => setTimeout(resolve2, 250));
4695
4830
  if (child.exitCode === null && !child.killed) {
4696
4831
  child.kill("SIGKILL");
4697
4832
  }
@@ -4700,7 +4835,7 @@ class CodexAdapter extends BaseAdapter {
4700
4835
  await this.persistState();
4701
4836
  }
4702
4837
  get codexOptions() {
4703
- const runtimeRoot = join4(homedir5(), ".scout/pairing", "codex", this.session.id);
4838
+ const runtimeRoot = join5(homedir6(), ".scout/pairing", "codex", this.session.id);
4704
4839
  const configuredThreadId = this.config.options?.["threadId"];
4705
4840
  const requireExistingThread = this.config.options?.["requireExistingThread"];
4706
4841
  const rawLaunchArgs = this.config.options?.["launchArgs"];
@@ -4710,8 +4845,8 @@ class CodexAdapter extends BaseAdapter {
4710
4845
  sessionId: this.session.id,
4711
4846
  cwd: this.config.cwd ?? process.cwd(),
4712
4847
  systemPrompt: this.systemPrompt,
4713
- runtimeDirectory: join4(runtimeRoot, "runtime"),
4714
- logsDirectory: join4(runtimeRoot, "logs"),
4848
+ runtimeDirectory: join5(runtimeRoot, "runtime"),
4849
+ logsDirectory: join5(runtimeRoot, "logs"),
4715
4850
  launchArgs,
4716
4851
  threadId: typeof configuredThreadId === "string" && configuredThreadId.trim().length > 0 ? configuredThreadId.trim() : undefined,
4717
4852
  requireExistingThread: requireExistingThread ?? Boolean(configuredThreadId)
@@ -4722,16 +4857,16 @@ class CodexAdapter extends BaseAdapter {
4722
4857
  return typeof raw === "string" && raw.trim().length > 0 ? raw : "You are a helpful agent working through Pairing.";
4723
4858
  }
4724
4859
  get threadIdPath() {
4725
- return join4(this.codexOptions.runtimeDirectory, "codex-thread-id.txt");
4860
+ return join5(this.codexOptions.runtimeDirectory, "codex-thread-id.txt");
4726
4861
  }
4727
4862
  get statePath() {
4728
- return join4(this.codexOptions.runtimeDirectory, "state.json");
4863
+ return join5(this.codexOptions.runtimeDirectory, "state.json");
4729
4864
  }
4730
4865
  get stdoutLogPath() {
4731
- return join4(this.codexOptions.logsDirectory, "stdout.log");
4866
+ return join5(this.codexOptions.logsDirectory, "stdout.log");
4732
4867
  }
4733
4868
  get stderrLogPath() {
4734
- return join4(this.codexOptions.logsDirectory, "stderr.log");
4869
+ return join5(this.codexOptions.logsDirectory, "stderr.log");
4735
4870
  }
4736
4871
  enqueue(task) {
4737
4872
  const next = this.serialized.then(task, task);
@@ -4760,14 +4895,22 @@ class CodexAdapter extends BaseAdapter {
4760
4895
  const options = this.codexOptions;
4761
4896
  await mkdir(options.runtimeDirectory, { recursive: true });
4762
4897
  await mkdir(options.logsDirectory, { recursive: true });
4763
- await writeFile(join4(options.runtimeDirectory, "prompt.txt"), options.systemPrompt);
4898
+ await writeFile(join5(options.runtimeDirectory, "prompt.txt"), options.systemPrompt);
4764
4899
  const codexExecutable = await resolveCodexExecutable();
4765
- const child = spawn(codexExecutable, ["app-server", ...options.launchArgs], {
4900
+ const childEnv = {
4901
+ ...process.env,
4902
+ ...this.config.env ?? {}
4903
+ };
4904
+ const child = spawn(codexExecutable, [
4905
+ "app-server",
4906
+ ...buildScoutMcpCodexLaunchArgs({
4907
+ currentDirectory: options.cwd,
4908
+ env: childEnv
4909
+ }),
4910
+ ...options.launchArgs
4911
+ ], {
4766
4912
  cwd: options.cwd,
4767
- env: {
4768
- ...process.env,
4769
- ...this.config.env ?? {}
4770
- },
4913
+ env: childEnv,
4771
4914
  stdio: ["pipe", "pipe", "pipe"]
4772
4915
  });
4773
4916
  this.process = child;
@@ -5477,9 +5620,9 @@ class CodexAdapter extends BaseAdapter {
5477
5620
  }
5478
5621
  async request(method, params) {
5479
5622
  const id = String(this.nextRequestId++);
5480
- return new Promise((resolve, reject) => {
5623
+ return new Promise((resolve2, reject) => {
5481
5624
  this.pendingRequests.set(id, {
5482
- resolve: (value) => resolve(value),
5625
+ resolve: (value) => resolve2(value),
5483
5626
  reject
5484
5627
  });
5485
5628
  try {
@@ -6825,8 +6968,8 @@ class EchoAdapter extends BaseAdapter {
6825
6968
  blockId: actionId,
6826
6969
  approval: { version: 1, description: `Run echo tool with: ${text}`, risk: "low" }
6827
6970
  });
6828
- const decision = await new Promise((resolve) => {
6829
- this.pendingApprovals.set(this.approvalKey(turnId, actionId), { resolve });
6971
+ const decision = await new Promise((resolve2) => {
6972
+ this.pendingApprovals.set(this.approvalKey(turnId, actionId), { resolve: resolve2 });
6830
6973
  });
6831
6974
  if (this.interrupted) {
6832
6975
  this.emitTurnEnd(sessionId, turnId, "stopped");
@@ -6901,15 +7044,15 @@ class EchoAdapter extends BaseAdapter {
6901
7044
  delay() {
6902
7045
  if (this.stepDelay <= 0)
6903
7046
  return Promise.resolve();
6904
- return new Promise((resolve) => setTimeout(resolve, this.stepDelay));
7047
+ return new Promise((resolve2) => setTimeout(resolve2, this.stepDelay));
6905
7048
  }
6906
7049
  }
6907
7050
  // ../../apps/desktop/src/core/pairing/runtime/bridge/log.ts
6908
7051
  import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync6 } from "fs";
6909
- import { join as join5 } from "path";
6910
- import { homedir as homedir6 } from "os";
6911
- var LOG_DIR = join5(homedir6(), ".scout/pairing");
6912
- var LOG_FILE = join5(LOG_DIR, "bridge.log");
7052
+ import { join as join6 } from "path";
7053
+ import { homedir as homedir7 } from "os";
7054
+ var LOG_DIR = join6(homedir7(), ".scout/pairing");
7055
+ var LOG_FILE = join6(LOG_DIR, "bridge.log");
6913
7056
  mkdirSync6(LOG_DIR, { recursive: true });
6914
7057
  function write2(level, category, message, data) {
6915
7058
  const ts = new Date().toISOString().slice(11, 23);
@@ -6993,17 +7136,17 @@ class Bridge {
6993
7136
  }
6994
7137
 
6995
7138
  // ../../apps/desktop/src/core/pairing/runtime/bridge/config.ts
6996
- import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
6997
- import { join as join6 } from "path";
6998
- import { homedir as homedir7 } from "os";
7139
+ import { existsSync as existsSync7, readFileSync as readFileSync4 } from "fs";
7140
+ import { join as join7 } from "path";
7141
+ import { homedir as homedir8 } from "os";
6999
7142
  var DEFAULTS = {
7000
7143
  port: 7888,
7001
7144
  secure: true
7002
7145
  };
7003
- var CONFIG_DIR = join6(homedir7(), ".scout/pairing");
7004
- var CONFIG_FILE = join6(CONFIG_DIR, "config.json");
7146
+ var CONFIG_DIR = join7(homedir8(), ".scout/pairing");
7147
+ var CONFIG_FILE = join7(CONFIG_DIR, "config.json");
7005
7148
  function loadConfigFile() {
7006
- if (!existsSync6(CONFIG_FILE)) {
7149
+ if (!existsSync7(CONFIG_FILE)) {
7007
7150
  return {};
7008
7151
  }
7009
7152
  try {
@@ -7061,12 +7204,12 @@ function resolveConfig() {
7061
7204
 
7062
7205
  // ../../apps/desktop/src/core/pairing/runtime/bridge/fileserver.ts
7063
7206
  import { isAbsolute } from "path";
7064
- import { homedir as homedir8 } from "os";
7065
- var ALLOWED_ROOTS = [homedir8(), "/tmp"];
7207
+ import { homedir as homedir9 } from "os";
7208
+ var ALLOWED_ROOTS = [homedir9(), "/tmp"];
7066
7209
  function isAllowedPath(filePath) {
7067
7210
  if (!isAbsolute(filePath))
7068
7211
  return false;
7069
- const relToHome = filePath.slice(homedir8().length + 1);
7212
+ const relToHome = filePath.slice(homedir9().length + 1);
7070
7213
  if (relToHome.startsWith(".") && !relToHome.startsWith(".claude") && !relToHome.startsWith(".scout/pairing")) {
7071
7214
  return false;
7072
7215
  }
@@ -7127,56 +7270,56 @@ function serveFile(url) {
7127
7270
  // ../../apps/desktop/src/core/pairing/runtime/bridge/server.ts
7128
7271
  import { readdirSync as readdirSync3, readFileSync as readFileSync8, realpathSync, statSync as statSync3 } from "fs";
7129
7272
  import { execSync as execSync3 } from "child_process";
7130
- import { basename as basename5, isAbsolute as isAbsolute3, join as join16, relative as relative2 } from "path";
7131
- import { homedir as homedir14 } from "os";
7273
+ import { basename as basename6, isAbsolute as isAbsolute3, join as join17, relative as relative2 } from "path";
7274
+ import { homedir as homedir15 } from "os";
7132
7275
 
7133
7276
  // ../../apps/desktop/src/core/mobile/service.ts
7134
- import { basename as basename4, resolve as resolve5 } from "path";
7277
+ import { basename as basename5, resolve as resolve6 } from "path";
7135
7278
 
7136
7279
  // ../runtime/src/harness-catalog.ts
7137
7280
  import { execFileSync } from "child_process";
7138
- import { existsSync as existsSync8, statSync as statSync2 } from "fs";
7281
+ import { existsSync as existsSync9, statSync as statSync2 } from "fs";
7139
7282
  import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
7140
- import { dirname, join as join8 } from "path";
7283
+ import { dirname as dirname2, join as join9 } from "path";
7141
7284
 
7142
7285
  // ../runtime/src/support-paths.ts
7143
- import { existsSync as existsSync7, mkdirSync as mkdirSync7, rmSync, writeFileSync as writeFileSync4 } from "fs";
7144
- import { homedir as homedir9 } from "os";
7145
- import { join as join7 } from "path";
7286
+ import { existsSync as existsSync8, mkdirSync as mkdirSync7, rmSync, writeFileSync as writeFileSync4 } from "fs";
7287
+ import { homedir as homedir10 } from "os";
7288
+ import { join as join8 } from "path";
7146
7289
  var OPENSCOUT_RPC_CUTOVER_MARKER = "rpc-runtime-cutover-v1";
7147
7290
  function resolveOpenScoutSupportPaths() {
7148
- const home = homedir9();
7149
- const supportDirectory = process.env.OPENSCOUT_SUPPORT_DIRECTORY ?? join7(home, "Library", "Application Support", "OpenScout");
7150
- const logsDirectory = join7(supportDirectory, "logs");
7151
- const runtimeDirectory = join7(supportDirectory, "runtime");
7152
- const catalogDirectory = join7(supportDirectory, "catalog");
7291
+ const home = homedir10();
7292
+ const supportDirectory = process.env.OPENSCOUT_SUPPORT_DIRECTORY ?? join8(home, "Library", "Application Support", "OpenScout");
7293
+ const logsDirectory = join8(supportDirectory, "logs");
7294
+ const runtimeDirectory = join8(supportDirectory, "runtime");
7295
+ const catalogDirectory = join8(supportDirectory, "catalog");
7153
7296
  return {
7154
7297
  supportDirectory,
7155
7298
  logsDirectory,
7156
- appLogsDirectory: join7(logsDirectory, "app"),
7157
- brokerLogsDirectory: join7(logsDirectory, "broker"),
7299
+ appLogsDirectory: join8(logsDirectory, "app"),
7300
+ brokerLogsDirectory: join8(logsDirectory, "broker"),
7158
7301
  runtimeDirectory,
7159
7302
  catalogDirectory,
7160
- relayAgentsDirectory: join7(runtimeDirectory, "agents"),
7161
- settingsPath: join7(supportDirectory, "settings.json"),
7162
- harnessCatalogPath: join7(catalogDirectory, "harness-catalog.json"),
7163
- relayAgentsRegistryPath: join7(supportDirectory, "relay-agents.json"),
7164
- relayHubDirectory: process.env.OPENSCOUT_RELAY_HUB ?? join7(home, ".openscout", "relay"),
7165
- controlHome: process.env.OPENSCOUT_CONTROL_HOME ?? join7(home, ".openscout", "control-plane"),
7166
- desktopStatusPath: join7(supportDirectory, "agent-status.json"),
7167
- workspaceStatePath: join7(supportDirectory, "workspace-state.json"),
7168
- cutoverMarkerPath: join7(supportDirectory, OPENSCOUT_RPC_CUTOVER_MARKER)
7303
+ relayAgentsDirectory: join8(runtimeDirectory, "agents"),
7304
+ settingsPath: join8(supportDirectory, "settings.json"),
7305
+ harnessCatalogPath: join8(catalogDirectory, "harness-catalog.json"),
7306
+ relayAgentsRegistryPath: join8(supportDirectory, "relay-agents.json"),
7307
+ relayHubDirectory: process.env.OPENSCOUT_RELAY_HUB ?? join8(home, ".openscout", "relay"),
7308
+ controlHome: process.env.OPENSCOUT_CONTROL_HOME ?? join8(home, ".openscout", "control-plane"),
7309
+ desktopStatusPath: join8(supportDirectory, "agent-status.json"),
7310
+ workspaceStatePath: join8(supportDirectory, "workspace-state.json"),
7311
+ cutoverMarkerPath: join8(supportDirectory, OPENSCOUT_RPC_CUTOVER_MARKER)
7169
7312
  };
7170
7313
  }
7171
7314
  function relayAgentRuntimeDirectory(agentId) {
7172
- return join7(resolveOpenScoutSupportPaths().relayAgentsDirectory, agentId);
7315
+ return join8(resolveOpenScoutSupportPaths().relayAgentsDirectory, agentId);
7173
7316
  }
7174
7317
  function relayAgentLogsDirectory(agentId) {
7175
- return join7(relayAgentRuntimeDirectory(agentId), "logs");
7318
+ return join8(relayAgentRuntimeDirectory(agentId), "logs");
7176
7319
  }
7177
7320
  function ensureOpenScoutCleanSlateSync() {
7178
7321
  const paths = resolveOpenScoutSupportPaths();
7179
- if (existsSync7(paths.cutoverMarkerPath)) {
7322
+ if (existsSync8(paths.cutoverMarkerPath)) {
7180
7323
  return;
7181
7324
  }
7182
7325
  rmSync(paths.supportDirectory, { recursive: true, force: true });
@@ -7267,7 +7410,7 @@ function expandHomePath(value) {
7267
7410
  if (value === "~")
7268
7411
  return process.env.HOME || value;
7269
7412
  if (value.startsWith("~/"))
7270
- return join8(process.env.HOME || "~", value.slice(2));
7413
+ return join9(process.env.HOME || "~", value.slice(2));
7271
7414
  return value;
7272
7415
  }
7273
7416
  function defaultWhichBinary(binary, platform) {
@@ -7301,7 +7444,7 @@ function defaultRunCommand(command, platform) {
7301
7444
  }
7302
7445
  function defaultRequirementExists(requirement) {
7303
7446
  const expanded = expandHomePath(requirement.path);
7304
- if (!existsSync8(expanded))
7447
+ if (!existsSync9(expanded))
7305
7448
  return false;
7306
7449
  if (requirement.fileType === "any" || !requirement.fileType)
7307
7450
  return true;
@@ -7496,7 +7639,7 @@ async function readHarnessCatalogOverrides(overridePath = resolveOpenScoutSuppor
7496
7639
  }
7497
7640
  }
7498
7641
  async function writeHarnessCatalogOverrides(overrides, overridePath = resolveOpenScoutSupportPaths().harnessCatalogPath) {
7499
- await mkdir2(dirname(overridePath), { recursive: true });
7642
+ await mkdir2(dirname2(overridePath), { recursive: true });
7500
7643
  const payload = {
7501
7644
  version: HARNESS_CATALOG_VERSION,
7502
7645
  entries: overrides,
@@ -7506,7 +7649,7 @@ async function writeHarnessCatalogOverrides(overrides, overridePath = resolveOpe
7506
7649
  `, "utf8");
7507
7650
  }
7508
7651
  async function ensureHarnessCatalogOverrideFile(overridePath = resolveOpenScoutSupportPaths().harnessCatalogPath) {
7509
- if (existsSync8(overridePath))
7652
+ if (existsSync9(overridePath))
7510
7653
  return;
7511
7654
  await writeHarnessCatalogOverrides({}, overridePath);
7512
7655
  }
@@ -7529,11 +7672,11 @@ async function loadHarnessCatalogSnapshot(options = {}) {
7529
7672
 
7530
7673
  // ../runtime/src/setup.ts
7531
7674
  import { execFileSync as execFileSync2 } from "child_process";
7532
- import { existsSync as existsSync9, readFileSync as readFileSync5 } from "fs";
7675
+ import { existsSync as existsSync10, readFileSync as readFileSync5 } from "fs";
7533
7676
  import { access as access2, mkdir as mkdir3, readdir as readdir2, readFile as readFile4, realpath, rm as rm2, stat as stat2, writeFile as writeFile3 } from "fs/promises";
7534
- import { homedir as homedir11, hostname, userInfo } from "os";
7535
- import { basename, dirname as dirname3, isAbsolute as isAbsolute2, join as join10, relative, resolve as resolve2 } from "path";
7536
- import { fileURLToPath as fileURLToPath2 } from "url";
7677
+ import { homedir as homedir12, hostname, userInfo } from "os";
7678
+ import { basename as basename2, dirname as dirname4, isAbsolute as isAbsolute2, join as join11, relative, resolve as resolve3 } from "path";
7679
+ import { fileURLToPath as fileURLToPath3 } from "url";
7537
7680
 
7538
7681
  // ../../node_modules/.bun/smol-toml@1.6.1/node_modules/smol-toml/dist/error.js
7539
7682
  /*!
@@ -8766,9 +8909,9 @@ function buildScoutReturnAddress(input) {
8766
8909
  }
8767
8910
  // ../runtime/src/user-project-hints.ts
8768
8911
  import { readdir, readFile as readFile3, stat } from "fs/promises";
8769
- import { homedir as homedir10 } from "os";
8770
- import { dirname as dirname2, join as join9, resolve } from "path";
8771
- import { fileURLToPath } from "url";
8912
+ import { homedir as homedir11 } from "os";
8913
+ import { dirname as dirname3, join as join10, resolve as resolve2 } from "path";
8914
+ import { fileURLToPath as fileURLToPath2 } from "url";
8772
8915
  var PROJECT_HINT_MARKERS = [
8773
8916
  ".git",
8774
8917
  ".openscout/project.json",
@@ -8793,18 +8936,18 @@ function decodeClaudeProjectsSlug2(name) {
8793
8936
  return `/${tail.replace(/-/g, "/")}`;
8794
8937
  }
8795
8938
  function encodeClaudeProjectsSlug(absolutePath) {
8796
- const normalized = resolve(absolutePath);
8939
+ const normalized = resolve2(absolutePath);
8797
8940
  return `-${normalized.replace(/^\//, "").replace(/\//g, "-")}`;
8798
8941
  }
8799
8942
  async function resolveExistingDirectoryHint(pathLike) {
8800
- const absolutePath = resolve(pathLike);
8943
+ const absolutePath = resolve2(pathLike);
8801
8944
  try {
8802
8945
  const info = await stat(absolutePath);
8803
8946
  if (info.isDirectory()) {
8804
8947
  return absolutePath;
8805
8948
  }
8806
8949
  if (info.isFile()) {
8807
- return dirname2(absolutePath);
8950
+ return dirname3(absolutePath);
8808
8951
  }
8809
8952
  } catch {
8810
8953
  return null;
@@ -8820,18 +8963,18 @@ async function pathExists(pathLike) {
8820
8963
  }
8821
8964
  }
8822
8965
  async function findLikelyProjectRoot(absolutePath) {
8823
- let current = resolve(absolutePath);
8966
+ let current = resolve2(absolutePath);
8824
8967
  let lastCandidate = null;
8825
8968
  while (true) {
8826
8969
  for (const marker of PROJECT_HINT_MARKERS) {
8827
- if (await pathExists(join9(current, marker))) {
8970
+ if (await pathExists(join10(current, marker))) {
8828
8971
  lastCandidate = current;
8829
8972
  if (marker === ".git" || marker === ".openscout/project.json") {
8830
8973
  return current;
8831
8974
  }
8832
8975
  }
8833
8976
  }
8834
- const parent = dirname2(current);
8977
+ const parent = dirname3(current);
8835
8978
  if (parent === current) {
8836
8979
  return lastCandidate ?? absolutePath;
8837
8980
  }
@@ -8847,16 +8990,16 @@ async function appendPathHint(pathLike, roots) {
8847
8990
  }
8848
8991
  function cursorWorkspaceStoragePath(home) {
8849
8992
  if (process.platform === "darwin") {
8850
- return join9(home, "Library", "Application Support", "Cursor", "User", "workspaceStorage");
8993
+ return join10(home, "Library", "Application Support", "Cursor", "User", "workspaceStorage");
8851
8994
  }
8852
8995
  if (process.platform === "win32") {
8853
8996
  const appData = process.env.APPDATA;
8854
8997
  if (appData) {
8855
- return join9(appData, "Cursor", "User", "workspaceStorage");
8998
+ return join10(appData, "Cursor", "User", "workspaceStorage");
8856
8999
  }
8857
- return join9(home, "AppData", "Roaming", "Cursor", "User", "workspaceStorage");
9000
+ return join10(home, "AppData", "Roaming", "Cursor", "User", "workspaceStorage");
8858
9001
  }
8859
- return join9(home, ".config", "Cursor", "User", "workspaceStorage");
9002
+ return join10(home, ".config", "Cursor", "User", "workspaceStorage");
8860
9003
  }
8861
9004
  function collectPathLikeStrings(value, out, depth) {
8862
9005
  if (depth > 4 || value === null || value === undefined) {
@@ -8885,7 +9028,7 @@ function collectPathLikeStrings(value, out, depth) {
8885
9028
  }
8886
9029
  }
8887
9030
  async function appendCodexHistoryPaths(home, roots) {
8888
- const candidates = [join9(home, ".codex", "history.jsonl"), join9(home, ".openai-codex", "history.jsonl")];
9031
+ const candidates = [join10(home, ".codex", "history.jsonl"), join10(home, ".openai-codex", "history.jsonl")];
8889
9032
  const maxLines = 2500;
8890
9033
  const maxBytes = 4 * 1024 * 1024;
8891
9034
  for (const filePath of candidates) {
@@ -8936,7 +9079,7 @@ async function appendCursorWorkspacePaths(home, roots) {
8936
9079
  return;
8937
9080
  }
8938
9081
  for (const id of ids) {
8939
- const workspaceJsonPath = join9(base, id, "workspace.json");
9082
+ const workspaceJsonPath = join10(base, id, "workspace.json");
8940
9083
  let raw;
8941
9084
  try {
8942
9085
  raw = await readFile3(workspaceJsonPath, "utf8");
@@ -8951,13 +9094,13 @@ async function appendCursorWorkspacePaths(home, roots) {
8951
9094
  }
8952
9095
  if (typeof doc.folder === "string" && doc.folder.startsWith("file://")) {
8953
9096
  try {
8954
- const folderPath = fileURLToPath(doc.folder);
9097
+ const folderPath = fileURLToPath2(doc.folder);
8955
9098
  await appendPathHint(folderPath, roots);
8956
9099
  } catch {}
8957
9100
  }
8958
9101
  if (typeof doc.workspace === "string" && doc.workspace.startsWith("file://")) {
8959
9102
  try {
8960
- const wsFile = fileURLToPath(doc.workspace);
9103
+ const wsFile = fileURLToPath2(doc.workspace);
8961
9104
  if (!wsFile.endsWith(".code-workspace")) {
8962
9105
  continue;
8963
9106
  }
@@ -8972,12 +9115,12 @@ async function appendCursorWorkspacePaths(home, roots) {
8972
9115
  }
8973
9116
  const wsRaw = await readFile3(wsFile, "utf8");
8974
9117
  const wsDoc = JSON.parse(wsRaw);
8975
- const wsDir = dirname2(wsFile);
9118
+ const wsDir = dirname3(wsFile);
8976
9119
  for (const f of wsDoc.folders ?? []) {
8977
9120
  if (typeof f.path !== "string" || !f.path) {
8978
9121
  continue;
8979
9122
  }
8980
- const resolvedPath = resolve(wsDir, f.path);
9123
+ const resolvedPath = resolve2(wsDir, f.path);
8981
9124
  await appendPathHint(resolvedPath, roots);
8982
9125
  }
8983
9126
  } catch {}
@@ -8985,7 +9128,7 @@ async function appendCursorWorkspacePaths(home, roots) {
8985
9128
  }
8986
9129
  }
8987
9130
  async function appendClaudeProjectSlugs(home, roots) {
8988
- const projectsDir = join9(home, ".claude", "projects");
9131
+ const projectsDir = join10(home, ".claude", "projects");
8989
9132
  let names = [];
8990
9133
  try {
8991
9134
  names = await readdir(projectsDir, { withFileTypes: false });
@@ -9001,7 +9144,7 @@ async function appendClaudeProjectSlugs(home, roots) {
9001
9144
  }
9002
9145
  }
9003
9146
  async function appendClaudeSessionPaths(home, roots) {
9004
- const projectsDir = join9(home, ".claude", "projects");
9147
+ const projectsDir = join10(home, ".claude", "projects");
9005
9148
  const maxProjectDirectories = 200;
9006
9149
  const maxSessionFiles = 400;
9007
9150
  const maxLinesPerFile = 400;
@@ -9016,7 +9159,7 @@ async function appendClaudeSessionPaths(home, roots) {
9016
9159
  for (const projectName of projectNames) {
9017
9160
  let entries = [];
9018
9161
  try {
9019
- entries = await readdir(join9(projectsDir, projectName), { withFileTypes: false });
9162
+ entries = await readdir(join10(projectsDir, projectName), { withFileTypes: false });
9020
9163
  } catch {
9021
9164
  continue;
9022
9165
  }
@@ -9027,7 +9170,7 @@ async function appendClaudeSessionPaths(home, roots) {
9027
9170
  if (!entry.endsWith(".jsonl")) {
9028
9171
  continue;
9029
9172
  }
9030
- const sessionPath = join9(projectsDir, projectName, entry);
9173
+ const sessionPath = join10(projectsDir, projectName, entry);
9031
9174
  let info;
9032
9175
  try {
9033
9176
  info = await stat(sessionPath);
@@ -9069,7 +9212,7 @@ async function appendClaudeSessionPaths(home, roots) {
9069
9212
  }
9070
9213
  }
9071
9214
  async function collectUserLevelProjectRootHints(options = {}) {
9072
- const home = options.home ?? homedir10();
9215
+ const home = options.home ?? homedir11();
9073
9216
  const roots = new Set;
9074
9217
  try {
9075
9218
  await appendClaudeProjectSlugs(home, roots);
@@ -9237,7 +9380,7 @@ async function matchNestedMarkers(projectRoot, nestedMarkers) {
9237
9380
  if (nestedMarkers.length === 0) {
9238
9381
  return [];
9239
9382
  }
9240
- const hits = await Promise.all(nestedMarkers.map(async (marker) => await pathExists2(join10(projectRoot, marker)) ? marker : null));
9383
+ const hits = await Promise.all(nestedMarkers.map(async (marker) => await pathExists2(join11(projectRoot, marker)) ? marker : null));
9241
9384
  return hits.filter((marker) => Boolean(marker));
9242
9385
  }
9243
9386
  function nowSeconds() {
@@ -9245,21 +9388,21 @@ function nowSeconds() {
9245
9388
  }
9246
9389
  function expandHomePath2(value) {
9247
9390
  if (value === "~") {
9248
- return homedir11();
9391
+ return homedir12();
9249
9392
  }
9250
9393
  if (value.startsWith("~/")) {
9251
- return join10(homedir11(), value.slice(2));
9394
+ return join11(homedir12(), value.slice(2));
9252
9395
  }
9253
9396
  return value;
9254
9397
  }
9255
9398
  function normalizePath(value) {
9256
- return resolve2(expandHomePath2(value.trim() || "."));
9399
+ return resolve3(expandHomePath2(value.trim() || "."));
9257
9400
  }
9258
9401
  function normalizeProjectRelativePath(projectRoot, value) {
9259
9402
  const expanded = expandHomePath2(value.trim() || ".");
9260
- return isAbsolute2(expanded) ? resolve2(expanded) : resolve2(projectRoot, expanded);
9403
+ return isAbsolute2(expanded) ? resolve3(expanded) : resolve3(projectRoot, expanded);
9261
9404
  }
9262
- function uniquePaths(values) {
9405
+ function uniquePaths2(values) {
9263
9406
  return Array.from(new Set(Array.from(values).map((value) => normalizePath(value))));
9264
9407
  }
9265
9408
  function normalizeAgentId(value) {
@@ -9326,16 +9469,16 @@ function resolveTelegramConfigSeedValue(key, currentDirectory) {
9326
9469
  return envValue;
9327
9470
  }
9328
9471
  if (currentDirectory) {
9329
- const currentDirValue = readEnvFileValue(join10(currentDirectory, ".env.local"), key).trim();
9472
+ const currentDirValue = readEnvFileValue(join11(currentDirectory, ".env.local"), key).trim();
9330
9473
  if (currentDirValue) {
9331
9474
  return currentDirValue;
9332
9475
  }
9333
9476
  }
9334
- const home = homedir11();
9477
+ const home = homedir12();
9335
9478
  if (!home) {
9336
9479
  return "";
9337
9480
  }
9338
- return readEnvFileValue(join10(home, ".env.local"), key).trim();
9481
+ return readEnvFileValue(join11(home, ".env.local"), key).trim();
9339
9482
  }
9340
9483
  function normalizeTelegramBridgeMode(value) {
9341
9484
  const normalized = typeof value === "string" ? value.trim().toLowerCase() : "";
@@ -9612,13 +9755,13 @@ function defaultSettings() {
9612
9755
  };
9613
9756
  }
9614
9757
  function projectConfigPath(projectRoot) {
9615
- return join10(projectRoot, ".openscout", "project.json");
9758
+ return join11(projectRoot, ".openscout", "project.json");
9616
9759
  }
9617
9760
  function projectGitignorePath(projectRoot) {
9618
- return join10(projectRoot, ".gitignore");
9761
+ return join11(projectRoot, ".gitignore");
9619
9762
  }
9620
9763
  function legacyLocalRelayLinkPath(projectRoot) {
9621
- return join10(projectRoot, ".openscout", "relay.json");
9764
+ return join11(projectRoot, ".openscout", "relay.json");
9622
9765
  }
9623
9766
  async function pathExists2(filePath) {
9624
9767
  try {
@@ -9644,15 +9787,15 @@ async function readJsonFile(filePath) {
9644
9787
  }
9645
9788
  }
9646
9789
  async function writeJsonFile(filePath, value) {
9647
- await mkdir3(dirname3(filePath), { recursive: true });
9790
+ await mkdir3(dirname4(filePath), { recursive: true });
9648
9791
  await writeFile3(filePath, JSON.stringify(value, null, 2) + `
9649
9792
  `, "utf8");
9650
9793
  }
9651
9794
  function codexEnvironmentPath(projectRoot) {
9652
- return join10(projectRoot, ".codex", "environments", "environment.toml");
9795
+ return join11(projectRoot, ".codex", "environments", "environment.toml");
9653
9796
  }
9654
9797
  function currentHomeDirectory() {
9655
- return process.env.HOME?.trim() || homedir11();
9798
+ return process.env.HOME?.trim() || homedir12();
9656
9799
  }
9657
9800
  function normalizeProjectScriptSet(value) {
9658
9801
  if (typeof value !== "object" || !value) {
@@ -9808,11 +9951,11 @@ async function readCodexEnvironmentImport(projectRoot) {
9808
9951
  }
9809
9952
  async function readClaudeProjectImport(projectRoot) {
9810
9953
  const slug = encodeClaudeProjectsSlug(projectRoot);
9811
- const sourcePath = join10(currentHomeDirectory(), ".claude", "projects", slug);
9954
+ const sourcePath = join11(currentHomeDirectory(), ".claude", "projects", slug);
9812
9955
  if (!await isDirectory(sourcePath)) {
9813
9956
  return null;
9814
9957
  }
9815
- const memoryPath = await pathExists2(join10(sourcePath, "memory", "MEMORY.md")) ? join10(sourcePath, "memory", "MEMORY.md") : undefined;
9958
+ const memoryPath = await pathExists2(join11(sourcePath, "memory", "MEMORY.md")) ? join11(sourcePath, "memory", "MEMORY.md") : undefined;
9816
9959
  let entries = [];
9817
9960
  try {
9818
9961
  entries = await readdir2(sourcePath, { withFileTypes: false });
@@ -9827,7 +9970,7 @@ async function readClaudeProjectImport(projectRoot) {
9827
9970
  continue;
9828
9971
  }
9829
9972
  sessionCount += 1;
9830
- const sessionPath = join10(sourcePath, entry);
9973
+ const sessionPath = join11(sourcePath, entry);
9831
9974
  let body;
9832
9975
  try {
9833
9976
  body = await readFile4(sessionPath, "utf8");
@@ -9889,7 +10032,7 @@ function applyImportedEnvironmentSeeds(config, codexImport, projectRoot) {
9889
10032
  ...(config.environment?.actions?.length ?? 0) === 0 && importedEnvironment.actions ? { actions: importedEnvironment.actions } : {}
9890
10033
  };
9891
10034
  }
9892
- const defaultProjectName = titleCase(basename(projectRoot));
10035
+ const defaultProjectName = titleCase(basename2(projectRoot));
9893
10036
  if (codexImport?.name?.trim() && (!config.project.name?.trim() || config.project.name === defaultProjectName)) {
9894
10037
  next.project = {
9895
10038
  ...config.project,
@@ -9942,11 +10085,11 @@ async function ensureProjectConfigIgnored(projectRoot) {
9942
10085
  }
9943
10086
  async function readLegacyRelayConfig() {
9944
10087
  const relayHub = resolveOpenScoutSupportPaths().relayHubDirectory;
9945
- return readJsonFile(join10(relayHub, "config.json"));
10088
+ return readJsonFile(join11(relayHub, "config.json"));
9946
10089
  }
9947
10090
  async function readLegacyAgentRegistry() {
9948
10091
  const relayHub = resolveOpenScoutSupportPaths().relayHubDirectory;
9949
- return await readJsonFile(join10(relayHub, "agents.json")) ?? {};
10092
+ return await readJsonFile(join11(relayHub, "agents.json")) ?? {};
9950
10093
  }
9951
10094
  async function detectHarnessMarkers(projectRoot) {
9952
10095
  const detected = {
@@ -9955,7 +10098,7 @@ async function detectHarnessMarkers(projectRoot) {
9955
10098
  };
9956
10099
  for (const harness of MANAGED_AGENT_HARNESSES) {
9957
10100
  for (const marker of PROJECT_HARNESS_MARKERS[harness]) {
9958
- if (await pathExists2(join10(projectRoot, marker))) {
10101
+ if (await pathExists2(join11(projectRoot, marker))) {
9959
10102
  detected[harness].push(marker);
9960
10103
  }
9961
10104
  }
@@ -9992,8 +10135,8 @@ async function normalizeSettingsRecord(value, options = {}) {
9992
10135
  legacyAgents: options.legacyAgents ?? {}
9993
10136
  });
9994
10137
  const rawWorkspaceRoots = Array.isArray(discovery.workspaceRoots) ? discovery.workspaceRoots.map((entry) => String(entry)) : [];
9995
- const workspaceRoots = uniquePaths(rawWorkspaceRoots.length > 0 ? rawWorkspaceRoots : seededWorkspaceRoots);
9996
- const hiddenProjectRoots = uniquePaths(Array.isArray(discovery.hiddenProjectRoots) ? discovery.hiddenProjectRoots.map((entry) => String(entry)) : []);
10138
+ const workspaceRoots = uniquePaths2(rawWorkspaceRoots.length > 0 ? rawWorkspaceRoots : seededWorkspaceRoots);
10139
+ const hiddenProjectRoots = uniquePaths2(Array.isArray(discovery.hiddenProjectRoots) ? discovery.hiddenProjectRoots.map((entry) => String(entry)) : []);
9997
10140
  const contextRoot = normalizeOptionalString(discovery.contextRoot) ? normalizePath(String(discovery.contextRoot)) : null;
9998
10141
  const seededTelegramBotToken = resolveTelegramConfigSeedValue("TELEGRAM_BOT_TOKEN", options.currentDirectory);
9999
10142
  const seededTelegramSecretToken = resolveTelegramConfigSeedValue("TELEGRAM_WEBHOOK_SECRET_TOKEN", options.currentDirectory);
@@ -10057,7 +10200,7 @@ async function seedWorkspaceRoots(options) {
10057
10200
  const roots = new Set;
10058
10201
  const currentProjectRoot = options.currentDirectory ? await findNearestProjectRoot(options.currentDirectory) : null;
10059
10202
  if (currentProjectRoot) {
10060
- roots.add(dirname3(currentProjectRoot));
10203
+ roots.add(dirname4(currentProjectRoot));
10061
10204
  }
10062
10205
  const legacyRoot = options.legacyRelayConfig?.projectRoot?.trim();
10063
10206
  if (legacyRoot) {
@@ -10065,11 +10208,11 @@ async function seedWorkspaceRoots(options) {
10065
10208
  }
10066
10209
  for (const record of Object.values(options.legacyAgents ?? {})) {
10067
10210
  if (record.cwd?.trim()) {
10068
- roots.add(dirname3(normalizePath(record.cwd)));
10211
+ roots.add(dirname4(normalizePath(record.cwd)));
10069
10212
  }
10070
10213
  }
10071
10214
  if (roots.size === 0) {
10072
- roots.add(join10(homedir11(), "dev"));
10215
+ roots.add(join11(homedir12(), "dev"));
10073
10216
  }
10074
10217
  return Array.from(roots);
10075
10218
  }
@@ -10086,11 +10229,11 @@ async function readOpenScoutSettings(options = {}) {
10086
10229
  });
10087
10230
  }
10088
10231
  var SCOUT_SKILL_FILE_NAME = "SKILL.md";
10089
- var SETUP_MODULE_DIRECTORY = dirname3(fileURLToPath2(import.meta.url));
10090
- var SCOUT_SKILL_REPO_ROOT = resolve2(SETUP_MODULE_DIRECTORY, "..", "..", "..");
10232
+ var SETUP_MODULE_DIRECTORY = dirname4(fileURLToPath3(import.meta.url));
10233
+ var SCOUT_SKILL_REPO_ROOT = resolve3(SETUP_MODULE_DIRECTORY, "..", "..", "..");
10091
10234
  var SCOUT_SKILL_INSTALL_PATHS = {
10092
- claude: join10(homedir11(), ".claude", "skills", "scout", SCOUT_SKILL_FILE_NAME),
10093
- codex: join10(homedir11(), ".agents", "skills", "scout", SCOUT_SKILL_FILE_NAME)
10235
+ claude: join11(homedir12(), ".claude", "skills", "scout", SCOUT_SKILL_FILE_NAME),
10236
+ codex: join11(homedir12(), ".agents", "skills", "scout", SCOUT_SKILL_FILE_NAME)
10094
10237
  };
10095
10238
  async function readRelayAgentOverrides() {
10096
10239
  const supportPaths = resolveOpenScoutSupportPaths();
@@ -10173,13 +10316,13 @@ async function findNearestProjectRoot(startDirectory) {
10173
10316
  let current = normalizePath(startDirectory);
10174
10317
  let lastCandidate = null;
10175
10318
  while (true) {
10176
- if (await pathExists2(join10(current, ".git"))) {
10319
+ if (await pathExists2(join11(current, ".git"))) {
10177
10320
  return current;
10178
10321
  }
10179
- if (await pathExists2(projectConfigPath(current)) || await pathExists2(join10(current, "package.json")) || await pathExists2(join10(current, "AGENTS.md")) || await pathExists2(join10(current, "CLAUDE.md"))) {
10322
+ if (await pathExists2(projectConfigPath(current)) || await pathExists2(join11(current, "package.json")) || await pathExists2(join11(current, "AGENTS.md")) || await pathExists2(join11(current, "CLAUDE.md"))) {
10180
10323
  lastCandidate = current;
10181
10324
  }
10182
- const parent = dirname3(current);
10325
+ const parent = dirname4(current);
10183
10326
  if (parent === current) {
10184
10327
  return lastCandidate;
10185
10328
  }
@@ -10187,7 +10330,7 @@ async function findNearestProjectRoot(startDirectory) {
10187
10330
  }
10188
10331
  }
10189
10332
  function defaultProjectConfig(projectRoot, settings, preferredHarness) {
10190
- const projectName = basename(projectRoot);
10333
+ const projectName = basename2(projectRoot);
10191
10334
  const definitionId = normalizeAgentId(projectName);
10192
10335
  const relativeRoot = relative(projectRoot, projectRoot) || ".";
10193
10336
  return {
@@ -10361,7 +10504,7 @@ async function scanSourceRoot(sourceRoot) {
10361
10504
  if (PROJECT_SCAN_SKIP_DIRECTORIES.has(entry.name)) {
10362
10505
  continue;
10363
10506
  }
10364
- const nextPath = join10(currentDirectory, entry.name);
10507
+ const nextPath = join11(currentDirectory, entry.name);
10365
10508
  if (entry.isSymbolicLink()) {
10366
10509
  if (!await isDirectory(nextPath)) {
10367
10510
  continue;
@@ -10402,7 +10545,7 @@ function relativeProjectPath(projectRoot, sourceRoot) {
10402
10545
  return relative(sourceRoot, projectRoot) || ".";
10403
10546
  }
10404
10547
  function resolveProjectRootFromConfig(projectRoot, config) {
10405
- return normalizePath(join10(projectRoot, config.project.root ?? "."));
10548
+ return normalizePath(join11(projectRoot, config.project.root ?? "."));
10406
10549
  }
10407
10550
  function mergeResolvedAgentConfig(base, override, settings) {
10408
10551
  if (!override) {
@@ -10494,8 +10637,8 @@ function selectorFromInput(value) {
10494
10637
  }
10495
10638
  async function resolveManifestBackedAgent(projectRoot, config, settings, override) {
10496
10639
  const resolvedProjectRoot = resolveProjectRootFromConfig(projectRoot, config);
10497
- const projectName = config.project.name?.trim() || titleCase(config.project.id || basename(resolvedProjectRoot));
10498
- const fallbackDefinitionId = normalizeAgentId(config.project.id || basename(resolvedProjectRoot));
10640
+ const projectName = config.project.name?.trim() || titleCase(config.project.id || basename2(resolvedProjectRoot));
10641
+ const fallbackDefinitionId = normalizeAgentId(config.project.id || basename2(resolvedProjectRoot));
10499
10642
  const definitionId = normalizeAgentId(config.agent?.id || override?.definitionId || fallbackDefinitionId);
10500
10643
  const detectedHarness = await detectPreferredHarness(resolvedProjectRoot, settings.agents.defaultHarness);
10501
10644
  const runtimeDefaults = config.agent?.runtime?.defaults;
@@ -10532,7 +10675,7 @@ async function resolveManifestBackedAgent(projectRoot, config, settings, overrid
10532
10675
  return mergeResolvedAgentConfig(base, override, settings);
10533
10676
  }
10534
10677
  async function resolveInferredAgent(projectRoot, settings, override) {
10535
- const projectName = basename(projectRoot);
10678
+ const projectName = basename2(projectRoot);
10536
10679
  const definitionId = normalizeAgentId(override?.definitionId?.trim() || projectName);
10537
10680
  const detectedHarness = await detectPreferredHarness(projectRoot, settings.agents.defaultHarness);
10538
10681
  const defaultHarness = normalizeManagedHarness(override?.defaultHarness ?? override?.runtime?.harness, normalizeManagedHarness(detectedHarness, "claude"));
@@ -10568,7 +10711,7 @@ async function resolveInferredAgent(projectRoot, settings, override) {
10568
10711
  return mergeResolvedAgentConfig(base, override, settings);
10569
10712
  }
10570
10713
  async function buildProjectInventoryEntry(agent, sourceRoot) {
10571
- const manifestRoot = agent.projectConfigPath ? normalizePath(join10(dirname3(agent.projectConfigPath), "..")) : null;
10714
+ const manifestRoot = agent.projectConfigPath ? normalizePath(join11(dirname4(agent.projectConfigPath), "..")) : null;
10572
10715
  const manifest = manifestRoot ? await readProjectConfig(manifestRoot) : null;
10573
10716
  const markers = await detectHarnessMarkers(agent.projectRoot);
10574
10717
  const harnesses = new Map;
@@ -10676,7 +10819,7 @@ async function loadResolvedRelayAgents(options = {}) {
10676
10819
  const sourceRootByProject = new Map(workspaceCandidates.map((candidate) => [candidate.projectRoot, candidate.sourceRoot]));
10677
10820
  if (process.env.OPENSCOUT_SKIP_USER_PROJECT_HINTS !== "1") {
10678
10821
  try {
10679
- const hintHome = options.userLevelHintsHome ?? homedir11();
10822
+ const hintHome = options.userLevelHintsHome ?? homedir12();
10680
10823
  const userHints = await collectUserLevelProjectRootHints({ home: hintHome });
10681
10824
  for (const hint of userHints) {
10682
10825
  const normalized = normalizePath(hint);
@@ -10814,16 +10957,16 @@ async function ensureRelayAgentConfigured(value, options = {}) {
10814
10957
 
10815
10958
  // ../runtime/src/local-agents.ts
10816
10959
  import { execFileSync as execFileSync3, execSync as execSync2 } from "child_process";
10817
- import { existsSync as existsSync11, readFileSync as readFileSync7 } from "fs";
10960
+ import { existsSync as existsSync12, readFileSync as readFileSync7 } from "fs";
10818
10961
  import { mkdir as mkdir6, rm as rm5, stat as stat3, writeFile as writeFile6 } from "fs/promises";
10819
- import { basename as basename3, dirname as dirname5, join as join14, resolve as resolve4 } from "path";
10820
- import { fileURLToPath as fileURLToPath4 } from "url";
10962
+ import { basename as basename4, dirname as dirname6, join as join15, resolve as resolve5 } from "path";
10963
+ import { fileURLToPath as fileURLToPath5 } from "url";
10821
10964
 
10822
10965
  // ../runtime/src/claude-stream-json.ts
10823
10966
  import { randomUUID } from "crypto";
10824
10967
  import { spawn as spawn2 } from "child_process";
10825
10968
  import { appendFile as appendFile2, mkdir as mkdir4, readFile as readFile5, rm as rm3, writeFile as writeFile4 } from "fs/promises";
10826
- import { join as join11 } from "path";
10969
+ import { join as join12 } from "path";
10827
10970
 
10828
10971
  // ../runtime/src/managed-agent-environment.ts
10829
10972
  function managedAgentEnvironmentEntries(options) {
@@ -10885,9 +11028,9 @@ class ClaudeStreamJsonSession {
10885
11028
  lastConfigSignature;
10886
11029
  constructor(options) {
10887
11030
  this.options = options;
10888
- this.sessionStatePath = join11(options.runtimeDirectory, "claude-session-id.txt");
10889
- this.stdoutLogPath = join11(options.logsDirectory, "stdout.log");
10890
- this.stderrLogPath = join11(options.logsDirectory, "stderr.log");
11031
+ this.sessionStatePath = join12(options.runtimeDirectory, "claude-session-id.txt");
11032
+ this.stdoutLogPath = join12(options.logsDirectory, "stdout.log");
11033
+ this.stderrLogPath = join12(options.logsDirectory, "stderr.log");
10891
11034
  this.lastConfigSignature = this.configSignature(options);
10892
11035
  }
10893
11036
  matches(options) {
@@ -10914,13 +11057,13 @@ class ClaudeStreamJsonSession {
10914
11057
  if (this.activeTurn) {
10915
11058
  throw new Error(`Claude stream-json session for ${this.options.agentName} already has an active turn.`);
10916
11059
  }
10917
- const outputPromise = new Promise((resolve3, reject) => {
11060
+ const outputPromise = new Promise((resolve4, reject) => {
10918
11061
  const turn = {
10919
11062
  id: randomUUID(),
10920
11063
  output: [],
10921
11064
  timer: null,
10922
11065
  stallMs: stallTimeoutMs,
10923
- resolve: resolve3,
11066
+ resolve: resolve4,
10924
11067
  reject
10925
11068
  };
10926
11069
  this.activeTurn = turn;
@@ -11019,7 +11162,7 @@ class ClaudeStreamJsonSession {
11019
11162
  async startSession() {
11020
11163
  await mkdir4(this.options.runtimeDirectory, { recursive: true });
11021
11164
  await mkdir4(this.options.logsDirectory, { recursive: true });
11022
- await writeFile4(join11(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
11165
+ await writeFile4(join12(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
11023
11166
  this.claudeSessionId = await readOptionalFile2(this.sessionStatePath);
11024
11167
  const args = [
11025
11168
  "--print",
@@ -11163,7 +11306,7 @@ async function shutdownClaudeStreamJsonAgent(options, shutdownOptions = {}) {
11163
11306
  const session = sessions.get(key);
11164
11307
  if (!session) {
11165
11308
  if (shutdownOptions.resetSession) {
11166
- await rm3(join11(options.runtimeDirectory, "claude-session-id.txt"), { force: true });
11309
+ await rm3(join12(options.runtimeDirectory, "claude-session-id.txt"), { force: true });
11167
11310
  }
11168
11311
  return;
11169
11312
  }
@@ -11173,8 +11316,8 @@ async function shutdownClaudeStreamJsonAgent(options, shutdownOptions = {}) {
11173
11316
 
11174
11317
  // ../runtime/src/codex-app-server.ts
11175
11318
  import { spawn as spawn3 } from "child_process";
11176
- import { access as access3, appendFile as appendFile3, constants as constants2, mkdir as mkdir5, readFile as readFile6, rm as rm4, writeFile as writeFile5 } from "fs/promises";
11177
- import { delimiter as delimiter2, join as join12 } from "path";
11319
+ import { access as access3, appendFile as appendFile3, constants as constants3, mkdir as mkdir5, readFile as readFile6, rm as rm4, writeFile as writeFile5 } from "fs/promises";
11320
+ import { delimiter as delimiter3, join as join13 } from "path";
11178
11321
  function sessionKey2(options) {
11179
11322
  return `${options.agentName}:${options.sessionId}`;
11180
11323
  }
@@ -11189,12 +11332,12 @@ function metadataRecord(metadata, key) {
11189
11332
  }
11190
11333
  return value;
11191
11334
  }
11192
- async function isExecutable2(filePath) {
11335
+ async function isExecutable3(filePath) {
11193
11336
  if (!filePath) {
11194
11337
  return false;
11195
11338
  }
11196
11339
  try {
11197
- await access3(filePath, constants2.X_OK);
11340
+ await access3(filePath, constants3.X_OK);
11198
11341
  return true;
11199
11342
  } catch {
11200
11343
  return false;
@@ -11206,20 +11349,20 @@ async function resolveCodexExecutable2() {
11206
11349
  process.env.CODEX_BIN
11207
11350
  ].filter(Boolean);
11208
11351
  for (const candidate of explicitCandidates) {
11209
- if (await isExecutable2(candidate)) {
11352
+ if (await isExecutable3(candidate)) {
11210
11353
  return candidate;
11211
11354
  }
11212
11355
  }
11213
11356
  const bundledCandidates = [
11214
11357
  "/Applications/Codex.app/Contents/Resources/codex",
11215
- join12(process.env.HOME ?? "", "Applications", "Codex.app", "Contents", "Resources", "codex")
11358
+ join13(process.env.HOME ?? "", "Applications", "Codex.app", "Contents", "Resources", "codex")
11216
11359
  ].filter(Boolean);
11217
11360
  for (const candidate of bundledCandidates) {
11218
- if (await isExecutable2(candidate)) {
11361
+ if (await isExecutable3(candidate)) {
11219
11362
  return candidate;
11220
11363
  }
11221
11364
  }
11222
- const pathEntries = (process.env.PATH ?? "").split(delimiter2).filter(Boolean);
11365
+ const pathEntries = (process.env.PATH ?? "").split(delimiter3).filter(Boolean);
11223
11366
  const commonDirectories = [
11224
11367
  `${process.env.HOME ?? ""}/.local/bin`,
11225
11368
  `${process.env.HOME ?? ""}/.bun/bin`,
@@ -11227,8 +11370,8 @@ async function resolveCodexExecutable2() {
11227
11370
  "/usr/local/bin"
11228
11371
  ].filter(Boolean);
11229
11372
  for (const directory of [...pathEntries, ...commonDirectories]) {
11230
- const candidate = join12(directory, "codex");
11231
- if (await isExecutable2(candidate)) {
11373
+ const candidate = join13(directory, "codex");
11374
+ if (await isExecutable3(candidate)) {
11232
11375
  return candidate;
11233
11376
  }
11234
11377
  }
@@ -11304,10 +11447,10 @@ class CodexAppServerSession {
11304
11447
  constructor(options) {
11305
11448
  this.options = options;
11306
11449
  this.key = sessionKey2(options);
11307
- this.threadIdPath = join12(options.runtimeDirectory, "codex-thread-id.txt");
11308
- this.statePath = join12(options.runtimeDirectory, "state.json");
11309
- this.stdoutLogPath = join12(options.logsDirectory, "stdout.log");
11310
- this.stderrLogPath = join12(options.logsDirectory, "stderr.log");
11450
+ this.threadIdPath = join13(options.runtimeDirectory, "codex-thread-id.txt");
11451
+ this.statePath = join13(options.runtimeDirectory, "state.json");
11452
+ this.stdoutLogPath = join13(options.logsDirectory, "stdout.log");
11453
+ this.stderrLogPath = join13(options.logsDirectory, "stderr.log");
11311
11454
  this.lastConfigSignature = this.configSignature(options);
11312
11455
  }
11313
11456
  matches(options) {
@@ -11335,8 +11478,8 @@ class CodexAppServerSession {
11335
11478
  if (!this.threadId) {
11336
11479
  throw new Error(`Codex app-server session for ${this.options.agentName} has no active thread.`);
11337
11480
  }
11338
- const output = await new Promise(async (resolve3, reject) => {
11339
- const turn = this.createActiveTurn(resolve3, reject, timeoutMs);
11481
+ const output = await new Promise(async (resolve4, reject) => {
11482
+ const turn = this.createActiveTurn(resolve4, reject, timeoutMs);
11340
11483
  try {
11341
11484
  const response = await this.request("turn/start", {
11342
11485
  threadId: this.threadId,
@@ -11374,8 +11517,8 @@ class CodexAppServerSession {
11374
11517
  if (!activeTurn?.turnId) {
11375
11518
  return this.invoke(prompt, timeoutMs);
11376
11519
  }
11377
- const output = await new Promise(async (resolve3, reject) => {
11378
- const watcher = this.addTurnWatcher(activeTurn, resolve3, reject, timeoutMs);
11520
+ const output = await new Promise(async (resolve4, reject) => {
11521
+ const watcher = this.addTurnWatcher(activeTurn, resolve4, reject, timeoutMs);
11379
11522
  try {
11380
11523
  await this.request("turn/steer", {
11381
11524
  threadId: this.threadId,
@@ -11444,7 +11587,7 @@ class CodexAppServerSession {
11444
11587
  this.lineBuffer = "";
11445
11588
  if (child && child.exitCode === null && !child.killed) {
11446
11589
  child.kill("SIGTERM");
11447
- await new Promise((resolve3) => setTimeout(resolve3, 250));
11590
+ await new Promise((resolve4) => setTimeout(resolve4, 250));
11448
11591
  if (child.exitCode === null && !child.killed) {
11449
11592
  child.kill("SIGKILL");
11450
11593
  }
@@ -11492,15 +11635,22 @@ class CodexAppServerSession {
11492
11635
  async startSession() {
11493
11636
  await mkdir5(this.options.runtimeDirectory, { recursive: true });
11494
11637
  await mkdir5(this.options.logsDirectory, { recursive: true });
11495
- await writeFile5(join12(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
11638
+ await writeFile5(join13(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
11496
11639
  const codexExecutable = await resolveCodexExecutable2();
11497
- const child = spawn3(codexExecutable, ["app-server"], {
11498
- cwd: this.options.cwd,
11499
- env: buildManagedAgentEnvironment({
11500
- agentName: this.options.agentName,
11640
+ const env = buildManagedAgentEnvironment({
11641
+ agentName: this.options.agentName,
11642
+ currentDirectory: this.options.cwd,
11643
+ baseEnv: process.env
11644
+ });
11645
+ const child = spawn3(codexExecutable, [
11646
+ "app-server",
11647
+ ...buildScoutMcpCodexLaunchArgs({
11501
11648
  currentDirectory: this.options.cwd,
11502
- baseEnv: process.env
11503
- }),
11649
+ env
11650
+ })
11651
+ ], {
11652
+ cwd: this.options.cwd,
11653
+ env,
11504
11654
  stdio: ["pipe", "pipe", "pipe"]
11505
11655
  });
11506
11656
  this.process = child;
@@ -11587,7 +11737,7 @@ class CodexAppServerSession {
11587
11737
  this.threadPath = started.thread.path ?? null;
11588
11738
  await this.persistThreadId();
11589
11739
  }
11590
- createActiveTurn(resolve3, reject, timeoutMs) {
11740
+ createActiveTurn(resolve4, reject, timeoutMs) {
11591
11741
  if (this.activeTurn) {
11592
11742
  throw new Error(`Codex app-server session for ${this.options.agentName} already has an active turn.`);
11593
11743
  }
@@ -11597,7 +11747,7 @@ class CodexAppServerSession {
11597
11747
  timer: null,
11598
11748
  messageOrder: [],
11599
11749
  messageByItemId: new Map,
11600
- resolve: resolve3,
11750
+ resolve: resolve4,
11601
11751
  reject,
11602
11752
  watchers: []
11603
11753
  };
@@ -11616,9 +11766,9 @@ class CodexAppServerSession {
11616
11766
  this.activeTurn = turn;
11617
11767
  return turn;
11618
11768
  }
11619
- addTurnWatcher(turn, resolve3, reject, timeoutMs) {
11769
+ addTurnWatcher(turn, resolve4, reject, timeoutMs) {
11620
11770
  const watcher = {
11621
- resolve: resolve3,
11771
+ resolve: resolve4,
11622
11772
  reject,
11623
11773
  timer: null
11624
11774
  };
@@ -11877,9 +12027,9 @@ class CodexAppServerSession {
11877
12027
  }
11878
12028
  async request(method, params) {
11879
12029
  const id = String(this.nextRequestId++);
11880
- return new Promise((resolve3, reject) => {
12030
+ return new Promise((resolve4, reject) => {
11881
12031
  this.pendingRequests.set(id, {
11882
- resolve: (value) => resolve3(value),
12032
+ resolve: (value) => resolve4(value),
11883
12033
  reject
11884
12034
  });
11885
12035
  try {
@@ -11936,7 +12086,7 @@ async function shutdownCodexAppServerAgent(options, shutdownOptions = {}) {
11936
12086
  if (!session) {
11937
12087
  if (shutdownOptions.resetThread) {
11938
12088
  const runtimeDirectory = options.runtimeDirectory;
11939
- await rm4(join12(runtimeDirectory, "codex-thread-id.txt"), { force: true });
12089
+ await rm4(join13(runtimeDirectory, "codex-thread-id.txt"), { force: true });
11940
12090
  }
11941
12091
  return;
11942
12092
  }
@@ -11949,10 +12099,13 @@ function buildCollaborationContractPrompt(agentId) {
11949
12099
  return [
11950
12100
  "Collaboration contract:",
11951
12101
  ` - Identity: act as the stable OpenScout agent "${agentId}" for this turn`,
12102
+ " - Default loop: orient -> resolve -> choose venue -> keep follow-up in that same venue",
11952
12103
  " - Treat information-seeking requests as questions and durable execution as work",
11953
12104
  " - Use collaboration verbs intentionally: answer, delegate, wait, review, complete",
11954
12105
  " - @mention another agent only when handing off real work or requesting a concrete answer",
12106
+ " - One target means DM; group coordination means an explicit channel or separate DMs",
11955
12107
  " - Do not broadcast ordinary delegation or wake agents who do not own the next move",
12108
+ " - Tell / update stays on the message path; owned work or a requested reply goes on the ask path",
11956
12109
  " - If you can answer safely, answer directly",
11957
12110
  " - If more work is required, make the next responsible agent explicit",
11958
12111
  " - If blocked, say what you are waiting on and who owns the next move",
@@ -11964,10 +12117,10 @@ function buildCollaborationContractPrompt(agentId) {
11964
12117
 
11965
12118
  // ../runtime/src/broker-service.ts
11966
12119
  import { spawnSync } from "child_process";
11967
- import { existsSync as existsSync10, mkdirSync as mkdirSync8, readFileSync as readFileSync6, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "fs";
11968
- import { homedir as homedir12 } from "os";
11969
- import { basename as basename2, dirname as dirname4, join as join13, resolve as resolve3 } from "path";
11970
- import { fileURLToPath as fileURLToPath3 } from "url";
12120
+ import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync6, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "fs";
12121
+ import { homedir as homedir13 } from "os";
12122
+ import { basename as basename3, dirname as dirname5, join as join14, resolve as resolve4 } from "path";
12123
+ import { fileURLToPath as fileURLToPath4 } from "url";
11971
12124
  function isTmpPath(p) {
11972
12125
  return /^\/(?:private\/)?tmp\//.test(p);
11973
12126
  }
@@ -12006,17 +12159,17 @@ function runtimePackageDir() {
12006
12159
  const fromCwd = findWorkspaceRuntimeDir(process.cwd());
12007
12160
  if (fromCwd)
12008
12161
  return fromCwd;
12009
- const moduleDir = dirname4(fileURLToPath3(import.meta.url));
12010
- return resolve3(moduleDir, "..");
12162
+ const moduleDir = dirname5(fileURLToPath4(import.meta.url));
12163
+ return resolve4(moduleDir, "..");
12011
12164
  }
12012
12165
  function isInstalledRuntimePackageDir(candidate) {
12013
- return existsSync10(join13(candidate, "package.json")) && existsSync10(join13(candidate, "bin", "openscout-runtime.mjs"));
12166
+ return existsSync11(join14(candidate, "package.json")) && existsSync11(join14(candidate, "bin", "openscout-runtime.mjs"));
12014
12167
  }
12015
12168
  function findGlobalRuntimeDir() {
12016
12169
  const candidates = [
12017
- join13(homedir12(), ".bun", "node_modules", "@openscout", "runtime"),
12018
- join13(homedir12(), ".bun", "install", "global", "node_modules", "@openscout", "runtime"),
12019
- join13(homedir12(), ".bun", "install", "global", "node_modules", "@openscout", "scout", "node_modules", "@openscout", "runtime")
12170
+ join14(homedir13(), ".bun", "node_modules", "@openscout", "runtime"),
12171
+ join14(homedir13(), ".bun", "install", "global", "node_modules", "@openscout", "runtime"),
12172
+ join14(homedir13(), ".bun", "install", "global", "node_modules", "@openscout", "scout", "node_modules", "@openscout", "runtime")
12020
12173
  ];
12021
12174
  for (const c of candidates) {
12022
12175
  if (isInstalledRuntimePackageDir(c))
@@ -12026,11 +12179,11 @@ function findGlobalRuntimeDir() {
12026
12179
  const result = spawnSync("which", ["scout"], { encoding: "utf8", timeout: 3000 });
12027
12180
  const scoutBin = result.stdout?.trim();
12028
12181
  if (scoutBin) {
12029
- const scoutPkg = resolve3(scoutBin, "..", "..");
12030
- const nested = join13(scoutPkg, "node_modules", "@openscout", "runtime");
12182
+ const scoutPkg = resolve4(scoutBin, "..", "..");
12183
+ const nested = join14(scoutPkg, "node_modules", "@openscout", "runtime");
12031
12184
  if (isInstalledRuntimePackageDir(nested))
12032
12185
  return nested;
12033
- const sibling = resolve3(scoutPkg, "..", "runtime");
12186
+ const sibling = resolve4(scoutPkg, "..", "runtime");
12034
12187
  if (isInstalledRuntimePackageDir(sibling))
12035
12188
  return sibling;
12036
12189
  }
@@ -12038,35 +12191,35 @@ function findGlobalRuntimeDir() {
12038
12191
  return null;
12039
12192
  }
12040
12193
  function findWorkspaceRuntimeDir(startDir) {
12041
- let current = resolve3(startDir);
12194
+ let current = resolve4(startDir);
12042
12195
  while (true) {
12043
- const candidate = join13(current, "packages", "runtime");
12044
- if (existsSync10(join13(candidate, "package.json")) && existsSync10(join13(candidate, "src"))) {
12196
+ const candidate = join14(current, "packages", "runtime");
12197
+ if (existsSync11(join14(candidate, "package.json")) && existsSync11(join14(candidate, "src"))) {
12045
12198
  return candidate;
12046
12199
  }
12047
- const parent = dirname4(current);
12200
+ const parent = dirname5(current);
12048
12201
  if (parent === current)
12049
12202
  return null;
12050
12203
  current = parent;
12051
12204
  }
12052
12205
  }
12053
- function resolveBunExecutable() {
12206
+ function resolveBunExecutable2() {
12054
12207
  const explicit = process.env.OPENSCOUT_BUN_BIN ?? process.env.BUN_BIN;
12055
12208
  if (explicit && explicit.trim().length > 0) {
12056
12209
  return explicit;
12057
12210
  }
12058
- if (basename2(process.execPath).startsWith("bun") && existsSync10(process.execPath)) {
12211
+ if (basename3(process.execPath).startsWith("bun") && existsSync11(process.execPath)) {
12059
12212
  return process.execPath;
12060
12213
  }
12061
12214
  const pathEntries = (process.env.PATH ?? "").split(":").filter(Boolean);
12062
12215
  for (const entry of pathEntries) {
12063
- const candidate = join13(entry, "bun");
12064
- if (existsSync10(candidate)) {
12216
+ const candidate = join14(entry, "bun");
12217
+ if (existsSync11(candidate)) {
12065
12218
  return candidate;
12066
12219
  }
12067
12220
  }
12068
- const homeBun = join13(homedir12(), ".bun", "bin", "bun");
12069
- if (existsSync10(homeBun)) {
12221
+ const homeBun = join14(homedir13(), ".bun", "bin", "bun");
12222
+ if (existsSync11(homeBun)) {
12070
12223
  return homeBun;
12071
12224
  }
12072
12225
  return "bun";
@@ -12108,15 +12261,15 @@ function resolveBrokerServiceConfig() {
12108
12261
  const label = resolveBrokerServiceLabel(mode);
12109
12262
  const uid = typeof process.getuid === "function" ? process.getuid() : Number.parseInt(process.env.UID ?? "0", 10);
12110
12263
  const supportPaths = resolveOpenScoutSupportPaths();
12111
- const defaultSupportDir = join13(homedir12(), "Library", "Application Support", "OpenScout");
12264
+ const defaultSupportDir = join14(homedir13(), "Library", "Application Support", "OpenScout");
12112
12265
  const supportDirectory = isTmpPath(supportPaths.supportDirectory) ? defaultSupportDir : supportPaths.supportDirectory;
12113
- const logsDirectory = join13(supportDirectory, "logs", "broker");
12114
- const controlHome = isTmpPath(supportPaths.controlHome) ? join13(homedir12(), ".openscout", "control-plane") : supportPaths.controlHome;
12266
+ const logsDirectory = join14(supportDirectory, "logs", "broker");
12267
+ const controlHome = isTmpPath(supportPaths.controlHome) ? join14(homedir13(), ".openscout", "control-plane") : supportPaths.controlHome;
12115
12268
  const advertiseScope = resolveAdvertiseScope();
12116
12269
  const brokerHost = resolveBrokerHost(advertiseScope);
12117
12270
  const brokerPort = Number.parseInt(process.env.OPENSCOUT_BROKER_PORT ?? String(DEFAULT_BROKER_PORT), 10);
12118
12271
  const brokerUrl = process.env.OPENSCOUT_BROKER_URL ?? buildDefaultBrokerUrl(brokerHost, brokerPort);
12119
- const launchAgentPath = join13(homedir12(), "Library", "LaunchAgents", `${label}.plist`);
12272
+ const launchAgentPath = join14(homedir13(), "Library", "LaunchAgents", `${label}.plist`);
12120
12273
  return {
12121
12274
  label,
12122
12275
  mode,
@@ -12126,11 +12279,11 @@ function resolveBrokerServiceConfig() {
12126
12279
  launchAgentPath,
12127
12280
  supportDirectory,
12128
12281
  logsDirectory,
12129
- stdoutLogPath: join13(logsDirectory, "stdout.log"),
12130
- stderrLogPath: join13(logsDirectory, "stderr.log"),
12282
+ stdoutLogPath: join14(logsDirectory, "stdout.log"),
12283
+ stderrLogPath: join14(logsDirectory, "stderr.log"),
12131
12284
  controlHome,
12132
12285
  runtimePackageDir: runtimePackageDir(),
12133
- bunExecutable: resolveBunExecutable(),
12286
+ bunExecutable: resolveBunExecutable2(),
12134
12287
  brokerHost,
12135
12288
  brokerPort,
12136
12289
  brokerUrl,
@@ -12147,7 +12300,7 @@ function renderLaunchAgentPlist(config) {
12147
12300
  OPENSCOUT_BROKER_SERVICE_MODE: config.mode,
12148
12301
  OPENSCOUT_BROKER_SERVICE_LABEL: config.label,
12149
12302
  OPENSCOUT_ADVERTISE_SCOPE: config.advertiseScope,
12150
- HOME: homedir12(),
12303
+ HOME: homedir13(),
12151
12304
  PATH: launchPath,
12152
12305
  ...collectOptionalEnvVars([
12153
12306
  "OPENSCOUT_MESH_ID",
@@ -12173,7 +12326,7 @@ function renderLaunchAgentPlist(config) {
12173
12326
  <key>ProgramArguments</key>
12174
12327
  <array>
12175
12328
  <string>${xmlEscape(config.bunExecutable)}</string>
12176
- <string>${xmlEscape(join13(config.runtimePackageDir, "bin", "openscout-runtime.mjs"))}</string>
12329
+ <string>${xmlEscape(join14(config.runtimePackageDir, "bin", "openscout-runtime.mjs"))}</string>
12177
12330
  <string>broker</string>
12178
12331
  </array>
12179
12332
  <key>WorkingDirectory</key>
@@ -12209,7 +12362,7 @@ function collectOptionalEnvVars(keys) {
12209
12362
  function resolveLaunchAgentPATH() {
12210
12363
  const entries = [
12211
12364
  ...(process.env.PATH ?? "").split(":").filter(Boolean),
12212
- join13(homedir12(), ".bun", "bin"),
12365
+ join14(homedir13(), ".bun", "bin"),
12213
12366
  "/opt/homebrew/bin",
12214
12367
  "/usr/local/bin",
12215
12368
  "/usr/bin",
@@ -12223,7 +12376,7 @@ function xmlEscape(value) {
12223
12376
  return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&apos;");
12224
12377
  }
12225
12378
  function ensureParentDirectory(filePath) {
12226
- mkdirSync8(dirname4(filePath), { recursive: true });
12379
+ mkdirSync8(dirname5(filePath), { recursive: true });
12227
12380
  }
12228
12381
  function ensureServiceDirectories(config) {
12229
12382
  ensureOpenScoutCleanSlateSync();
@@ -12256,7 +12409,7 @@ function launchctlPath() {
12256
12409
  return "/bin/launchctl";
12257
12410
  }
12258
12411
  function readLogLines(path2) {
12259
- if (!existsSync10(path2)) {
12412
+ if (!existsSync11(path2)) {
12260
12413
  return [];
12261
12414
  }
12262
12415
  return readFileSync6(path2, "utf8").split(`
@@ -12356,7 +12509,7 @@ async function brokerServiceStatus(config = resolveBrokerServiceConfig()) {
12356
12509
  ensureServiceDirectories(config);
12357
12510
  const launchctl = inspectLaunchctl(config);
12358
12511
  const health = await fetchHealthSnapshot(config);
12359
- const installed = existsSync10(config.launchAgentPath);
12512
+ const installed = existsSync11(config.launchAgentPath);
12360
12513
  const lastLogLine = health.reachable ? readLastLogLine([config.stdoutLogPath, config.stderrLogPath]) : readLastLogLine([config.stderrLogPath, config.stdoutLogPath]);
12361
12514
  return {
12362
12515
  label: config.label,
@@ -12399,7 +12552,7 @@ async function startBrokerService(config = resolveBrokerServiceConfig()) {
12399
12552
  throw new Error(status.lastLogLine ?? status.health.error ?? "Broker service did not become healthy.");
12400
12553
  }
12401
12554
  function sleep(ms) {
12402
- return new Promise((resolve4) => setTimeout(resolve4, ms));
12555
+ return new Promise((resolve5) => setTimeout(resolve5, ms));
12403
12556
  }
12404
12557
  async function stopBrokerService(config = resolveBrokerServiceConfig()) {
12405
12558
  runCommand(launchctlPath(), ["bootout", config.serviceTarget], { allowFailure: true });
@@ -12418,7 +12571,7 @@ async function restartBrokerService(config = resolveBrokerServiceConfig()) {
12418
12571
  }
12419
12572
  async function uninstallBrokerService(config = resolveBrokerServiceConfig()) {
12420
12573
  await stopBrokerService(config);
12421
- if (existsSync10(config.launchAgentPath)) {
12574
+ if (existsSync11(config.launchAgentPath)) {
12422
12575
  rmSync2(config.launchAgentPath, { force: true });
12423
12576
  }
12424
12577
  return brokerServiceStatus(config);
@@ -12476,7 +12629,7 @@ function formatBrokerServiceStatus(status) {
12476
12629
  return lines.join(`
12477
12630
  `);
12478
12631
  }
12479
- if (process.argv[1] && fileURLToPath3(import.meta.url) === process.argv[1]) {
12632
+ if (process.argv[1] && fileURLToPath4(import.meta.url) === process.argv[1]) {
12480
12633
  await main();
12481
12634
  }
12482
12635
 
@@ -12488,8 +12641,8 @@ var LOCAL_AGENT_SYSTEM_PROMPT_TEMPLATE_HINT = [
12488
12641
  ].join("");
12489
12642
 
12490
12643
  // ../runtime/src/local-agents.ts
12491
- var MODULE_DIRECTORY = dirname5(fileURLToPath4(import.meta.url));
12492
- var OPENSCOUT_REPO_ROOT = resolve4(MODULE_DIRECTORY, "..", "..", "..");
12644
+ var MODULE_DIRECTORY = dirname6(fileURLToPath5(import.meta.url));
12645
+ var OPENSCOUT_REPO_ROOT = resolve5(MODULE_DIRECTORY, "..", "..", "..");
12493
12646
  var DEFAULT_LOCAL_AGENT_CAPABILITIES = ["chat", "invoke", "deliver"];
12494
12647
  var DEFAULT_LOCAL_AGENT_HARNESS = "claude";
12495
12648
  function resolveRelayHub() {
@@ -12497,18 +12650,18 @@ function resolveRelayHub() {
12497
12650
  }
12498
12651
  function resolveProjectsRoot(projectPath) {
12499
12652
  if (process.env.OPENSCOUT_PROJECTS_ROOT?.trim()) {
12500
- return resolve4(process.env.OPENSCOUT_PROJECTS_ROOT.trim());
12653
+ return resolve5(process.env.OPENSCOUT_PROJECTS_ROOT.trim());
12501
12654
  }
12502
12655
  try {
12503
12656
  const supportPaths = resolveOpenScoutSupportPaths();
12504
- if (!existsSync11(supportPaths.settingsPath)) {
12505
- return dirname5(projectPath);
12657
+ if (!existsSync12(supportPaths.settingsPath)) {
12658
+ return dirname6(projectPath);
12506
12659
  }
12507
12660
  const raw = JSON.parse(readFileSync7(supportPaths.settingsPath, "utf8"));
12508
12661
  const workspaceRoot = raw.discovery?.workspaceRoots?.find((entry) => typeof entry === "string" && entry.trim().length > 0);
12509
- return workspaceRoot ? resolve4(workspaceRoot) : dirname5(projectPath);
12662
+ return workspaceRoot ? resolve5(workspaceRoot) : dirname6(projectPath);
12510
12663
  } catch {
12511
- return dirname5(projectPath);
12664
+ return dirname6(projectPath);
12512
12665
  }
12513
12666
  }
12514
12667
  function resolveBrokerUrl() {
@@ -12518,20 +12671,20 @@ function nowSeconds2() {
12518
12671
  return Math.floor(Date.now() / 1000);
12519
12672
  }
12520
12673
  function brokerRelayCommand() {
12521
- return `node ${JSON.stringify(join14(OPENSCOUT_REPO_ROOT, "packages", "cli", "bin", "scout.mjs"))}`;
12674
+ return `node ${JSON.stringify(join15(OPENSCOUT_REPO_ROOT, "packages", "cli", "bin", "scout.mjs"))}`;
12522
12675
  }
12523
12676
  function titleCaseLocalAgentName(value) {
12524
12677
  return value.split(/[-_.\s]+/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join(" ");
12525
12678
  }
12526
12679
  function resolveScoutSkillPath() {
12527
12680
  const candidatePaths = [
12528
- join14(OPENSCOUT_REPO_ROOT, ".agents", "skills", "scout", "SKILL.md"),
12529
- join14(process.env.HOME ?? "", ".agents", "skills", "scout", "SKILL.md"),
12530
- join14(OPENSCOUT_REPO_ROOT, ".agents", "skills", "relay-agent-comms", "SKILL.md"),
12531
- join14(process.env.HOME ?? "", ".agents", "skills", "relay-agent-comms", "SKILL.md")
12681
+ join15(OPENSCOUT_REPO_ROOT, ".agents", "skills", "scout", "SKILL.md"),
12682
+ join15(process.env.HOME ?? "", ".agents", "skills", "scout", "SKILL.md"),
12683
+ join15(OPENSCOUT_REPO_ROOT, ".agents", "skills", "relay-agent-comms", "SKILL.md"),
12684
+ join15(process.env.HOME ?? "", ".agents", "skills", "relay-agent-comms", "SKILL.md")
12532
12685
  ];
12533
12686
  for (const path2 of candidatePaths) {
12534
- if (existsSync11(path2)) {
12687
+ if (existsSync12(path2)) {
12535
12688
  return path2;
12536
12689
  }
12537
12690
  }
@@ -12583,12 +12736,18 @@ function buildLocalAgentTmuxProtocolPrompt(context) {
12583
12736
  return [
12584
12737
  "Relay protocol:",
12585
12738
  ` - Read recent context with: ${context.relayCommand} read --as ${context.agentId}`,
12586
- ` - Reply with: ${context.relayCommand} send --as ${context.agentId} "your message"`,
12587
- ` - Ask another agent and stay attached with: ${context.relayCommand} ask --to <agent> --as ${context.agentId} "your request"`,
12739
+ ` - Tell one agent with: ${context.relayCommand} send --as ${context.agentId} "@<agent> your message"`,
12740
+ ` - Ask one agent and stay attached with: ${context.relayCommand} ask --to <agent> --as ${context.agentId} "your request"`,
12588
12741
  "",
12589
12742
  "Rules:",
12590
12743
  " - Do not use file-backed relay state or side channels directly",
12591
12744
  " - Always reply via the broker-backed relay command above so other agents and the app can see your response",
12745
+ " - Default Scout loop: resolve identity, resolve one target, choose DM vs explicit channel, keep follow-up in that same venue",
12746
+ " - Keep one-to-one handoffs in a DM: do not pin a channel when the request is for exactly one agent",
12747
+ " - If you need multiple agents, use separate DMs or an explicit channel; do not guess a venue from multiple mentions",
12748
+ " - Do not use channel.shared for ordinary delegation or follow-up; reserve it for explicit group updates or broadcasts",
12749
+ " - If a short @handle may be ambiguous, resolve the exact target before sending; do not guess and do not fall back to shared",
12750
+ " - Use send for tells and status; use ask when the meaning is 'do this and get back to me'",
12592
12751
  " - When replying to an [ask:<id>] request, include the same [ask:<id>] tag in your reply",
12593
12752
  " - Use the broker-backed relay read command above to inspect recent context before responding",
12594
12753
  ` - Follow the scout skill at ${context.scoutSkill} for agent-to-agent communication`
@@ -12602,7 +12761,14 @@ function buildLocalAgentDirectProtocolPrompt(context) {
12602
12761
  " - Return your final answer in the assistant message for the current turn",
12603
12762
  " - Do not shell out to send the final answer through relay yourself",
12604
12763
  ` - If you need recent relay context, inspect it with: ${context.relayCommand} read --as ${context.agentId}`,
12764
+ ` - If you need to tell one agent something, use: ${context.relayCommand} send --as ${context.agentId} "@<agent> your message"`,
12605
12765
  ` - If you need another agent to do work, use: ${context.relayCommand} ask --to <agent> --as ${context.agentId} "your request"`,
12766
+ " - Default Scout loop: resolve identity, resolve one target, choose DM vs explicit channel, keep follow-up in that same venue",
12767
+ " - Keep one-to-one handoffs in a DM: do not pin a channel when the request is for exactly one agent",
12768
+ " - If you need multiple agents, use separate DMs or an explicit channel; do not guess a venue from multiple mentions",
12769
+ " - Do not use channel.shared for ordinary delegation or follow-up; reserve it for explicit group updates or broadcasts",
12770
+ " - If a short @handle may be ambiguous, resolve the exact target before sending; do not guess and do not fall back to shared",
12771
+ " - Use send for tells and status; use ask when the meaning is 'do this and get back to me'",
12606
12772
  ` - Follow the scout skill at ${context.scoutSkill} for agent-to-agent communication`
12607
12773
  ].join(`
12608
12774
  `);
@@ -12664,7 +12830,7 @@ function buildLegacySimpleRelayPrompt(agentId, projectName, projectPath, relayCo
12664
12830
  "A primary agent may call into you for context, execution, follow-through, and handoff.",
12665
12831
  "",
12666
12832
  `You have full access to the codebase at ${projectPath}.`,
12667
- `There is a structured relay event stream at ${join14(relayHub, "channel.jsonl")} shared by all agents.`,
12833
+ `There is a structured relay event stream at ${join15(relayHub, "channel.jsonl")} shared by all agents.`,
12668
12834
  "",
12669
12835
  "Your job:",
12670
12836
  ` - Respond to @${agentId} mentions from other agents`,
@@ -12757,12 +12923,12 @@ function expandHomePath3(value) {
12757
12923
  return process.env.HOME ?? process.cwd();
12758
12924
  }
12759
12925
  if (value.startsWith("~/")) {
12760
- return join14(process.env.HOME ?? process.cwd(), value.slice(2));
12926
+ return join15(process.env.HOME ?? process.cwd(), value.slice(2));
12761
12927
  }
12762
12928
  return value;
12763
12929
  }
12764
12930
  function normalizeProjectPath(value) {
12765
- return resolve4(expandHomePath3(value.trim() || "."));
12931
+ return resolve5(expandHomePath3(value.trim() || "."));
12766
12932
  }
12767
12933
  function normalizeTmuxSessionName2(value, agentId) {
12768
12934
  const fallback = `relay-${agentId}`;
@@ -12903,7 +13069,7 @@ function recordForHarness(record, harnessOverride) {
12903
13069
  function normalizeLocalAgentRecord(agentId, record) {
12904
13070
  const cwd = normalizeProjectPath(record.cwd || process.cwd());
12905
13071
  const projectRoot = normalizeProjectPath(record.projectRoot || cwd);
12906
- const project = record.project?.trim() || basename3(projectRoot);
13072
+ const project = record.project?.trim() || basename4(projectRoot);
12907
13073
  const definitionId = record.definitionId?.trim() || agentId;
12908
13074
  const defaultHarness = activeLocalHarness(record);
12909
13075
  const harnessProfiles = normalizeLocalHarnessProfiles(agentId, {
@@ -12968,7 +13134,7 @@ function localAgentRecordFromResolvedConfig(config) {
12968
13134
  function localAgentRecordFromRelayAgentOverride(agentId, override) {
12969
13135
  return normalizeLocalAgentRecord(agentId, {
12970
13136
  definitionId: override.definitionId ?? agentId,
12971
- project: override.projectName ?? basename3(override.projectRoot || override.runtime?.cwd || agentId),
13137
+ project: override.projectName ?? basename4(override.projectRoot || override.runtime?.cwd || agentId),
12972
13138
  projectRoot: override.projectRoot ?? override.runtime?.cwd,
12973
13139
  tmuxSession: override.runtime?.sessionId ?? `relay-${agentId}`,
12974
13140
  cwd: override.runtime?.cwd ?? override.projectRoot,
@@ -13064,7 +13230,7 @@ function buildLocalAgentBootstrapPrompt(_harness, _systemPrompt, initialMessage)
13064
13230
  function buildLocalAgentLaunchCommand(agentName, record, projectPath, promptFile, workerScript) {
13065
13231
  const extraArgs = shellQuoteArguments(normalizeLocalAgentLaunchArgs(record.launchArgs));
13066
13232
  if (normalizeLocalAgentHarness(record.harness) === "codex") {
13067
- return `exec bash ${JSON.stringify(workerScript ?? join14(relayAgentRuntimeDirectory(agentName), "codex-worker.sh"))}`;
13233
+ return `exec bash ${JSON.stringify(workerScript ?? join15(relayAgentRuntimeDirectory(agentName), "codex-worker.sh"))}`;
13068
13234
  }
13069
13235
  return [
13070
13236
  "claude",
@@ -13110,7 +13276,7 @@ async function ensureLocalAgentOnline(agentName, record) {
13110
13276
  return normalizedRecord;
13111
13277
  }
13112
13278
  const projectPath = normalizedRecord.cwd;
13113
- const projectName = normalizedRecord.project || basename3(projectPath);
13279
+ const projectName = normalizedRecord.project || basename4(projectPath);
13114
13280
  const systemPromptTemplate = normalizedRecord.systemPrompt || buildLocalAgentSystemPromptTemplate();
13115
13281
  const systemPrompt = renderLocalAgentSystemPromptTemplate(systemPromptTemplate, buildLocalAgentTemplateContext(agentName, projectName, projectPath), { transport: normalizedRecord.transport });
13116
13282
  const agentRuntimeDir = relayAgentRuntimeDirectory(agentName);
@@ -13118,7 +13284,7 @@ async function ensureLocalAgentOnline(agentName, record) {
13118
13284
  await mkdir6(agentRuntimeDir, { recursive: true });
13119
13285
  await mkdir6(logsDir, { recursive: true });
13120
13286
  if (normalizedRecord.transport === "codex_app_server") {
13121
- await writeFile6(join14(agentRuntimeDir, "prompt.txt"), systemPrompt);
13287
+ await writeFile6(join15(agentRuntimeDir, "prompt.txt"), systemPrompt);
13122
13288
  await ensureCodexAppServerAgentOnline(buildCodexAgentSessionOptions(agentName, normalizedRecord, systemPrompt));
13123
13289
  const registry2 = await readLocalAgentRegistry();
13124
13290
  registry2[agentName] = {
@@ -13130,7 +13296,7 @@ async function ensureLocalAgentOnline(agentName, record) {
13130
13296
  return registry2[agentName];
13131
13297
  }
13132
13298
  if (normalizedRecord.transport === "claude_stream_json") {
13133
- await writeFile6(join14(agentRuntimeDir, "prompt.txt"), systemPrompt);
13299
+ await writeFile6(join15(agentRuntimeDir, "prompt.txt"), systemPrompt);
13134
13300
  await ensureClaudeStreamJsonAgentOnline(buildClaudeAgentSessionOptions(agentName, normalizedRecord, systemPrompt));
13135
13301
  const registry2 = await readLocalAgentRegistry();
13136
13302
  registry2[agentName] = {
@@ -13143,17 +13309,17 @@ async function ensureLocalAgentOnline(agentName, record) {
13143
13309
  }
13144
13310
  const initialMessage = buildLocalAgentInitialMessage(projectName, agentName);
13145
13311
  const bootstrapPrompt = buildLocalAgentBootstrapPrompt(normalizeLocalAgentHarness(normalizedRecord.harness), systemPrompt, initialMessage);
13146
- const queueDirectory = join14(agentRuntimeDir, "queue");
13147
- const processingDirectory = join14(queueDirectory, "processing");
13148
- const processedDirectory = join14(queueDirectory, "processed");
13149
- const promptFile = join14(agentRuntimeDir, "prompt.txt");
13150
- const initialFile = join14(agentRuntimeDir, "initial.txt");
13151
- const launchScript = join14(agentRuntimeDir, "launch.sh");
13152
- const workerScript = join14(agentRuntimeDir, "codex-worker.sh");
13153
- const codexSessionIdFile = join14(agentRuntimeDir, "codex-session-id.txt");
13154
- const stateFile = join14(agentRuntimeDir, "state.json");
13155
- const stdoutLogFile = join14(logsDir, "stdout.log");
13156
- const stderrLogFile = join14(logsDir, "stderr.log");
13312
+ const queueDirectory = join15(agentRuntimeDir, "queue");
13313
+ const processingDirectory = join15(queueDirectory, "processing");
13314
+ const processedDirectory = join15(queueDirectory, "processed");
13315
+ const promptFile = join15(agentRuntimeDir, "prompt.txt");
13316
+ const initialFile = join15(agentRuntimeDir, "initial.txt");
13317
+ const launchScript = join15(agentRuntimeDir, "launch.sh");
13318
+ const workerScript = join15(agentRuntimeDir, "codex-worker.sh");
13319
+ const codexSessionIdFile = join15(agentRuntimeDir, "codex-session-id.txt");
13320
+ const stateFile = join15(agentRuntimeDir, "state.json");
13321
+ const stdoutLogFile = join15(logsDir, "stdout.log");
13322
+ const stderrLogFile = join15(logsDir, "stderr.log");
13157
13323
  await writeFile6(promptFile, systemPrompt);
13158
13324
  await writeFile6(initialFile, bootstrapPrompt);
13159
13325
  await writeFile6(stderrLogFile, "");
@@ -13215,10 +13381,10 @@ async function ensureLocalAgentOnline(agentName, record) {
13215
13381
  if (isLocalAgentSessionAlive(normalizedRecord.tmuxSession)) {
13216
13382
  break;
13217
13383
  }
13218
- await new Promise((resolve5) => setTimeout(resolve5, 100));
13384
+ await new Promise((resolve6) => setTimeout(resolve6, 100));
13219
13385
  }
13220
13386
  if (!isLocalAgentSessionAlive(normalizedRecord.tmuxSession)) {
13221
- const stderrTail = existsSync11(stderrLogFile) ? readFileSync7(stderrLogFile, "utf8").trim().split(/\r?\n/).slice(-10).join(`
13387
+ const stderrTail = existsSync12(stderrLogFile) ? readFileSync7(stderrLogFile, "utf8").trim().split(/\r?\n/).slice(-10).join(`
13222
13388
  `).trim() : "";
13223
13389
  throw new Error(stderrTail ? `Relay agent ${agentName} failed to stay online:
13224
13390
  ${stderrTail}` : `Relay agent ${agentName} failed to stay online.`);
@@ -13320,7 +13486,7 @@ async function startLocalAgent(input) {
13320
13486
  }
13321
13487
  if (!matchingOverride) {
13322
13488
  const configDefinitionId = coldProjectConfig?.agent?.id?.trim() ? normalizeAgentSelectorSegment(coldProjectConfig.agent.id.trim()) : "";
13323
- const definitionId = requestedDefinitionId || configDefinitionId || normalizeAgentSelectorSegment(basename3(projectRoot)) || "agent";
13489
+ const definitionId = requestedDefinitionId || configDefinitionId || normalizeAgentSelectorSegment(basename4(projectRoot)) || "agent";
13324
13490
  const configDisplayName = coldProjectConfig?.agent?.displayName?.trim() || "";
13325
13491
  const effectiveDisplayName = input.displayName || configDisplayName || titleCaseLocalAgentName(definitionId);
13326
13492
  const instance = buildRelayAgentInstance(definitionId, projectRoot);
@@ -13336,7 +13502,7 @@ async function startLocalAgent(input) {
13336
13502
  agentId: instance.id,
13337
13503
  definitionId,
13338
13504
  displayName: effectiveDisplayName,
13339
- projectName: basename3(projectRoot),
13505
+ projectName: basename4(projectRoot),
13340
13506
  projectRoot,
13341
13507
  projectConfigPath: coldProjectConfigPath,
13342
13508
  source: "manual",
@@ -13372,7 +13538,7 @@ async function startLocalAgent(input) {
13372
13538
  agentId: instance.id,
13373
13539
  definitionId: requestedDefinitionId,
13374
13540
  displayName: input.displayName || titleCaseLocalAgentName(requestedDefinitionId),
13375
- projectName: matchingOverride.projectName ?? basename3(matchingProjectRoot),
13541
+ projectName: matchingOverride.projectName ?? basename4(matchingProjectRoot),
13376
13542
  projectRoot: matchingProjectRoot,
13377
13543
  projectConfigPath: matchingOverride.projectConfigPath ?? null,
13378
13544
  source: "manual",
@@ -14090,11 +14256,11 @@ async function upScoutAgent(input) {
14090
14256
 
14091
14257
  // ../../apps/desktop/src/server/db-queries.ts
14092
14258
  import { Database } from "bun:sqlite";
14093
- import { homedir as homedir13 } from "os";
14094
- import { join as join15 } from "path";
14259
+ import { homedir as homedir14 } from "os";
14260
+ import { join as join16 } from "path";
14095
14261
  function resolveDbPath() {
14096
- const controlHome = process.env.OPENSCOUT_CONTROL_HOME ?? join15(homedir13(), ".openscout", "control-plane");
14097
- return join15(controlHome, "control-plane.sqlite");
14262
+ const controlHome = process.env.OPENSCOUT_CONTROL_HOME ?? join16(homedir14(), ".openscout", "control-plane");
14263
+ return join16(controlHome, "control-plane.sqlite");
14098
14264
  }
14099
14265
  var _db = null;
14100
14266
  function db() {
@@ -14105,7 +14271,7 @@ function db() {
14105
14271
  }
14106
14272
  return _db;
14107
14273
  }
14108
- var HOME = homedir13();
14274
+ var HOME = homedir14();
14109
14275
  function compact(p) {
14110
14276
  if (!p)
14111
14277
  return null;
@@ -14753,8 +14919,8 @@ async function createScoutSession(input, currentDirectory, deviceId) {
14753
14919
  if (!rawWorkspaceId) {
14754
14920
  throw new Error(`Invalid workspaceId.`);
14755
14921
  }
14756
- const workspaceRoot = resolve5(rawWorkspaceId);
14757
- const projectName = basename4(workspaceRoot) || workspaceRoot;
14922
+ const workspaceRoot = resolve6(rawWorkspaceId);
14923
+ const projectName = basename5(workspaceRoot) || workspaceRoot;
14758
14924
  const workspace = {
14759
14925
  id: workspaceRoot,
14760
14926
  title: projectName,
@@ -14863,17 +15029,17 @@ async function deriveNewAgentName(projectName, branch, harness) {
14863
15029
  }
14864
15030
  async function createGitWorktree(projectRoot, agentName) {
14865
15031
  const { execSync: execSync3 } = await import("child_process");
14866
- const { join: join16 } = await import("path");
14867
- const { mkdirSync: mkdirSync9, existsSync: existsSync12 } = await import("fs");
15032
+ const { join: join17 } = await import("path");
15033
+ const { mkdirSync: mkdirSync9, existsSync: existsSync13 } = await import("fs");
14868
15034
  try {
14869
15035
  execSync3("git rev-parse --git-dir", { cwd: projectRoot, stdio: "pipe" });
14870
15036
  } catch {
14871
15037
  return null;
14872
15038
  }
14873
15039
  const branchName = `scout/${agentName}`;
14874
- const worktreeDir = join16(projectRoot, ".scout-worktrees");
14875
- const worktreePath = join16(worktreeDir, agentName);
14876
- if (existsSync12(worktreePath)) {
15040
+ const worktreeDir = join17(projectRoot, ".scout-worktrees");
15041
+ const worktreePath = join17(worktreeDir, agentName);
15042
+ if (existsSync13(worktreePath)) {
14877
15043
  return { path: worktreePath, branch: branchName };
14878
15044
  }
14879
15045
  mkdirSync9(worktreeDir, { recursive: true });
@@ -15050,9 +15216,9 @@ async function handleRPCInner(bridge, req, deviceId) {
15050
15216
  }
15051
15217
  case "session/resume": {
15052
15218
  const p = req.params;
15053
- const sessionFilename = basename5(p.sessionPath, ".jsonl");
15219
+ const sessionFilename = basename6(p.sessionPath, ".jsonl");
15054
15220
  const parentDir = p.sessionPath.substring(0, p.sessionPath.lastIndexOf("/"));
15055
- const dirName = basename5(parentDir);
15221
+ const dirName = basename6(parentDir);
15056
15222
  let cwd;
15057
15223
  if (dirName.startsWith("-")) {
15058
15224
  const candidate = "/" + dirName.slice(1).replace(/-/g, "/");
@@ -15119,7 +15285,7 @@ async function handleRPCInner(bridge, req, deviceId) {
15119
15285
  return { id: req.id, error: { code: -32000, message: "Workspace target is not a directory" } };
15120
15286
  }
15121
15287
  const adapterType = p.adapter ?? "claude-code";
15122
- const name = p.name ?? basename5(projectPath);
15288
+ const name = p.name ?? basename6(projectPath);
15123
15289
  const session = await bridge.createSession(adapterType, {
15124
15290
  name,
15125
15291
  cwd: projectPath
@@ -15359,13 +15525,13 @@ function resolveMobileCurrentDirectory() {
15359
15525
  }
15360
15526
  }
15361
15527
  function resolveWorkspaceRoot(root) {
15362
- const expandedRoot = root.replace(/^~/, homedir14());
15528
+ const expandedRoot = root.replace(/^~/, homedir15());
15363
15529
  return realpathSync(expandedRoot);
15364
15530
  }
15365
15531
  function resolveWorkspacePath(root, requestedPath) {
15366
15532
  const normalizedRoot = resolveWorkspaceRoot(root);
15367
- const expandedPath = requestedPath?.replace(/^~/, homedir14());
15368
- const candidate = expandedPath ? isAbsolute3(expandedPath) ? expandedPath : join16(normalizedRoot, expandedPath) : normalizedRoot;
15533
+ const expandedPath = requestedPath?.replace(/^~/, homedir15());
15534
+ const candidate = expandedPath ? isAbsolute3(expandedPath) ? expandedPath : join17(normalizedRoot, expandedPath) : normalizedRoot;
15369
15535
  const resolvedCandidate = realpathSync(candidate);
15370
15536
  const rel = relative2(normalizedRoot, resolvedCandidate);
15371
15537
  if (rel === "" || !rel.startsWith("..") && !isAbsolute3(rel)) {
@@ -15395,7 +15561,7 @@ function listDirectories(dirPath) {
15395
15561
  continue;
15396
15562
  if (name === "node_modules" || name === ".build" || name === "target")
15397
15563
  continue;
15398
- const fullPath = join16(dirPath, name);
15564
+ const fullPath = join17(dirPath, name);
15399
15565
  try {
15400
15566
  const stat4 = statSync3(fullPath);
15401
15567
  if (!stat4.isDirectory())
@@ -15418,7 +15584,7 @@ function listDirectories(dirPath) {
15418
15584
  return entries.sort((a, b) => a.name.localeCompare(b.name));
15419
15585
  }
15420
15586
  async function discoverSessionFiles(maxAgeDays, limit) {
15421
- const home = homedir14();
15587
+ const home = homedir15();
15422
15588
  const results = [];
15423
15589
  const searchPaths = [
15424
15590
  { pattern: `${home}/.claude/projects`, agent: "claude-code" },
@@ -18007,8 +18173,8 @@ function emoji() {
18007
18173
  }
18008
18174
  var ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
18009
18175
  var ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
18010
- var mac = (delimiter3) => {
18011
- const escapedDelim = escapeRegex(delimiter3 ?? ":");
18176
+ var mac = (delimiter4) => {
18177
+ const escapedDelim = escapeRegex(delimiter4 ?? ":");
18012
18178
  return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
18013
18179
  };
18014
18180
  var cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
@@ -29958,8 +30124,8 @@ config(en_default());
29958
30124
  // ../../apps/desktop/src/core/pairing/runtime/bridge/router.ts
29959
30125
  import { readFileSync as readFileSync9, readdirSync as readdirSync4, realpathSync as realpathSync2, statSync as statSync4 } from "fs";
29960
30126
  import { execSync as execSync4 } from "child_process";
29961
- import { basename as basename6, isAbsolute as isAbsolute4, join as join17, relative as relative3 } from "path";
29962
- import { homedir as homedir15 } from "os";
30127
+ import { basename as basename7, isAbsolute as isAbsolute4, join as join18, relative as relative3 } from "path";
30128
+ import { homedir as homedir16 } from "os";
29963
30129
  var t = initTRPC.context().create();
29964
30130
  var logged = t.middleware(async ({ path: path2, type, next }) => {
29965
30131
  const start = Date.now();
@@ -29986,13 +30152,13 @@ function resolveMobileCurrentDirectory2() {
29986
30152
  }
29987
30153
  }
29988
30154
  function resolveWorkspaceRoot2(root) {
29989
- const expandedRoot = root.replace(/^~/, homedir15());
30155
+ const expandedRoot = root.replace(/^~/, homedir16());
29990
30156
  return realpathSync2(expandedRoot);
29991
30157
  }
29992
30158
  function resolveWorkspacePath2(root, requestedPath) {
29993
30159
  const normalizedRoot = resolveWorkspaceRoot2(root);
29994
- const expandedPath = requestedPath?.replace(/^~/, homedir15());
29995
- const candidate = expandedPath ? isAbsolute4(expandedPath) ? expandedPath : join17(normalizedRoot, expandedPath) : normalizedRoot;
30160
+ const expandedPath = requestedPath?.replace(/^~/, homedir16());
30161
+ const candidate = expandedPath ? isAbsolute4(expandedPath) ? expandedPath : join18(normalizedRoot, expandedPath) : normalizedRoot;
29996
30162
  const resolvedCandidate = realpathSync2(candidate);
29997
30163
  const rel = relative3(normalizedRoot, resolvedCandidate);
29998
30164
  if (rel === "" || !rel.startsWith("..") && !isAbsolute4(rel)) {
@@ -30022,7 +30188,7 @@ function listDirectories2(dirPath) {
30022
30188
  continue;
30023
30189
  if (name === "node_modules" || name === ".build" || name === "target")
30024
30190
  continue;
30025
- const fullPath = join17(dirPath, name);
30191
+ const fullPath = join18(dirPath, name);
30026
30192
  try {
30027
30193
  const stat4 = statSync4(fullPath);
30028
30194
  if (!stat4.isDirectory())
@@ -30061,7 +30227,7 @@ function detectAgent2(filePath) {
30061
30227
  return "unknown";
30062
30228
  }
30063
30229
  async function discoverSessionFiles2(maxAgeDays, limit) {
30064
- const home = homedir15();
30230
+ const home = homedir16();
30065
30231
  const results = [];
30066
30232
  const searchPaths = [
30067
30233
  { pattern: `${home}/.claude/projects`, agent: "claude-code" },
@@ -30143,23 +30309,23 @@ function bridgeEventIterable(bridge, signal) {
30143
30309
  return {
30144
30310
  [Symbol.asyncIterator]() {
30145
30311
  const buffer = [];
30146
- let resolve6 = null;
30312
+ let resolve7 = null;
30147
30313
  let done = false;
30148
30314
  const unsub = bridge.onEvent((event) => {
30149
30315
  if (done)
30150
30316
  return;
30151
30317
  buffer.push(event);
30152
- if (resolve6) {
30153
- resolve6();
30154
- resolve6 = null;
30318
+ if (resolve7) {
30319
+ resolve7();
30320
+ resolve7 = null;
30155
30321
  }
30156
30322
  });
30157
30323
  const cleanup = () => {
30158
30324
  done = true;
30159
30325
  unsub();
30160
- if (resolve6) {
30161
- resolve6();
30162
- resolve6 = null;
30326
+ if (resolve7) {
30327
+ resolve7();
30328
+ resolve7 = null;
30163
30329
  }
30164
30330
  };
30165
30331
  signal?.addEventListener("abort", cleanup, { once: true });
@@ -30172,7 +30338,7 @@ function bridgeEventIterable(bridge, signal) {
30172
30338
  return { done: false, value: buffer.shift() };
30173
30339
  }
30174
30340
  await new Promise((r) => {
30175
- resolve6 = r;
30341
+ resolve7 = r;
30176
30342
  });
30177
30343
  }
30178
30344
  },
@@ -30239,9 +30405,9 @@ var sessionRouter = t.router({
30239
30405
  adapterType: exports_external.string().optional(),
30240
30406
  name: exports_external.string().optional()
30241
30407
  })).mutation(async ({ input, ctx }) => {
30242
- const sessionFilename = basename6(input.sessionPath, ".jsonl");
30408
+ const sessionFilename = basename7(input.sessionPath, ".jsonl");
30243
30409
  const parentDir = input.sessionPath.substring(0, input.sessionPath.lastIndexOf("/"));
30244
- const dirName = basename6(parentDir);
30410
+ const dirName = basename7(parentDir);
30245
30411
  let cwd;
30246
30412
  if (dirName.startsWith("-")) {
30247
30413
  const candidate = "/" + dirName.slice(1).replace(/-/g, "/");
@@ -30445,7 +30611,7 @@ var workspaceRouter = t.router({
30445
30611
  });
30446
30612
  }
30447
30613
  const adapterType = input.adapter ?? "claude-code";
30448
- const name = input.name ?? basename6(projectPath);
30614
+ const name = input.name ?? basename7(projectPath);
30449
30615
  return ctx.bridge.createSession(adapterType, {
30450
30616
  name,
30451
30617
  cwd: projectPath
@@ -32965,8 +33131,8 @@ var Unpromise = class Unpromise2 {
32965
33131
  status: "fulfilled",
32966
33132
  value
32967
33133
  };
32968
- subscribers === null || subscribers === undefined || subscribers.forEach(({ resolve: resolve6 }) => {
32969
- resolve6(value);
33134
+ subscribers === null || subscribers === undefined || subscribers.forEach(({ resolve: resolve7 }) => {
33135
+ resolve7(value);
32970
33136
  });
32971
33137
  });
32972
33138
  if ("catch" in thenReturn)
@@ -33074,15 +33240,15 @@ function resolveSelfTuple(promise2) {
33074
33240
  return Unpromise.proxy(promise2).then(() => [promise2]);
33075
33241
  }
33076
33242
  function withResolvers() {
33077
- let resolve6;
33243
+ let resolve7;
33078
33244
  let reject;
33079
33245
  const promise2 = new Promise((_resolve, _reject) => {
33080
- resolve6 = _resolve;
33246
+ resolve7 = _resolve;
33081
33247
  reject = _reject;
33082
33248
  });
33083
33249
  return {
33084
33250
  promise: promise2,
33085
- resolve: resolve6,
33251
+ resolve: resolve7,
33086
33252
  reject
33087
33253
  };
33088
33254
  }
@@ -33128,8 +33294,8 @@ function timerResource(ms) {
33128
33294
  return makeResource({ start() {
33129
33295
  if (timer)
33130
33296
  throw new Error("Timer already started");
33131
- const promise2 = new Promise((resolve6) => {
33132
- timer = setTimeout(() => resolve6(disposablePromiseTimerResult), ms);
33297
+ const promise2 = new Promise((resolve7) => {
33298
+ timer = setTimeout(() => resolve7(disposablePromiseTimerResult), ms);
33133
33299
  });
33134
33300
  return promise2;
33135
33301
  } }, () => {
@@ -33332,15 +33498,15 @@ function _takeWithGrace() {
33332
33498
  return _takeWithGrace.apply(this, arguments);
33333
33499
  }
33334
33500
  function createDeferred() {
33335
- let resolve6;
33501
+ let resolve7;
33336
33502
  let reject;
33337
33503
  const promise2 = new Promise((res, rej) => {
33338
- resolve6 = res;
33504
+ resolve7 = res;
33339
33505
  reject = rej;
33340
33506
  });
33341
33507
  return {
33342
33508
  promise: promise2,
33343
- resolve: resolve6,
33509
+ resolve: resolve7,
33344
33510
  reject
33345
33511
  };
33346
33512
  }
@@ -34571,14 +34737,14 @@ function parseTRPCMessage(obj, transformer) {
34571
34737
  }
34572
34738
  // ../../apps/desktop/src/core/pairing/runtime/bridge/server-trpc.ts
34573
34739
  import { realpathSync as realpathSync3 } from "fs";
34574
- import { homedir as homedir16 } from "os";
34740
+ import { homedir as homedir17 } from "os";
34575
34741
  function resolveCurrentDirectory() {
34576
34742
  try {
34577
34743
  const config2 = resolveConfig();
34578
34744
  const configuredRoot = config2.workspace?.root;
34579
34745
  if (!configuredRoot)
34580
34746
  return process.cwd();
34581
- const expanded = configuredRoot.replace(/^~/, homedir16());
34747
+ const expanded = configuredRoot.replace(/^~/, homedir17());
34582
34748
  return realpathSync3(expanded);
34583
34749
  } catch {
34584
34750
  return process.cwd();
@@ -34696,8 +34862,8 @@ function startBridgeServerTRPC(options) {
34696
34862
  }
34697
34863
  const iterable = isObservable(result) ? observableToAsyncIterable(result, abortController.signal) : result;
34698
34864
  const iterator = iterable[Symbol.asyncIterator]();
34699
- const abortPromise = new Promise((resolve6) => {
34700
- abortController.signal.addEventListener("abort", () => resolve6("abort"), {
34865
+ const abortPromise = new Promise((resolve7) => {
34866
+ abortController.signal.addEventListener("abort", () => resolve7("abort"), {
34701
34867
  once: true
34702
34868
  });
34703
34869
  });
@@ -35056,7 +35222,7 @@ async function autoStartConfiguredSessions(bridge, sessions3) {
35056
35222
  try {
35057
35223
  const session = await bridge.createSession(entry.adapter, {
35058
35224
  name: entry.name,
35059
- cwd: entry.cwd?.replace(/^~/, homedir17()),
35225
+ cwd: entry.cwd?.replace(/^~/, homedir18()),
35060
35226
  options: entry.options
35061
35227
  });
35062
35228
  console.log(`[bridge] session started: ${session.name} (${entry.adapter})`);