@openscout/scout 0.2.37 → 0.2.40

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.
@@ -2272,27 +2272,38 @@ function agentIdentityMatches(identity, candidate) {
2272
2272
  return true;
2273
2273
  }
2274
2274
  function resolveAgentIdentity(identity, candidates) {
2275
+ const diagnosis = diagnoseAgentIdentity(identity, candidates);
2276
+ return diagnosis.kind === "resolved" ? diagnosis.match : null;
2277
+ }
2278
+ function diagnoseAgentIdentity(identity, candidates) {
2275
2279
  const aliasKeys = identityAliasKeys(identity);
2276
2280
  const exactAliasMatches = candidates.filter((candidate) => {
2277
2281
  const candidateAliasKeys = explicitCandidateAliases(candidate).map(canonicalizeAliasValue);
2278
2282
  return aliasKeys.some((key) => candidateAliasKeys.includes(key));
2279
2283
  });
2280
2284
  if (exactAliasMatches.length === 1) {
2281
- return exactAliasMatches[0];
2285
+ return { kind: "resolved", match: exactAliasMatches[0] };
2282
2286
  }
2283
2287
  if (exactAliasMatches.length > 1) {
2284
- return null;
2288
+ return { kind: "ambiguous", candidates: exactAliasMatches };
2285
2289
  }
2286
2290
  const matches = candidates.filter((candidate) => agentIdentityMatches(identity, candidate));
2287
2291
  if (matches.length === 1) {
2288
- return matches[0];
2292
+ return { kind: "resolved", match: matches[0] };
2293
+ }
2294
+ if (matches.length === 0) {
2295
+ return { kind: "unknown" };
2289
2296
  }
2290
2297
  if (!identity.nodeQualifier && !identity.workspaceQualifier && !identity.profile && !identity.harness) {
2291
- return matches.find((candidate) => normalizeAgentIdentitySegment(candidate.agentId) === identity.definitionId) ?? matches[0] ?? null;
2298
+ const exactIdMatch = matches.find((candidate) => normalizeAgentIdentitySegment(candidate.agentId) === identity.definitionId);
2299
+ if (exactIdMatch) {
2300
+ return { kind: "resolved", match: exactIdMatch };
2301
+ }
2302
+ return { kind: "ambiguous", candidates: matches };
2292
2303
  }
2293
- return null;
2304
+ return { kind: "ambiguous", candidates: matches };
2294
2305
  }
2295
- var DIMENSION_ALIASES, normalizeAgentSelectorSegment, parseAgentSelector, formatAgentSelector, resolveAgentSelector;
2306
+ var DIMENSION_ALIASES, normalizeAgentSelectorSegment, SCOUT_DISPATCHER_AGENT_ID = "scout", BUILT_IN_AGENT_DEFINITION_IDS, RESERVED_AGENT_DEFINITION_IDS, parseAgentSelector, formatAgentSelector, resolveAgentSelector;
2296
2307
  var init_agent_identity = __esm(() => {
2297
2308
  DIMENSION_ALIASES = {
2298
2309
  workspace: "workspace",
@@ -2306,6 +2317,15 @@ var init_agent_identity = __esm(() => {
2306
2317
  host: "node"
2307
2318
  };
2308
2319
  normalizeAgentSelectorSegment = normalizeAgentIdentitySegment;
2320
+ BUILT_IN_AGENT_DEFINITION_IDS = new Set([
2321
+ SCOUT_DISPATCHER_AGENT_ID,
2322
+ "builder",
2323
+ "reviewer",
2324
+ "research"
2325
+ ]);
2326
+ RESERVED_AGENT_DEFINITION_IDS = new Set([
2327
+ SCOUT_DISPATCHER_AGENT_ID
2328
+ ]);
2309
2329
  parseAgentSelector = parseAgentIdentity;
2310
2330
  formatAgentSelector = formatAgentIdentity;
2311
2331
  resolveAgentSelector = resolveAgentIdentity;
@@ -3602,7 +3622,7 @@ async function readRelayAgentOverrides() {
3602
3622
  return Object.fromEntries(Object.entries(agents).map(([agentId, record]) => {
3603
3623
  const definitionId = normalizeAgentId(record.definitionId || record.agentId || agentId);
3604
3624
  const projectRoot = normalizePath(record.projectRoot);
3605
- const concreteAgentId = BUILT_IN_AGENT_IDS.has(definitionId) ? definitionId : buildRelayAgentInstance(definitionId, projectRoot).id;
3625
+ const concreteAgentId = buildRelayAgentInstance(definitionId, projectRoot).id;
3606
3626
  const defaultHarness = normalizeManagedHarness(typeof record.defaultHarness === "string" ? record.defaultHarness : record.runtime?.harness, "claude");
3607
3627
  const harnessProfiles = buildHarnessProfiles({
3608
3628
  projectRoot,
@@ -3637,7 +3657,7 @@ async function writeRelayAgentOverrides(overrides) {
3637
3657
  const normalizedAgents = Object.fromEntries(Object.entries(overrides).map(([agentId, record]) => {
3638
3658
  const definitionId = normalizeAgentId(record.definitionId || record.agentId || agentId);
3639
3659
  const projectRoot = normalizePath(record.projectRoot);
3640
- const concreteAgentId = BUILT_IN_AGENT_IDS.has(definitionId) ? definitionId : buildRelayAgentInstance(definitionId, projectRoot).id;
3660
+ const concreteAgentId = buildRelayAgentInstance(definitionId, projectRoot).id;
3641
3661
  const defaultHarness = normalizeManagedHarness(typeof record.defaultHarness === "string" ? record.defaultHarness : record.runtime?.harness, "claude");
3642
3662
  const harnessProfiles = buildHarnessProfiles({
3643
3663
  projectRoot,
@@ -4215,14 +4235,14 @@ async function loadResolvedRelayAgents(options = {}) {
4215
4235
  const manifest = await readProjectConfig(projectRoot);
4216
4236
  const override = overrideByRoot.get(projectRoot);
4217
4237
  const resolvedAgent = manifest ? await resolveManifestBackedAgent(projectRoot, manifest, settings, override) : await resolveInferredAgent(projectRoot, settings, override);
4218
- if (!resolvedAgent.agentId || BUILT_IN_AGENT_IDS.has(resolvedAgent.agentId)) {
4238
+ if (!resolvedAgent.agentId || BUILT_IN_AGENT_DEFINITION_IDS.has(resolvedAgent.definitionId)) {
4219
4239
  continue;
4220
4240
  }
4221
4241
  resolvedAgents.push(resolvedAgent);
4222
4242
  }
4223
4243
  const dedupedResolvedAgents = await dedupeResolvedAgentsByCanonicalProjectRoot(resolvedAgents);
4224
4244
  const configuredAgents = dedupedResolvedAgents.filter((agent) => agent.registrationKind === "configured");
4225
- const builtInOverrides = Object.fromEntries(Object.entries(overrides).filter(([agentId]) => BUILT_IN_AGENT_IDS.has(agentId)));
4245
+ const builtInOverrides = Object.fromEntries(Object.entries(overrides).filter(([, record]) => record.definitionId ? BUILT_IN_AGENT_DEFINITION_IDS.has(record.definitionId) : false));
4226
4246
  const nextOverrides = {
4227
4247
  ...builtInOverrides,
4228
4248
  ...Object.fromEntries(configuredAgents.map((agent) => [
@@ -4311,7 +4331,7 @@ async function ensureRelayAgentConfigured(value, options = {}) {
4311
4331
  registrationKind: "configured"
4312
4332
  };
4313
4333
  }
4314
- var SCOUT_AGENT_ID = "scout", SCOUT_PRIMARY_CONVERSATION_ID = "dm.scout.primary", MANAGED_AGENT_HARNESSES, DEFAULT_OPERATOR_NAME, DEFAULT_CAPABILITIES, DEFAULT_TRANSPORT = "claude_stream_json", DEFAULT_TELEGRAM_MODE = "polling", LEGACY_DEFAULT_TELEGRAM_CONVERSATION_ID = "channel.shared", DEFAULT_TELEGRAM_CONVERSATION_ID, SETTINGS_VERSION = 1, PROJECT_CONFIG_VERSION = 1, BUILT_IN_AGENT_IDS, PROJECT_SCAN_SKIP_DIRECTORIES, PROJECT_STRONG_MARKERS, PROJECT_WEAK_MARKERS, PROJECT_HARNESS_MARKERS, PROJECT_STRONG_MARKERS_FLAT_NESTED, PROJECT_WEAK_MARKERS_FLAT_NESTED, GIT_BRANCH_CACHE_TTL_MS = 15000, gitBranchCache, SCOUT_SKILL_FILE_NAME = "SKILL.md", SETUP_MODULE_DIRECTORY, SCOUT_SKILL_REPO_ROOT, SCOUT_SKILL_INSTALL_PATHS, PROJECT_SCAN_MAX_DEPTH = 64;
4334
+ var SCOUT_AGENT_ID = "scout", SCOUT_PRIMARY_CONVERSATION_ID = "dm.scout.primary", MANAGED_AGENT_HARNESSES, DEFAULT_OPERATOR_NAME, DEFAULT_CAPABILITIES, DEFAULT_TRANSPORT = "claude_stream_json", DEFAULT_TELEGRAM_MODE = "polling", LEGACY_DEFAULT_TELEGRAM_CONVERSATION_ID = "channel.shared", DEFAULT_TELEGRAM_CONVERSATION_ID, SETTINGS_VERSION = 1, PROJECT_CONFIG_VERSION = 1, PROJECT_SCAN_SKIP_DIRECTORIES, PROJECT_STRONG_MARKERS, PROJECT_WEAK_MARKERS, PROJECT_HARNESS_MARKERS, PROJECT_STRONG_MARKERS_FLAT_NESTED, PROJECT_WEAK_MARKERS_FLAT_NESTED, GIT_BRANCH_CACHE_TTL_MS = 15000, gitBranchCache, SCOUT_SKILL_FILE_NAME = "SKILL.md", SETUP_MODULE_DIRECTORY, SCOUT_SKILL_REPO_ROOT, SCOUT_SKILL_INSTALL_PATHS, PROJECT_SCAN_MAX_DEPTH = 64;
4315
4335
  var init_setup = __esm(() => {
4316
4336
  init_dist();
4317
4337
  init_src();
@@ -4322,7 +4342,6 @@ var init_setup = __esm(() => {
4322
4342
  DEFAULT_OPERATOR_NAME = guessedOperatorName();
4323
4343
  DEFAULT_CAPABILITIES = ["chat", "invoke", "deliver"];
4324
4344
  DEFAULT_TELEGRAM_CONVERSATION_ID = SCOUT_PRIMARY_CONVERSATION_ID;
4325
- BUILT_IN_AGENT_IDS = new Set(["scout", "builder", "reviewer", "research"]);
4326
4345
  PROJECT_SCAN_SKIP_DIRECTORIES = new Set([
4327
4346
  ".git",
4328
4347
  ".hg",
@@ -4751,6 +4770,24 @@ import { existsSync as existsSync9, mkdirSync as mkdirSync8, readFileSync as rea
4751
4770
  import { homedir as homedir11 } from "os";
4752
4771
  import { basename as basename2, dirname as dirname4, join as join12, resolve as resolve3 } from "path";
4753
4772
  import { fileURLToPath as fileURLToPath3 } from "url";
4773
+ function isTmpPath(p) {
4774
+ return /^\/(?:private\/)?tmp\//.test(p);
4775
+ }
4776
+ function resolveAdvertiseScope() {
4777
+ const raw = (process.env.OPENSCOUT_ADVERTISE_SCOPE ?? "").trim().toLowerCase();
4778
+ if (raw === "mesh")
4779
+ return "mesh";
4780
+ if (raw === "local")
4781
+ return "local";
4782
+ return DEFAULT_ADVERTISE_SCOPE;
4783
+ }
4784
+ function resolveBrokerHost(scope = resolveAdvertiseScope()) {
4785
+ const explicit = process.env.OPENSCOUT_BROKER_HOST;
4786
+ if (typeof explicit === "string" && explicit.trim().length > 0) {
4787
+ return explicit;
4788
+ }
4789
+ return scope === "mesh" ? DEFAULT_BROKER_HOST_MESH : DEFAULT_BROKER_HOST;
4790
+ }
4754
4791
  function buildDefaultBrokerUrl(host = DEFAULT_BROKER_HOST, port = DEFAULT_BROKER_PORT) {
4755
4792
  return `http://${host}:${port}`;
4756
4793
  }
@@ -4771,15 +4808,28 @@ function isInstalledRuntimePackageDir(candidate) {
4771
4808
  return existsSync9(join12(candidate, "package.json")) && existsSync9(join12(candidate, "bin", "openscout-runtime.mjs"));
4772
4809
  }
4773
4810
  function findGlobalRuntimeDir() {
4774
- const bunCandidate = join12(homedir11(), ".bun", "node_modules", "@openscout", "runtime");
4775
- if (isInstalledRuntimePackageDir(bunCandidate))
4776
- return bunCandidate;
4777
- const bunGlobalCandidate = join12(homedir11(), ".bun", "install", "global", "node_modules", "@openscout", "runtime");
4778
- if (isInstalledRuntimePackageDir(bunGlobalCandidate))
4779
- return bunGlobalCandidate;
4780
- const bunScoutNested = join12(homedir11(), ".bun", "install", "global", "node_modules", "@openscout", "scout", "node_modules", "@openscout", "runtime");
4781
- if (isInstalledRuntimePackageDir(bunScoutNested))
4782
- return bunScoutNested;
4811
+ const candidates = [
4812
+ join12(homedir11(), ".bun", "node_modules", "@openscout", "runtime"),
4813
+ join12(homedir11(), ".bun", "install", "global", "node_modules", "@openscout", "runtime"),
4814
+ join12(homedir11(), ".bun", "install", "global", "node_modules", "@openscout", "scout", "node_modules", "@openscout", "runtime")
4815
+ ];
4816
+ for (const c of candidates) {
4817
+ if (isInstalledRuntimePackageDir(c))
4818
+ return c;
4819
+ }
4820
+ try {
4821
+ const result = spawnSync("which", ["scout"], { encoding: "utf8", timeout: 3000 });
4822
+ const scoutBin = result.stdout?.trim();
4823
+ if (scoutBin) {
4824
+ const scoutPkg = resolve3(scoutBin, "..", "..");
4825
+ const nested = join12(scoutPkg, "node_modules", "@openscout", "runtime");
4826
+ if (isInstalledRuntimePackageDir(nested))
4827
+ return nested;
4828
+ const sibling = resolve3(scoutPkg, "..", "runtime");
4829
+ if (isInstalledRuntimePackageDir(sibling))
4830
+ return sibling;
4831
+ }
4832
+ } catch {}
4783
4833
  return null;
4784
4834
  }
4785
4835
  function findWorkspaceRuntimeDir(startDir) {
@@ -4853,11 +4903,12 @@ function resolveBrokerServiceConfig() {
4853
4903
  const label = resolveBrokerServiceLabel(mode);
4854
4904
  const uid = typeof process.getuid === "function" ? process.getuid() : Number.parseInt(process.env.UID ?? "0", 10);
4855
4905
  const supportPaths = resolveOpenScoutSupportPaths();
4856
- const supportDirectory = supportPaths.supportDirectory;
4857
- const logsDirectory = supportPaths.brokerLogsDirectory;
4858
- const rawControlHome = supportPaths.controlHome;
4859
- const controlHome = /^\/(?:private\/)?tmp\//.test(rawControlHome) ? join12(homedir11(), ".openscout", "control-plane") : rawControlHome;
4860
- const brokerHost = process.env.OPENSCOUT_BROKER_HOST ?? DEFAULT_BROKER_HOST;
4906
+ const defaultSupportDir = join12(homedir11(), "Library", "Application Support", "OpenScout");
4907
+ const supportDirectory = isTmpPath(supportPaths.supportDirectory) ? defaultSupportDir : supportPaths.supportDirectory;
4908
+ const logsDirectory = join12(supportDirectory, "logs", "broker");
4909
+ const controlHome = isTmpPath(supportPaths.controlHome) ? join12(homedir11(), ".openscout", "control-plane") : supportPaths.controlHome;
4910
+ const advertiseScope = resolveAdvertiseScope();
4911
+ const brokerHost = resolveBrokerHost(advertiseScope);
4861
4912
  const brokerPort = Number.parseInt(process.env.OPENSCOUT_BROKER_PORT ?? String(DEFAULT_BROKER_PORT), 10);
4862
4913
  const brokerUrl = process.env.OPENSCOUT_BROKER_URL ?? buildDefaultBrokerUrl(brokerHost, brokerPort);
4863
4914
  const launchAgentPath = join12(homedir11(), "Library", "LaunchAgents", `${label}.plist`);
@@ -4877,7 +4928,8 @@ function resolveBrokerServiceConfig() {
4877
4928
  bunExecutable: resolveBunExecutable(),
4878
4929
  brokerHost,
4879
4930
  brokerPort,
4880
- brokerUrl
4931
+ brokerUrl,
4932
+ advertiseScope
4881
4933
  };
4882
4934
  }
4883
4935
  function renderLaunchAgentPlist(config) {
@@ -4889,6 +4941,7 @@ function renderLaunchAgentPlist(config) {
4889
4941
  OPENSCOUT_CONTROL_HOME: config.controlHome,
4890
4942
  OPENSCOUT_BROKER_SERVICE_MODE: config.mode,
4891
4943
  OPENSCOUT_BROKER_SERVICE_LABEL: config.label,
4944
+ OPENSCOUT_ADVERTISE_SCOPE: config.advertiseScope,
4892
4945
  HOME: homedir11(),
4893
4946
  PATH: launchPath,
4894
4947
  ...collectOptionalEnvVars([
@@ -4959,7 +5012,7 @@ function resolveLaunchAgentPATH() {
4959
5012
  "/usr/sbin",
4960
5013
  "/sbin"
4961
5014
  ];
4962
- return Array.from(new Set(entries)).join(":");
5015
+ return Array.from(new Set(entries)).filter((e) => !isTmpPath(e)).join(":");
4963
5016
  }
4964
5017
  function xmlEscape(value) {
4965
5018
  return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&apos;");
@@ -5218,7 +5271,7 @@ function formatBrokerServiceStatus(status) {
5218
5271
  return lines.join(`
5219
5272
  `);
5220
5273
  }
5221
- var DEFAULT_BROKER_HOST = "127.0.0.1", DEFAULT_BROKER_PORT = 65535, BROKER_SERVICE_POLL_INTERVAL_MS = 100, DEFAULT_BROKER_START_TIMEOUT_MS = 15000, DEFAULT_BROKER_URL;
5274
+ var DEFAULT_BROKER_HOST = "127.0.0.1", DEFAULT_BROKER_HOST_MESH = "0.0.0.0", DEFAULT_BROKER_PORT = 65535, DEFAULT_ADVERTISE_SCOPE = "local", BROKER_SERVICE_POLL_INTERVAL_MS = 100, DEFAULT_BROKER_START_TIMEOUT_MS = 15000, DEFAULT_BROKER_URL;
5222
5275
  var init_broker_service = __esm(async () => {
5223
5276
  init_support_paths();
5224
5277
  DEFAULT_BROKER_URL = buildDefaultBrokerUrl();
@@ -6032,7 +6085,7 @@ async function startLocalAgent(input) {
6032
6085
  const findMatchForRoot = (root) => {
6033
6086
  let fallback = null;
6034
6087
  for (const [id, override] of Object.entries(overrides)) {
6035
- if (BUILT_IN_LOCAL_AGENT_IDS.has(id))
6088
+ if (BUILT_IN_AGENT_DEFINITION_IDS.has(id))
6036
6089
  continue;
6037
6090
  if (!override.projectRoot)
6038
6091
  continue;
@@ -6311,7 +6364,7 @@ async function loadRegisteredLocalAgentBindings(nodeId, options = {}) {
6311
6364
  return results;
6312
6365
  }
6313
6366
  async function inferLocalAgentBinding(agentId, nodeId) {
6314
- if (!agentId || BUILT_IN_LOCAL_AGENT_IDS.has(agentId)) {
6367
+ if (!agentId || BUILT_IN_AGENT_DEFINITION_IDS.has(agentId)) {
6315
6368
  return null;
6316
6369
  }
6317
6370
  const overrides = await readRelayAgentOverrides();
@@ -6334,7 +6387,7 @@ async function ensureLocalAgentBindingOnline(agentId, nodeId, options = {}) {
6334
6387
  if (registeredBinding) {
6335
6388
  return registeredBinding;
6336
6389
  }
6337
- if (BUILT_IN_LOCAL_AGENT_IDS.has(agentId)) {
6390
+ if (BUILT_IN_AGENT_DEFINITION_IDS.has(agentId)) {
6338
6391
  return null;
6339
6392
  }
6340
6393
  if (options.includeDiscovered) {
@@ -6357,7 +6410,7 @@ async function ensureLocalAgentBindingOnline(agentId, nodeId, options = {}) {
6357
6410
  const onlineRecord = await ensureLocalAgentOnline(agentId, recordForHarness(localAgentRecordFromRelayAgentOverride(agentId, override), options.harness));
6358
6411
  return buildLocalAgentBinding(agentId, onlineRecord, isLocalAgentRecordOnline(agentId, onlineRecord), nodeId, "relay-agent-registry");
6359
6412
  }
6360
- var BUILT_IN_LOCAL_AGENT_IDS, MODULE_DIRECTORY, OPENSCOUT_REPO_ROOT, DEFAULT_LOCAL_AGENT_CAPABILITIES, DEFAULT_LOCAL_AGENT_HARNESS = "claude";
6413
+ var MODULE_DIRECTORY, OPENSCOUT_REPO_ROOT, DEFAULT_LOCAL_AGENT_CAPABILITIES, DEFAULT_LOCAL_AGENT_HARNESS = "claude";
6361
6414
  var init_local_agents = __esm(async () => {
6362
6415
  init_src();
6363
6416
  init_claude_stream_json();
@@ -6366,7 +6419,6 @@ var init_local_agents = __esm(async () => {
6366
6419
  init_support_paths();
6367
6420
  init_local_agent_template();
6368
6421
  await init_broker_service();
6369
- BUILT_IN_LOCAL_AGENT_IDS = new Set(["scout", "builder", "reviewer", "research"]);
6370
6422
  MODULE_DIRECTORY = dirname5(fileURLToPath4(import.meta.url));
6371
6423
  OPENSCOUT_REPO_ROOT = resolve4(MODULE_DIRECTORY, "..", "..", "..");
6372
6424
  DEFAULT_LOCAL_AGENT_CAPABILITIES = ["chat", "invoke", "deliver"];
@@ -12093,7 +12145,6 @@ var BROKER_SHARED_CHANNEL_ID = "channel.shared";
12093
12145
  var OPERATOR_ID = "operator";
12094
12146
  var DEFAULT_BROKER_HOST2 = "127.0.0.1";
12095
12147
  var DEFAULT_BROKER_PORT2 = 65535;
12096
- var BUILT_IN_SCOUT_AGENT_IDS = new Set([SCOUT_AGENT_ID, "builder", "reviewer", "research"]);
12097
12148
  function buildScoutBrokerUrlFromEnv() {
12098
12149
  const host = process.env.OPENSCOUT_BROKER_HOST ?? DEFAULT_BROKER_HOST2;
12099
12150
  const port = Number.parseInt(process.env.OPENSCOUT_BROKER_PORT ?? String(DEFAULT_BROKER_PORT2), 10);
@@ -1201,27 +1201,38 @@ function agentIdentityMatches(identity, candidate) {
1201
1201
  return true;
1202
1202
  }
1203
1203
  function resolveAgentIdentity(identity, candidates) {
1204
+ const diagnosis = diagnoseAgentIdentity(identity, candidates);
1205
+ return diagnosis.kind === "resolved" ? diagnosis.match : null;
1206
+ }
1207
+ function diagnoseAgentIdentity(identity, candidates) {
1204
1208
  const aliasKeys = identityAliasKeys(identity);
1205
1209
  const exactAliasMatches = candidates.filter((candidate) => {
1206
1210
  const candidateAliasKeys = explicitCandidateAliases(candidate).map(canonicalizeAliasValue);
1207
1211
  return aliasKeys.some((key) => candidateAliasKeys.includes(key));
1208
1212
  });
1209
1213
  if (exactAliasMatches.length === 1) {
1210
- return exactAliasMatches[0];
1214
+ return { kind: "resolved", match: exactAliasMatches[0] };
1211
1215
  }
1212
1216
  if (exactAliasMatches.length > 1) {
1213
- return null;
1217
+ return { kind: "ambiguous", candidates: exactAliasMatches };
1214
1218
  }
1215
1219
  const matches = candidates.filter((candidate) => agentIdentityMatches(identity, candidate));
1216
1220
  if (matches.length === 1) {
1217
- return matches[0];
1221
+ return { kind: "resolved", match: matches[0] };
1222
+ }
1223
+ if (matches.length === 0) {
1224
+ return { kind: "unknown" };
1218
1225
  }
1219
1226
  if (!identity.nodeQualifier && !identity.workspaceQualifier && !identity.profile && !identity.harness) {
1220
- return matches.find((candidate) => normalizeAgentIdentitySegment(candidate.agentId) === identity.definitionId) ?? matches[0] ?? null;
1227
+ const exactIdMatch = matches.find((candidate) => normalizeAgentIdentitySegment(candidate.agentId) === identity.definitionId);
1228
+ if (exactIdMatch) {
1229
+ return { kind: "resolved", match: exactIdMatch };
1230
+ }
1231
+ return { kind: "ambiguous", candidates: matches };
1221
1232
  }
1222
- return null;
1233
+ return { kind: "ambiguous", candidates: matches };
1223
1234
  }
1224
- var DIMENSION_ALIASES, normalizeAgentSelectorSegment, parseAgentSelector, formatAgentSelector, extractAgentSelectors, resolveAgentSelector;
1235
+ var DIMENSION_ALIASES, normalizeAgentSelectorSegment, SCOUT_DISPATCHER_AGENT_ID = "scout", BUILT_IN_AGENT_DEFINITION_IDS, RESERVED_AGENT_DEFINITION_IDS, parseAgentSelector, formatAgentSelector, extractAgentSelectors, resolveAgentSelector;
1225
1236
  var init_agent_identity = __esm(() => {
1226
1237
  DIMENSION_ALIASES = {
1227
1238
  workspace: "workspace",
@@ -1235,6 +1246,15 @@ var init_agent_identity = __esm(() => {
1235
1246
  host: "node"
1236
1247
  };
1237
1248
  normalizeAgentSelectorSegment = normalizeAgentIdentitySegment;
1249
+ BUILT_IN_AGENT_DEFINITION_IDS = new Set([
1250
+ SCOUT_DISPATCHER_AGENT_ID,
1251
+ "builder",
1252
+ "reviewer",
1253
+ "research"
1254
+ ]);
1255
+ RESERVED_AGENT_DEFINITION_IDS = new Set([
1256
+ SCOUT_DISPATCHER_AGENT_ID
1257
+ ]);
1238
1258
  parseAgentSelector = parseAgentIdentity;
1239
1259
  formatAgentSelector = formatAgentIdentity;
1240
1260
  extractAgentSelectors = extractAgentIdentities;
@@ -2679,7 +2699,7 @@ async function readRelayAgentOverrides() {
2679
2699
  return Object.fromEntries(Object.entries(agents).map(([agentId, record]) => {
2680
2700
  const definitionId = normalizeAgentId(record.definitionId || record.agentId || agentId);
2681
2701
  const projectRoot = normalizePath(record.projectRoot);
2682
- const concreteAgentId = BUILT_IN_AGENT_IDS.has(definitionId) ? definitionId : buildRelayAgentInstance(definitionId, projectRoot).id;
2702
+ const concreteAgentId = buildRelayAgentInstance(definitionId, projectRoot).id;
2683
2703
  const defaultHarness = normalizeManagedHarness(typeof record.defaultHarness === "string" ? record.defaultHarness : record.runtime?.harness, "claude");
2684
2704
  const harnessProfiles = buildHarnessProfiles({
2685
2705
  projectRoot,
@@ -2714,7 +2734,7 @@ async function writeRelayAgentOverrides(overrides) {
2714
2734
  const normalizedAgents = Object.fromEntries(Object.entries(overrides).map(([agentId, record]) => {
2715
2735
  const definitionId = normalizeAgentId(record.definitionId || record.agentId || agentId);
2716
2736
  const projectRoot = normalizePath(record.projectRoot);
2717
- const concreteAgentId = BUILT_IN_AGENT_IDS.has(definitionId) ? definitionId : buildRelayAgentInstance(definitionId, projectRoot).id;
2737
+ const concreteAgentId = buildRelayAgentInstance(definitionId, projectRoot).id;
2718
2738
  const defaultHarness = normalizeManagedHarness(typeof record.defaultHarness === "string" ? record.defaultHarness : record.runtime?.harness, "claude");
2719
2739
  const harnessProfiles = buildHarnessProfiles({
2720
2740
  projectRoot,
@@ -3292,14 +3312,14 @@ async function loadResolvedRelayAgents(options = {}) {
3292
3312
  const manifest = await readProjectConfig(projectRoot);
3293
3313
  const override = overrideByRoot.get(projectRoot);
3294
3314
  const resolvedAgent = manifest ? await resolveManifestBackedAgent(projectRoot, manifest, settings, override) : await resolveInferredAgent(projectRoot, settings, override);
3295
- if (!resolvedAgent.agentId || BUILT_IN_AGENT_IDS.has(resolvedAgent.agentId)) {
3315
+ if (!resolvedAgent.agentId || BUILT_IN_AGENT_DEFINITION_IDS.has(resolvedAgent.definitionId)) {
3296
3316
  continue;
3297
3317
  }
3298
3318
  resolvedAgents.push(resolvedAgent);
3299
3319
  }
3300
3320
  const dedupedResolvedAgents = await dedupeResolvedAgentsByCanonicalProjectRoot(resolvedAgents);
3301
3321
  const configuredAgents = dedupedResolvedAgents.filter((agent) => agent.registrationKind === "configured");
3302
- const builtInOverrides = Object.fromEntries(Object.entries(overrides).filter(([agentId]) => BUILT_IN_AGENT_IDS.has(agentId)));
3322
+ const builtInOverrides = Object.fromEntries(Object.entries(overrides).filter(([, record]) => record.definitionId ? BUILT_IN_AGENT_DEFINITION_IDS.has(record.definitionId) : false));
3303
3323
  const nextOverrides = {
3304
3324
  ...builtInOverrides,
3305
3325
  ...Object.fromEntries(configuredAgents.map((agent) => [
@@ -3388,7 +3408,7 @@ async function ensureRelayAgentConfigured(value, options = {}) {
3388
3408
  registrationKind: "configured"
3389
3409
  };
3390
3410
  }
3391
- var SCOUT_AGENT_ID = "scout", SCOUT_PRIMARY_CONVERSATION_ID = "dm.scout.primary", MANAGED_AGENT_HARNESSES, DEFAULT_OPERATOR_NAME, DEFAULT_CAPABILITIES, DEFAULT_TRANSPORT = "claude_stream_json", DEFAULT_TELEGRAM_MODE = "polling", LEGACY_DEFAULT_TELEGRAM_CONVERSATION_ID = "channel.shared", DEFAULT_TELEGRAM_CONVERSATION_ID, SETTINGS_VERSION = 1, PROJECT_CONFIG_VERSION = 1, BUILT_IN_AGENT_IDS, PROJECT_SCAN_SKIP_DIRECTORIES, PROJECT_STRONG_MARKERS, PROJECT_WEAK_MARKERS, PROJECT_HARNESS_MARKERS, PROJECT_STRONG_MARKERS_FLAT_NESTED, PROJECT_WEAK_MARKERS_FLAT_NESTED, GIT_BRANCH_CACHE_TTL_MS = 15000, gitBranchCache, SCOUT_SKILL_FILE_NAME = "SKILL.md", SETUP_MODULE_DIRECTORY, SCOUT_SKILL_REPO_ROOT, SCOUT_SKILL_INSTALL_PATHS, PROJECT_SCAN_MAX_DEPTH = 64;
3411
+ var SCOUT_AGENT_ID = "scout", SCOUT_PRIMARY_CONVERSATION_ID = "dm.scout.primary", MANAGED_AGENT_HARNESSES, DEFAULT_OPERATOR_NAME, DEFAULT_CAPABILITIES, DEFAULT_TRANSPORT = "claude_stream_json", DEFAULT_TELEGRAM_MODE = "polling", LEGACY_DEFAULT_TELEGRAM_CONVERSATION_ID = "channel.shared", DEFAULT_TELEGRAM_CONVERSATION_ID, SETTINGS_VERSION = 1, PROJECT_CONFIG_VERSION = 1, PROJECT_SCAN_SKIP_DIRECTORIES, PROJECT_STRONG_MARKERS, PROJECT_WEAK_MARKERS, PROJECT_HARNESS_MARKERS, PROJECT_STRONG_MARKERS_FLAT_NESTED, PROJECT_WEAK_MARKERS_FLAT_NESTED, GIT_BRANCH_CACHE_TTL_MS = 15000, gitBranchCache, SCOUT_SKILL_FILE_NAME = "SKILL.md", SETUP_MODULE_DIRECTORY, SCOUT_SKILL_REPO_ROOT, SCOUT_SKILL_INSTALL_PATHS, PROJECT_SCAN_MAX_DEPTH = 64;
3392
3412
  var init_setup = __esm(() => {
3393
3413
  init_dist();
3394
3414
  init_src();
@@ -3399,7 +3419,6 @@ var init_setup = __esm(() => {
3399
3419
  DEFAULT_OPERATOR_NAME = guessedOperatorName();
3400
3420
  DEFAULT_CAPABILITIES = ["chat", "invoke", "deliver"];
3401
3421
  DEFAULT_TELEGRAM_CONVERSATION_ID = SCOUT_PRIMARY_CONVERSATION_ID;
3402
- BUILT_IN_AGENT_IDS = new Set(["scout", "builder", "reviewer", "research"]);
3403
3422
  PROJECT_SCAN_SKIP_DIRECTORIES = new Set([
3404
3423
  ".git",
3405
3424
  ".hg",
@@ -4163,6 +4182,24 @@ import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as rea
4163
4182
  import { homedir as homedir5 } from "os";
4164
4183
  import { basename as basename2, dirname as dirname5, join as join8, resolve as resolve4 } from "path";
4165
4184
  import { fileURLToPath as fileURLToPath4 } from "url";
4185
+ function isTmpPath(p) {
4186
+ return /^\/(?:private\/)?tmp\//.test(p);
4187
+ }
4188
+ function resolveAdvertiseScope() {
4189
+ const raw2 = (process.env.OPENSCOUT_ADVERTISE_SCOPE ?? "").trim().toLowerCase();
4190
+ if (raw2 === "mesh")
4191
+ return "mesh";
4192
+ if (raw2 === "local")
4193
+ return "local";
4194
+ return DEFAULT_ADVERTISE_SCOPE;
4195
+ }
4196
+ function resolveBrokerHost(scope = resolveAdvertiseScope()) {
4197
+ const explicit = process.env.OPENSCOUT_BROKER_HOST;
4198
+ if (typeof explicit === "string" && explicit.trim().length > 0) {
4199
+ return explicit;
4200
+ }
4201
+ return scope === "mesh" ? DEFAULT_BROKER_HOST_MESH : DEFAULT_BROKER_HOST;
4202
+ }
4166
4203
  function buildDefaultBrokerUrl(host = DEFAULT_BROKER_HOST, port = DEFAULT_BROKER_PORT) {
4167
4204
  return `http://${host}:${port}`;
4168
4205
  }
@@ -4183,15 +4220,28 @@ function isInstalledRuntimePackageDir(candidate) {
4183
4220
  return existsSync6(join8(candidate, "package.json")) && existsSync6(join8(candidate, "bin", "openscout-runtime.mjs"));
4184
4221
  }
4185
4222
  function findGlobalRuntimeDir() {
4186
- const bunCandidate = join8(homedir5(), ".bun", "node_modules", "@openscout", "runtime");
4187
- if (isInstalledRuntimePackageDir(bunCandidate))
4188
- return bunCandidate;
4189
- const bunGlobalCandidate = join8(homedir5(), ".bun", "install", "global", "node_modules", "@openscout", "runtime");
4190
- if (isInstalledRuntimePackageDir(bunGlobalCandidate))
4191
- return bunGlobalCandidate;
4192
- const bunScoutNested = join8(homedir5(), ".bun", "install", "global", "node_modules", "@openscout", "scout", "node_modules", "@openscout", "runtime");
4193
- if (isInstalledRuntimePackageDir(bunScoutNested))
4194
- return bunScoutNested;
4223
+ const candidates = [
4224
+ join8(homedir5(), ".bun", "node_modules", "@openscout", "runtime"),
4225
+ join8(homedir5(), ".bun", "install", "global", "node_modules", "@openscout", "runtime"),
4226
+ join8(homedir5(), ".bun", "install", "global", "node_modules", "@openscout", "scout", "node_modules", "@openscout", "runtime")
4227
+ ];
4228
+ for (const c of candidates) {
4229
+ if (isInstalledRuntimePackageDir(c))
4230
+ return c;
4231
+ }
4232
+ try {
4233
+ const result = spawnSync("which", ["scout"], { encoding: "utf8", timeout: 3000 });
4234
+ const scoutBin = result.stdout?.trim();
4235
+ if (scoutBin) {
4236
+ const scoutPkg = resolve4(scoutBin, "..", "..");
4237
+ const nested = join8(scoutPkg, "node_modules", "@openscout", "runtime");
4238
+ if (isInstalledRuntimePackageDir(nested))
4239
+ return nested;
4240
+ const sibling = resolve4(scoutPkg, "..", "runtime");
4241
+ if (isInstalledRuntimePackageDir(sibling))
4242
+ return sibling;
4243
+ }
4244
+ } catch {}
4195
4245
  return null;
4196
4246
  }
4197
4247
  function findWorkspaceRuntimeDir(startDir) {
@@ -4265,11 +4315,12 @@ function resolveBrokerServiceConfig() {
4265
4315
  const label = resolveBrokerServiceLabel(mode);
4266
4316
  const uid = typeof process.getuid === "function" ? process.getuid() : Number.parseInt(process.env.UID ?? "0", 10);
4267
4317
  const supportPaths = resolveOpenScoutSupportPaths();
4268
- const supportDirectory = supportPaths.supportDirectory;
4269
- const logsDirectory = supportPaths.brokerLogsDirectory;
4270
- const rawControlHome = supportPaths.controlHome;
4271
- const controlHome = /^\/(?:private\/)?tmp\//.test(rawControlHome) ? join8(homedir5(), ".openscout", "control-plane") : rawControlHome;
4272
- const brokerHost = process.env.OPENSCOUT_BROKER_HOST ?? DEFAULT_BROKER_HOST;
4318
+ const defaultSupportDir = join8(homedir5(), "Library", "Application Support", "OpenScout");
4319
+ const supportDirectory = isTmpPath(supportPaths.supportDirectory) ? defaultSupportDir : supportPaths.supportDirectory;
4320
+ const logsDirectory = join8(supportDirectory, "logs", "broker");
4321
+ const controlHome = isTmpPath(supportPaths.controlHome) ? join8(homedir5(), ".openscout", "control-plane") : supportPaths.controlHome;
4322
+ const advertiseScope = resolveAdvertiseScope();
4323
+ const brokerHost = resolveBrokerHost(advertiseScope);
4273
4324
  const brokerPort = Number.parseInt(process.env.OPENSCOUT_BROKER_PORT ?? String(DEFAULT_BROKER_PORT), 10);
4274
4325
  const brokerUrl = process.env.OPENSCOUT_BROKER_URL ?? buildDefaultBrokerUrl(brokerHost, brokerPort);
4275
4326
  const launchAgentPath = join8(homedir5(), "Library", "LaunchAgents", `${label}.plist`);
@@ -4289,7 +4340,8 @@ function resolveBrokerServiceConfig() {
4289
4340
  bunExecutable: resolveBunExecutable(),
4290
4341
  brokerHost,
4291
4342
  brokerPort,
4292
- brokerUrl
4343
+ brokerUrl,
4344
+ advertiseScope
4293
4345
  };
4294
4346
  }
4295
4347
  function renderLaunchAgentPlist(config) {
@@ -4301,6 +4353,7 @@ function renderLaunchAgentPlist(config) {
4301
4353
  OPENSCOUT_CONTROL_HOME: config.controlHome,
4302
4354
  OPENSCOUT_BROKER_SERVICE_MODE: config.mode,
4303
4355
  OPENSCOUT_BROKER_SERVICE_LABEL: config.label,
4356
+ OPENSCOUT_ADVERTISE_SCOPE: config.advertiseScope,
4304
4357
  HOME: homedir5(),
4305
4358
  PATH: launchPath,
4306
4359
  ...collectOptionalEnvVars([
@@ -4371,7 +4424,7 @@ function resolveLaunchAgentPATH() {
4371
4424
  "/usr/sbin",
4372
4425
  "/sbin"
4373
4426
  ];
4374
- return Array.from(new Set(entries)).join(":");
4427
+ return Array.from(new Set(entries)).filter((e) => !isTmpPath(e)).join(":");
4375
4428
  }
4376
4429
  function xmlEscape(value) {
4377
4430
  return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&apos;");
@@ -4630,7 +4683,7 @@ function formatBrokerServiceStatus(status) {
4630
4683
  return lines.join(`
4631
4684
  `);
4632
4685
  }
4633
- var DEFAULT_BROKER_HOST = "127.0.0.1", DEFAULT_BROKER_PORT = 65535, BROKER_SERVICE_POLL_INTERVAL_MS = 100, DEFAULT_BROKER_START_TIMEOUT_MS = 15000, DEFAULT_BROKER_URL;
4686
+ var DEFAULT_BROKER_HOST = "127.0.0.1", DEFAULT_BROKER_HOST_MESH = "0.0.0.0", DEFAULT_BROKER_PORT = 65535, DEFAULT_ADVERTISE_SCOPE = "local", BROKER_SERVICE_POLL_INTERVAL_MS = 100, DEFAULT_BROKER_START_TIMEOUT_MS = 15000, DEFAULT_BROKER_URL;
4634
4687
  var init_broker_service = __esm(async () => {
4635
4688
  init_support_paths();
4636
4689
  DEFAULT_BROKER_URL = buildDefaultBrokerUrl();
@@ -5187,7 +5240,7 @@ function buildLocalAgentBinding(agentId, record, alive, nodeId, source) {
5187
5240
  };
5188
5241
  }
5189
5242
  async function inferLocalAgentBinding(agentId, nodeId) {
5190
- if (!agentId || BUILT_IN_LOCAL_AGENT_IDS.has(agentId)) {
5243
+ if (!agentId || BUILT_IN_AGENT_DEFINITION_IDS.has(agentId)) {
5191
5244
  return null;
5192
5245
  }
5193
5246
  const overrides = await readRelayAgentOverrides();
@@ -5198,7 +5251,7 @@ async function inferLocalAgentBinding(agentId, nodeId) {
5198
5251
  const record = localAgentRecordFromRelayAgentOverride(agentId, override);
5199
5252
  return buildLocalAgentBinding(agentId, record, isLocalAgentRecordOnline(agentId, record), nodeId, "relay-agent-registry");
5200
5253
  }
5201
- var BUILT_IN_LOCAL_AGENT_IDS, MODULE_DIRECTORY, OPENSCOUT_REPO_ROOT, DEFAULT_LOCAL_AGENT_CAPABILITIES, DEFAULT_LOCAL_AGENT_HARNESS = "claude";
5254
+ var MODULE_DIRECTORY, OPENSCOUT_REPO_ROOT, DEFAULT_LOCAL_AGENT_CAPABILITIES, DEFAULT_LOCAL_AGENT_HARNESS = "claude";
5202
5255
  var init_local_agents = __esm(async () => {
5203
5256
  init_src();
5204
5257
  init_claude_stream_json();
@@ -5207,7 +5260,6 @@ var init_local_agents = __esm(async () => {
5207
5260
  init_support_paths();
5208
5261
  init_local_agent_template();
5209
5262
  await init_broker_service();
5210
- BUILT_IN_LOCAL_AGENT_IDS = new Set(["scout", "builder", "reviewer", "research"]);
5211
5263
  MODULE_DIRECTORY = dirname6(fileURLToPath5(import.meta.url));
5212
5264
  OPENSCOUT_REPO_ROOT = resolve5(MODULE_DIRECTORY, "..", "..", "..");
5213
5265
  DEFAULT_LOCAL_AGENT_CAPABILITIES = ["chat", "invoke", "deliver"];
@@ -7515,6 +7567,7 @@ async function controlScoutDesktopPairingService(action, currentDirectory) {
7515
7567
  }
7516
7568
 
7517
7569
  // apps/desktop/src/app/desktop/shell.ts
7570
+ init_src();
7518
7571
  init_setup();
7519
7572
  import { readFile as readFile5, readdir as readdir3, stat as stat3 } from "fs/promises";
7520
7573
  import { performance } from "perf_hooks";
@@ -7551,7 +7604,6 @@ var BROKER_SYSTEM_CHANNEL_ID = "channel.system";
7551
7604
  var OPERATOR_ID = "operator";
7552
7605
  var DEFAULT_BROKER_HOST2 = "127.0.0.1";
7553
7606
  var DEFAULT_BROKER_PORT2 = 65535;
7554
- var BUILT_IN_SCOUT_AGENT_IDS = new Set([SCOUT_AGENT_ID, "builder", "reviewer", "research"]);
7555
7607
  function buildScoutBrokerUrlFromEnv() {
7556
7608
  const host = process.env.OPENSCOUT_BROKER_HOST ?? DEFAULT_BROKER_HOST2;
7557
7609
  const port = Number.parseInt(process.env.OPENSCOUT_BROKER_PORT ?? String(DEFAULT_BROKER_PORT2), 10);
@@ -8297,7 +8349,6 @@ function readProjectGitActivity(projectRoot) {
8297
8349
 
8298
8350
  // apps/desktop/src/app/desktop/shell.ts
8299
8351
  var OPERATOR_ID2 = "operator";
8300
- var BUILT_IN_ROLE_AGENT_IDS = new Set(["scout", "builder", "reviewer", "research"]);
8301
8352
  var RECENT_AGENT_ACTIVITY_WINDOW_SECONDS = 60 * 60 * 24 * 30;
8302
8353
  var RECONCILE_OFFLINE_WAIT_SECONDS = 60 * 3;
8303
8354
  var RECONCILE_NO_FOLLOW_UP_SECONDS = 60 * 10;
@@ -8508,7 +8559,7 @@ function interAgentThreadKey(participantIds) {
8508
8559
  function visibleRelayAgentIds(snapshot, configuredAgentIds, messagesByConversation, directActivity) {
8509
8560
  const visible = new Set([
8510
8561
  ...configuredAgentIds,
8511
- ...Array.from(BUILT_IN_ROLE_AGENT_IDS)
8562
+ ...Array.from(BUILT_IN_AGENT_DEFINITION_IDS)
8512
8563
  ]);
8513
8564
  const cutoff = Math.floor(Date.now() / 1000) - RECENT_AGENT_ACTIVITY_WINDOW_SECONDS;
8514
8565
  for (const [agentId, activity] of directActivity.entries()) {