@openscout/scout 0.2.37 → 0.2.39

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.
@@ -1202,27 +1202,38 @@ function agentIdentityMatches(identity, candidate) {
1202
1202
  return true;
1203
1203
  }
1204
1204
  function resolveAgentIdentity(identity, candidates) {
1205
+ const diagnosis = diagnoseAgentIdentity(identity, candidates);
1206
+ return diagnosis.kind === "resolved" ? diagnosis.match : null;
1207
+ }
1208
+ function diagnoseAgentIdentity(identity, candidates) {
1205
1209
  const aliasKeys = identityAliasKeys(identity);
1206
1210
  const exactAliasMatches = candidates.filter((candidate) => {
1207
1211
  const candidateAliasKeys = explicitCandidateAliases(candidate).map(canonicalizeAliasValue);
1208
1212
  return aliasKeys.some((key) => candidateAliasKeys.includes(key));
1209
1213
  });
1210
1214
  if (exactAliasMatches.length === 1) {
1211
- return exactAliasMatches[0];
1215
+ return { kind: "resolved", match: exactAliasMatches[0] };
1212
1216
  }
1213
1217
  if (exactAliasMatches.length > 1) {
1214
- return null;
1218
+ return { kind: "ambiguous", candidates: exactAliasMatches };
1215
1219
  }
1216
1220
  const matches = candidates.filter((candidate) => agentIdentityMatches(identity, candidate));
1217
1221
  if (matches.length === 1) {
1218
- return matches[0];
1222
+ return { kind: "resolved", match: matches[0] };
1223
+ }
1224
+ if (matches.length === 0) {
1225
+ return { kind: "unknown" };
1219
1226
  }
1220
1227
  if (!identity.nodeQualifier && !identity.workspaceQualifier && !identity.profile && !identity.harness) {
1221
- return matches.find((candidate) => normalizeAgentIdentitySegment(candidate.agentId) === identity.definitionId) ?? matches[0] ?? null;
1228
+ const exactIdMatch = matches.find((candidate) => normalizeAgentIdentitySegment(candidate.agentId) === identity.definitionId);
1229
+ if (exactIdMatch) {
1230
+ return { kind: "resolved", match: exactIdMatch };
1231
+ }
1232
+ return { kind: "ambiguous", candidates: matches };
1222
1233
  }
1223
- return null;
1234
+ return { kind: "ambiguous", candidates: matches };
1224
1235
  }
1225
- var DIMENSION_ALIASES, normalizeAgentSelectorSegment, parseAgentSelector, formatAgentSelector, extractAgentSelectors, resolveAgentSelector;
1236
+ var DIMENSION_ALIASES, normalizeAgentSelectorSegment, SCOUT_DISPATCHER_AGENT_ID = "scout", RESERVED_AGENT_DEFINITION_IDS, parseAgentSelector, formatAgentSelector, extractAgentSelectors, resolveAgentSelector;
1226
1237
  var init_agent_identity = __esm(() => {
1227
1238
  DIMENSION_ALIASES = {
1228
1239
  workspace: "workspace",
@@ -1236,6 +1247,9 @@ var init_agent_identity = __esm(() => {
1236
1247
  host: "node"
1237
1248
  };
1238
1249
  normalizeAgentSelectorSegment = normalizeAgentIdentitySegment;
1250
+ RESERVED_AGENT_DEFINITION_IDS = new Set([
1251
+ SCOUT_DISPATCHER_AGENT_ID
1252
+ ]);
1239
1253
  parseAgentSelector = parseAgentIdentity;
1240
1254
  formatAgentSelector = formatAgentIdentity;
1241
1255
  extractAgentSelectors = extractAgentIdentities;
@@ -4833,6 +4847,24 @@ import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as rea
4833
4847
  import { homedir as homedir5 } from "os";
4834
4848
  import { basename as basename3, dirname as dirname5, join as join8, resolve as resolve3 } from "path";
4835
4849
  import { fileURLToPath as fileURLToPath4 } from "url";
4850
+ function isTmpPath(p) {
4851
+ return /^\/(?:private\/)?tmp\//.test(p);
4852
+ }
4853
+ function resolveAdvertiseScope() {
4854
+ const raw2 = (process.env.OPENSCOUT_ADVERTISE_SCOPE ?? "").trim().toLowerCase();
4855
+ if (raw2 === "mesh")
4856
+ return "mesh";
4857
+ if (raw2 === "local")
4858
+ return "local";
4859
+ return DEFAULT_ADVERTISE_SCOPE;
4860
+ }
4861
+ function resolveBrokerHost(scope = resolveAdvertiseScope()) {
4862
+ const explicit = process.env.OPENSCOUT_BROKER_HOST;
4863
+ if (typeof explicit === "string" && explicit.trim().length > 0) {
4864
+ return explicit;
4865
+ }
4866
+ return scope === "mesh" ? DEFAULT_BROKER_HOST_MESH : DEFAULT_BROKER_HOST;
4867
+ }
4836
4868
  function buildDefaultBrokerUrl(host = DEFAULT_BROKER_HOST, port = DEFAULT_BROKER_PORT) {
4837
4869
  return `http://${host}:${port}`;
4838
4870
  }
@@ -4853,15 +4885,28 @@ function isInstalledRuntimePackageDir(candidate) {
4853
4885
  return existsSync5(join8(candidate, "package.json")) && existsSync5(join8(candidate, "bin", "openscout-runtime.mjs"));
4854
4886
  }
4855
4887
  function findGlobalRuntimeDir() {
4856
- const bunCandidate = join8(homedir5(), ".bun", "node_modules", "@openscout", "runtime");
4857
- if (isInstalledRuntimePackageDir(bunCandidate))
4858
- return bunCandidate;
4859
- const bunGlobalCandidate = join8(homedir5(), ".bun", "install", "global", "node_modules", "@openscout", "runtime");
4860
- if (isInstalledRuntimePackageDir(bunGlobalCandidate))
4861
- return bunGlobalCandidate;
4862
- const bunScoutNested = join8(homedir5(), ".bun", "install", "global", "node_modules", "@openscout", "scout", "node_modules", "@openscout", "runtime");
4863
- if (isInstalledRuntimePackageDir(bunScoutNested))
4864
- return bunScoutNested;
4888
+ const candidates = [
4889
+ join8(homedir5(), ".bun", "node_modules", "@openscout", "runtime"),
4890
+ join8(homedir5(), ".bun", "install", "global", "node_modules", "@openscout", "runtime"),
4891
+ join8(homedir5(), ".bun", "install", "global", "node_modules", "@openscout", "scout", "node_modules", "@openscout", "runtime")
4892
+ ];
4893
+ for (const c of candidates) {
4894
+ if (isInstalledRuntimePackageDir(c))
4895
+ return c;
4896
+ }
4897
+ try {
4898
+ const result = spawnSync("which", ["scout"], { encoding: "utf8", timeout: 3000 });
4899
+ const scoutBin = result.stdout?.trim();
4900
+ if (scoutBin) {
4901
+ const scoutPkg = resolve3(scoutBin, "..", "..");
4902
+ const nested = join8(scoutPkg, "node_modules", "@openscout", "runtime");
4903
+ if (isInstalledRuntimePackageDir(nested))
4904
+ return nested;
4905
+ const sibling = resolve3(scoutPkg, "..", "runtime");
4906
+ if (isInstalledRuntimePackageDir(sibling))
4907
+ return sibling;
4908
+ }
4909
+ } catch {}
4865
4910
  return null;
4866
4911
  }
4867
4912
  function findWorkspaceRuntimeDir(startDir) {
@@ -4935,11 +4980,12 @@ function resolveBrokerServiceConfig() {
4935
4980
  const label = resolveBrokerServiceLabel(mode);
4936
4981
  const uid = typeof process.getuid === "function" ? process.getuid() : Number.parseInt(process.env.UID ?? "0", 10);
4937
4982
  const supportPaths = resolveOpenScoutSupportPaths();
4938
- const supportDirectory = supportPaths.supportDirectory;
4939
- const logsDirectory = supportPaths.brokerLogsDirectory;
4940
- const rawControlHome = supportPaths.controlHome;
4941
- const controlHome = /^\/(?:private\/)?tmp\//.test(rawControlHome) ? join8(homedir5(), ".openscout", "control-plane") : rawControlHome;
4942
- const brokerHost = process.env.OPENSCOUT_BROKER_HOST ?? DEFAULT_BROKER_HOST;
4983
+ const defaultSupportDir = join8(homedir5(), "Library", "Application Support", "OpenScout");
4984
+ const supportDirectory = isTmpPath(supportPaths.supportDirectory) ? defaultSupportDir : supportPaths.supportDirectory;
4985
+ const logsDirectory = join8(supportDirectory, "logs", "broker");
4986
+ const controlHome = isTmpPath(supportPaths.controlHome) ? join8(homedir5(), ".openscout", "control-plane") : supportPaths.controlHome;
4987
+ const advertiseScope = resolveAdvertiseScope();
4988
+ const brokerHost = resolveBrokerHost(advertiseScope);
4943
4989
  const brokerPort = Number.parseInt(process.env.OPENSCOUT_BROKER_PORT ?? String(DEFAULT_BROKER_PORT), 10);
4944
4990
  const brokerUrl = process.env.OPENSCOUT_BROKER_URL ?? buildDefaultBrokerUrl(brokerHost, brokerPort);
4945
4991
  const launchAgentPath = join8(homedir5(), "Library", "LaunchAgents", `${label}.plist`);
@@ -4959,7 +5005,8 @@ function resolveBrokerServiceConfig() {
4959
5005
  bunExecutable: resolveBunExecutable(),
4960
5006
  brokerHost,
4961
5007
  brokerPort,
4962
- brokerUrl
5008
+ brokerUrl,
5009
+ advertiseScope
4963
5010
  };
4964
5011
  }
4965
5012
  function renderLaunchAgentPlist(config) {
@@ -4971,6 +5018,7 @@ function renderLaunchAgentPlist(config) {
4971
5018
  OPENSCOUT_CONTROL_HOME: config.controlHome,
4972
5019
  OPENSCOUT_BROKER_SERVICE_MODE: config.mode,
4973
5020
  OPENSCOUT_BROKER_SERVICE_LABEL: config.label,
5021
+ OPENSCOUT_ADVERTISE_SCOPE: config.advertiseScope,
4974
5022
  HOME: homedir5(),
4975
5023
  PATH: launchPath,
4976
5024
  ...collectOptionalEnvVars([
@@ -5041,7 +5089,7 @@ function resolveLaunchAgentPATH() {
5041
5089
  "/usr/sbin",
5042
5090
  "/sbin"
5043
5091
  ];
5044
- return Array.from(new Set(entries)).join(":");
5092
+ return Array.from(new Set(entries)).filter((e) => !isTmpPath(e)).join(":");
5045
5093
  }
5046
5094
  function xmlEscape(value) {
5047
5095
  return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&apos;");
@@ -5300,7 +5348,7 @@ function formatBrokerServiceStatus(status) {
5300
5348
  return lines.join(`
5301
5349
  `);
5302
5350
  }
5303
- 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;
5351
+ 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;
5304
5352
  var init_broker_service = __esm(async () => {
5305
5353
  init_support_paths();
5306
5354
  DEFAULT_BROKER_URL = buildDefaultBrokerUrl();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openscout/scout",
3
- "version": "0.2.37",
3
+ "version": "0.2.39",
4
4
  "description": "Published Scout package that installs the `scout` command",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -23,6 +23,6 @@
23
23
  "access": "public"
24
24
  },
25
25
  "dependencies": {
26
- "@openscout/runtime": "0.2.37"
26
+ "@openscout/runtime": "0.2.39"
27
27
  }
28
28
  }
@@ -1 +0,0 @@
1
- :root{--bg: #F9F9F8;--surface: #FFFFFF;--ink: #1C1C1A;--muted: #8A8A86;--dim: #C4C4C0;--border: #E4E4E2;--accent: #0066FF;--accent-soft: rgba(0, 102, 255, .08);--green: #22c55e;--red: #dc2626;--radius: 8px;--shadow-soft: rgba(24, 24, 22, .06);--sidebar-w: 280px;--font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, sans-serif;--font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;--font-serif: "Spectral", Georgia, serif;font-family:var(--font-sans);font-size:13px;line-height:1.5;color:var(--ink);background:var(--bg);-webkit-font-smoothing:antialiased}*{box-sizing:border-box;margin:0}body{margin:0}.s-app{display:flex;height:100vh;overflow:hidden}.s-sidebar{width:var(--sidebar-w);flex-shrink:0;display:flex;flex-direction:column;border-right:1px solid var(--border);background:var(--surface);height:100vh;overflow:hidden}.s-content{flex:1;min-width:0;height:100vh;overflow-y:auto;background:var(--bg)}.s-sidebar-header{padding:16px 16px 12px;flex-shrink:0}.s-logo{font-family:var(--font-serif);font-size:18px;font-weight:600;letter-spacing:-.02em;cursor:pointer;-webkit-user-select:none;user-select:none}.s-sidebar-footer{flex-shrink:0;padding:8px;border-top:1px solid var(--border)}.s-nav-item{display:flex;align-items:center;gap:8px;width:100%;border:none;background:none;padding:6px 8px;border-radius:6px;font-family:var(--font-sans);font-size:12px;font-weight:500;color:var(--muted);cursor:pointer;transition:background .12s ease,color .12s ease}.s-nav-item:hover{background:var(--bg);color:var(--ink)}.s-nav-item-active{background:var(--accent-soft);color:var(--accent)}.s-sidebar-label{padding:4px 16px 6px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--dim);flex-shrink:0}.s-sidebar-list{flex:1;overflow-y:auto;padding-bottom:12px}.s-sidebar-empty{padding:24px 16px;text-align:center;font-size:11px;color:var(--dim)}.s-sidebar-row{display:flex;align-items:center;gap:8px;padding:8px 12px;margin:0 6px;border-radius:6px;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background .1s ease}.s-sidebar-row:hover{background:var(--bg)}.s-sidebar-row-active,.s-sidebar-row-active:hover{background:var(--accent-soft)}.s-sidebar-row-body{flex:1;min-width:0}.s-sidebar-row-header{display:flex;align-items:center;gap:5px}.s-sidebar-row-name{font-size:12px;font-weight:600;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.s-sidebar-row-preview{font-size:11px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px;line-height:1.3}.s-sidebar-row-preview-empty{font-style:italic;color:var(--dim)}.s-sidebar-row-time{font-size:10px;color:var(--dim);font-family:var(--font-mono);flex-shrink:0;align-self:flex-start;margin-top:2px}.s-welcome{display:flex;align-items:center;justify-content:center;height:100%;color:var(--dim)}.s-welcome-inner{text-align:center}.s-welcome h2{font-family:var(--font-serif);font-size:24px;font-weight:600;color:var(--dim);margin-bottom:4px}.s-welcome p{font-size:12px}.s-home{padding:32px;height:100vh;overflow-y:auto}.s-home-header{margin-bottom:32px}.s-home-header h2{font-family:var(--font-serif);font-size:22px;font-weight:600;color:var(--ink);margin-bottom:4px}.s-home-header p{font-size:12px;color:var(--muted)}.s-home-section{margin-bottom:28px}.s-home-section-title{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--dim);margin-bottom:10px}.s-home-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;max-width:480px}.s-home-card-row{display:flex;align-items:center;gap:10px;padding:10px 14px;font-size:12px}.s-home-card-row+.s-home-card-row{border-top:1px solid var(--border)}.s-home-card-row-label{color:var(--muted);font-size:11px;min-width:80px;flex-shrink:0}.s-home-card-row-value{color:var(--ink);font-family:var(--font-mono);font-size:11px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.s-home-steps{list-style:none;padding:0;max-width:480px}.s-home-steps li{display:flex;align-items:baseline;gap:10px;padding:6px 0;font-size:12px;color:var(--ink);line-height:1.5}.s-home-steps li:before{content:attr(data-step);font-size:10px;font-weight:700;font-family:var(--font-mono);color:var(--muted);flex-shrink:0;width:18px;height:18px;display:flex;align-items:center;justify-content:center;border-radius:50%;background:var(--bg);border:1px solid var(--border)}.s-home-steps code{font-family:var(--font-mono);font-size:11px;background:var(--bg);border:1px solid var(--border);border-radius:4px;padding:1px 5px}.s-home-card-row-clickable{cursor:pointer;transition:background .1s ease}.s-home-card-row-clickable:hover{background:var(--bg)}.s-activity-stream{max-width:560px}.s-activity-row{display:flex;align-items:baseline;gap:8px;padding:4px 0;font-size:12px;line-height:1.5}.s-activity-row-clickable{cursor:pointer;border-radius:4px;padding:4px 6px;margin:0 -6px;transition:background .1s ease}.s-activity-row-clickable:hover{background:var(--surface)}.s-activity-time{font-size:10px;color:var(--dim);font-family:var(--font-mono);flex-shrink:0;min-width:36px}.s-activity-actor{font-weight:600;color:var(--ink);flex-shrink:0}.s-activity-kind{color:var(--muted)}.s-activity-title{color:var(--muted);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.s-activity-list{max-width:560px}.s-activity-list-row{display:flex;align-items:flex-start;gap:10px;padding:8px 0}.s-activity-list-item+.s-activity-list-item{border-top:1px solid var(--border)}.s-activity-list-row-clickable{cursor:pointer;border-radius:6px;padding:8px;margin:0 -8px;transition:background .1s ease}.s-activity-list-row-clickable:hover{background:var(--surface)}.s-activity-list-body{flex:1;min-width:0}.s-activity-list-header{display:flex;align-items:baseline;gap:6px}.s-activity-list-actor{font-size:12px;font-weight:600;color:var(--ink)}.s-activity-list-kind{font-size:11px;color:var(--muted)}.s-activity-list-title{font-size:12px;color:var(--ink);margin-top:2px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.s-activity-list-summary{font-size:11px;color:var(--muted);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.s-activity-expanded{padding:4px 8px 12px 38px}.s-activity-expanded-summary{font-size:12px;color:var(--ink);margin-bottom:8px;line-height:1.4}.s-activity-expanded-meta{display:flex;gap:8px;font-size:11px;padding:2px 0}.s-activity-meta-label{color:var(--muted);min-width:56px}.s-activity-meta-value{color:var(--ink);word-break:break-all}.s-activity-expanded-actions{margin-top:8px}.s-btn-sm{font-size:11px;padding:4px 10px}.s-error{color:var(--red);font-size:12px;padding:8px 12px;background:#fef2f2;border:1px solid #fecaca;border-radius:var(--radius);margin:12px}.s-empty{padding:32px 0;color:var(--muted);font-size:12px}.s-empty p:first-child{font-size:13px;font-weight:500;color:var(--ink);margin-bottom:4px}.s-meta{font-size:11px;color:var(--muted);font-family:var(--font-mono)}.s-spacer{flex:1}.s-dot{display:inline-block;width:6px;height:6px;border-radius:50%;flex-shrink:0}.s-dot-sm{width:5px;height:5px}.s-badge{font-size:10px;font-family:var(--font-mono);color:var(--muted);background:var(--bg);border-radius:4px;padding:1px 6px;flex-shrink:0;text-transform:uppercase;letter-spacing:.04em}.s-time{font-size:10px;color:var(--dim);font-family:var(--font-mono);flex-shrink:0;letter-spacing:.01em}.s-back{border:none;background:none;padding:0;font-family:var(--font-sans);font-size:12px;font-weight:500;color:var(--muted);cursor:pointer;transition:color .12s ease}.s-back:hover{color:var(--ink)}.s-chevron{width:12px;height:12px;flex-shrink:0;position:relative;opacity:.3;transition:opacity .14s ease}.s-chevron:before{content:"";position:absolute;top:3px;left:2px;width:6px;height:6px;border-right:1.5px solid var(--ink);border-bottom:1.5px solid var(--ink);transform:rotate(-45deg)}.s-avatar{width:32px;height:32px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;color:#fff}.s-avatar-sm{width:28px;height:28px;font-size:11px}.s-avatar-lg{width:56px;height:56px;font-size:20px}.s-conversation{display:flex;flex-direction:column;height:100vh}.s-conv-header{display:flex;align-items:center;gap:10px;padding:10px 20px;border-bottom:1px solid var(--border);background:var(--bg);flex-shrink:0;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background .12s ease}.s-conv-header:hover{background:#f6f6f5}.s-conv-header .s-back{margin-right:2px;font-size:16px;line-height:1}.s-conv-header-info{flex:1;min-width:0}.s-conv-header-name{font-size:13px;font-weight:600;color:var(--ink)}.s-conv-header-state{display:flex;align-items:center;gap:4px;font-size:11px;color:var(--muted);margin-top:1px}.s-conv-status{display:flex;align-items:center;gap:10px;padding:10px 20px;border-bottom:1px solid var(--border);flex-shrink:0}.s-conv-status-pending{background:#0066ff0f;border-bottom-color:#0066ff1f}.s-conv-status-working{background:#22c55e0f;border-bottom-color:#22c55e24}.s-conv-status-offline{background:#1118270a;border-bottom-color:#11182714}.s-conv-status-dot{width:8px;height:8px;border-radius:50%;background:currentColor;color:var(--accent);flex-shrink:0}.s-conv-status-working .s-conv-status-dot{color:var(--green);animation:s-pulse 1.4s ease-in-out infinite}.s-conv-status-offline .s-conv-status-dot{color:var(--dim)}.s-conv-status-copy{display:flex;flex-direction:column;min-width:0;gap:2px}.s-conv-status-label{font-size:11px;font-weight:700;color:var(--ink)}.s-conv-status-detail{font-size:11px;color:var(--muted);line-height:1.4}.s-messages{flex:1;overflow-y:auto;padding:16px 20px;display:flex;flex-direction:column;gap:6px}.s-msg{max-width:85%;align-self:flex-start}.s-msg-you{align-self:flex-end}.s-msg-header{display:flex;align-items:baseline;gap:6px;margin-bottom:2px;padding:0 2px}.s-msg-actor{font-size:11px;font-weight:600;color:var(--ink)}.s-msg-time{font-size:10px;color:var(--dim);font-family:var(--font-mono)}.s-msg-body{font-size:12px;line-height:1.5;color:var(--ink);white-space:pre-wrap;word-break:break-word;padding:8px 12px;border-radius:14px 14px 14px 4px;background:var(--surface);border:1px solid var(--border)}.s-msg-you .s-msg-body{border-radius:14px 14px 4px;background:var(--accent-soft);border-color:#0066ff1f}.s-msg-you .s-msg-header{justify-content:flex-end}.s-msg-working{max-width:85%;align-self:flex-start}.s-msg-working-body{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:14px 14px 14px 4px;background:linear-gradient(135deg,#22c55e14,#22c55e0a);border:1px solid rgba(34,197,94,.14)}.s-msg-working-copy{font-size:12px;line-height:1.45;color:var(--ink)}.s-typing-indicator{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.s-typing-dot{width:6px;height:6px;border-radius:50%;background:var(--green);opacity:.35;animation:s-typing-bounce 1.1s ease-in-out infinite}.s-typing-dot:nth-child(2){animation-delay:.14s}.s-typing-dot:nth-child(3){animation-delay:.28s}@keyframes s-typing-bounce{0%,80%,to{opacity:.35;transform:translateY(0)}40%{opacity:1;transform:translateY(-2px)}}.s-compose{display:flex;align-items:flex-end;gap:8px;padding:10px 20px;border-top:1px solid var(--border);background:var(--bg);flex-shrink:0}.s-compose-input{flex:1;border:1px solid var(--border);background:var(--surface);border-radius:20px;min-height:40px;max-height:160px;padding:10px 14px;font-family:var(--font-sans);font-size:12px;line-height:1.45;color:var(--ink);outline:none;transition:border-color .12s ease;resize:none;overflow-y:hidden;white-space:pre-wrap}.s-compose-input:focus{border-color:var(--accent)}.s-compose-input:disabled{opacity:.5;cursor:not-allowed}.s-compose-send{width:32px;height:32px;border-radius:50%;border:none;background:var(--ink);color:#fff;font-size:14px;font-weight:700;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:opacity .12s ease}.s-compose-send svg{display:block}.s-compose-send:disabled{opacity:.3;cursor:not-allowed}.s-agent-profile{display:flex;flex-direction:column;align-items:flex-start;padding:8px 0 16px;gap:4px}.s-agent-profile-name{font-size:18px;font-weight:600;color:var(--ink);margin-top:8px}.s-agent-profile-handle{font-size:12px;font-family:var(--font-mono);color:var(--muted)}.s-agent-profile-state{display:flex;align-items:center;gap:5px;font-size:12px;color:var(--muted);margin-top:4px}.s-agent-details{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;margin-top:16px;max-width:480px}.s-detail-row{display:flex;align-items:baseline;justify-content:space-between;padding:7px 14px;font-size:12px;gap:12px}.s-detail-row+.s-detail-row{border-top:1px solid var(--border)}.s-detail-label{color:var(--muted);flex-shrink:0;font-size:11px}.s-detail-value{color:var(--ink);font-family:var(--font-mono);font-size:11px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.s-section-title{font-size:15px;font-weight:600;color:var(--ink);margin-bottom:16px}.s-actions{display:flex;gap:8px;margin-bottom:16px}.s-btn{border:1px solid var(--border);background:var(--surface);padding:6px 14px;border-radius:var(--radius);font-family:var(--font-sans);font-size:12px;font-weight:500;cursor:pointer;transition:all .14s cubic-bezier(.16,1,.3,1)}.s-btn:hover{border-color:var(--dim);box-shadow:0 1px 2px var(--shadow-soft)}.s-btn:disabled{opacity:.4;cursor:not-allowed}.s-btn-primary{background:var(--ink);color:var(--bg);border-color:var(--ink)}.s-btn-primary:hover{background:#2a2a28;box-shadow:0 2px 6px var(--shadow-soft)}.s-qr{max-width:240px;margin:20px 0;padding:16px;background:var(--surface);border:1px solid var(--border);border-radius:12px;box-shadow:0 2px 6px var(--shadow-soft)}.s-qr svg{display:block;width:100%;height:auto}.s-pair-meta{max-width:360px;margin:0;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden}.s-pair-row{display:flex;align-items:center;justify-content:space-between;padding:7px 14px;font-size:12px}.s-pair-row+.s-pair-row{border-top:1px solid var(--border)}.s-pair-label{color:var(--muted);flex-shrink:0}.s-pair-value{display:flex;align-items:center;color:var(--ink);text-align:right;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.s-pair-mono{font-family:var(--font-mono);font-size:11px}.s-sidebar-nav{padding:0 8px 4px;flex-shrink:0}.s-nav-badge{font-size:10px;font-weight:600;font-family:var(--font-mono);color:#fff;background:var(--green);border-radius:10px;padding:0 6px;min-width:18px;text-align:center;line-height:16px;margin-left:auto}.s-sidebar-avatar-wrap{position:relative;flex-shrink:0}.s-task-indicator{position:absolute;bottom:-1px;right:-1px;width:8px;height:8px;border-radius:50%;background:var(--green);border:2px solid var(--surface)}.s-sidebar-row-active .s-task-indicator{border-color:#0066ff14}.s-flight-banner{display:flex;align-items:center;gap:6px;padding:6px 20px;background:#22c55e0f;border-bottom:1px solid rgba(34,197,94,.12);font-size:11px;flex-shrink:0}.s-flight-banner-dot{width:6px;height:6px;border-radius:50%;background:var(--green);flex-shrink:0;animation:s-pulse 2s ease-in-out infinite}@keyframes s-pulse{0%,to{opacity:1}50%{opacity:.4}}.s-flight-banner-label{font-weight:600;color:var(--ink)}.s-flight-banner-summary{color:var(--muted);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.s-flights{border:1px solid var(--border);border-radius:var(--radius);overflow:hidden}.s-flight-row{display:flex;align-items:center;gap:10px;padding:10px 14px;background:var(--surface);cursor:pointer;transition:background .12s ease}.s-flight-row:hover{background:#f6f6f5}.s-flight-row+.s-flight-row{border-top:1px solid var(--border)}.s-flight-body{flex:1;min-width:0}.s-flight-header{display:flex;align-items:center;gap:6px}.s-flight-name{font-size:12px;font-weight:600;color:var(--ink)}.s-flight-state{font-size:11px;font-family:var(--font-mono);font-weight:500}.s-flight-summary{font-size:11px;color:var(--muted);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.s-content>div:not(.s-conversation):not(.s-welcome):not(.s-home):not(.s-agents-layout){padding:24px 32px;max-width:640px}.s-agents-layout{display:flex;height:100vh;overflow:hidden}.s-agents-list-panel{width:100%;height:100vh;overflow-y:auto;padding:24px 16px;transition:width .15s ease}.s-agents-layout-split .s-agents-list-panel{width:280px;flex-shrink:0;border-right:1px solid var(--border);padding:16px 8px}.s-agents-detail-panel{flex:1;min-width:0;height:100vh;overflow-y:auto;padding:24px 32px}.s-agent-list-row{display:flex;align-items:center;gap:10px;padding:8px;border-radius:6px;cursor:pointer;transition:background .1s ease}.s-agent-list-row:hover{background:var(--bg)}.s-agent-list-row-active,.s-agent-list-row-active:hover{background:var(--accent-soft)}.s-agent-list-body{flex:1;min-width:0}.s-agent-list-header{display:flex;align-items:center;gap:5px}.s-agent-list-name{font-size:12px;font-weight:600;color:var(--ink)}.s-agent-list-qualifier{font-size:10px;font-family:var(--font-mono);color:var(--dim);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.s-agent-list-meta{display:flex;align-items:center;gap:8px;margin-top:1px;font-size:11px;color:var(--muted)}.s-agent-list-meta span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.s-agent-detail-header{display:flex;align-items:center;gap:16px;margin-bottom:20px}.s-agent-detail-name{font-size:18px;font-weight:600;color:var(--ink);display:flex;align-items:baseline;gap:8px}.s-agent-detail-qualifier{font-size:12px;font-family:var(--font-mono);color:var(--dim);font-weight:400}.s-agent-detail-state{display:flex;align-items:center;gap:5px;font-size:12px;color:var(--muted);margin-top:2px}.s-agent-detail-meta{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;max-width:480px}.s-agent-detail-section{margin-top:20px}.s-agent-detail-messages{max-width:480px}.s-agent-detail-msg{display:flex;align-items:baseline;gap:6px;padding:4px 0;font-size:12px}.s-agent-detail-msg-clickable{cursor:pointer;border-radius:4px;margin:0 -4px;padding:4px}.s-agent-detail-msg-clickable:hover{background:var(--hover)}.s-agent-detail-msg+.s-agent-detail-msg{border-top:1px solid var(--border)}.s-agent-detail-msg-actor{font-weight:600;color:var(--ink);flex-shrink:0}.s-agent-detail-msg-body{color:var(--muted);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media(max-width:767px){.s-sidebar{width:100%;position:absolute;inset:0;z-index:20;transition:transform .2s cubic-bezier(.16,1,.3,1)}.s-content{position:absolute;inset:0;z-index:10;transform:translate(100%);transition:transform .2s cubic-bezier(.16,1,.3,1)}.s-app{position:relative}.s-app-content-open .s-sidebar{transform:translate(-100%)}.s-app-content-open .s-content{transform:translate(0)}.s-conv-header .s-back{display:block}}@media(min-width:768px){.s-conv-header .s-back{display:none}}.s-sessions-screen,.s-mesh-screen{padding:20px 24px}.s-sessions-header{display:flex;align-items:baseline;gap:12px;margin-bottom:16px}.s-page-title{font-size:18px;font-weight:600;letter-spacing:-.01em}.s-session-participants{font-size:10px;font-family:var(--font-mono);color:var(--dim);margin-top:2px}.s-filter-bar{display:flex;gap:6px;margin-bottom:16px;overflow-x:auto}.s-filter-chip{font-size:11px;font-weight:500;padding:4px 12px;border-radius:20px;border:1px solid var(--border);background:var(--surface);color:var(--muted);cursor:pointer;flex-shrink:0;transition:background .15s,color .15s}.s-filter-chip:hover{background:var(--bg)}.s-filter-chip-active{background:var(--accent);color:#fff;border-color:var(--accent)}.s-filter-chip-active:hover{background:var(--accent)}.s-mesh-status-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:4px 0;margin-bottom:16px}.s-mesh-warnings{display:flex;flex-direction:column;gap:8px;margin-bottom:16px}.s-mesh-warning{font-size:12px;line-height:1.55;padding:10px 14px;border-radius:var(--radius);background:#f59e0b14;color:#92400e;border:1px solid rgba(245,158,11,.2)}.s-mesh-section{margin-bottom:20px}.s-mesh-section-title{font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin-bottom:10px;display:flex;align-items:center}.s-mesh-nodes{display:flex;flex-direction:column;gap:6px}.s-mesh-node{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:10px 14px}.s-mesh-node-local{border-color:var(--accent);border-width:1.5px}.s-mesh-node-header{display:flex;align-items:center;gap:8px}.s-mesh-node-name{font-size:13px;font-weight:500}.s-mesh-node-detail{font-size:11px;color:var(--muted);margin-top:3px;padding-left:14px}::-webkit-scrollbar{width:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:var(--muted)}