sootsim 0.1.175 → 0.1.177

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/dist-cli/bin.js +3 -3
  2. package/dist-cli/chunks/{agent-A4WFJEFV.js → agent-3BCITLIZ.js} +3 -3
  3. package/dist-cli/chunks/{agent-wrapper-EOZBE6UT.js → agent-wrapper-26RIZVGD.js} +2 -2
  4. package/dist-cli/chunks/{app-fonts-H2I7IV7N.js → app-fonts-JVDHATQE.js} +2 -2
  5. package/dist-cli/chunks/{assert-36QXQUCE.js → assert-IT2OXM4Y.js} +2 -2
  6. package/dist-cli/chunks/beta-SPH73CAA.js +2 -0
  7. package/dist-cli/chunks/{camera-7HK2Y3PY.js → camera-ZYVEUCIO.js} +2 -2
  8. package/dist-cli/chunks/{chunk-2QTAUBZX.js → chunk-3L6I2M2Z.js} +3 -3
  9. package/dist-cli/chunks/chunk-4INGTBO7.js +4 -0
  10. package/dist-cli/chunks/{chunk-EEIUS5AS.js → chunk-4JESO36F.js} +4 -4
  11. package/dist-cli/chunks/{chunk-HWUFW3IP.js → chunk-4YNKFN2A.js} +2 -2
  12. package/dist-cli/chunks/{chunk-V7AGBG2P.js → chunk-52O56BTW.js} +2 -2
  13. package/dist-cli/chunks/{chunk-ZZWAHZ37.js → chunk-64QAFSY7.js} +1 -1
  14. package/dist-cli/chunks/{chunk-OMJ2DTQJ.js → chunk-65ZBQDQM.js} +2 -2
  15. package/dist-cli/chunks/{chunk-DV6SWCY7.js → chunk-A2WASN2L.js} +1 -1
  16. package/dist-cli/chunks/{chunk-H2J4Z7LY.js → chunk-A3VHHWLU.js} +2 -2
  17. package/dist-cli/chunks/{chunk-UMJDCX2P.js → chunk-AN4DM7IB.js} +2 -2
  18. package/dist-cli/chunks/{chunk-5QLWXLML.js → chunk-ATVKVVHZ.js} +2 -2
  19. package/dist-cli/chunks/chunk-B6GISAUX.js +1 -0
  20. package/dist-cli/chunks/{chunk-P2WO5LMI.js → chunk-BTTZN2SN.js} +2 -2
  21. package/dist-cli/chunks/{chunk-LYZXARZO.js → chunk-C5QOGCVN.js} +2 -2
  22. package/dist-cli/chunks/{chunk-RCPMRHTK.js → chunk-CH3MWM5W.js} +1 -1
  23. package/dist-cli/chunks/{chunk-7F2LH7U5.js → chunk-CHTYIQLE.js} +2 -2
  24. package/dist-cli/chunks/{chunk-SV3SRWN5.js → chunk-CUO7F2JE.js} +1 -1
  25. package/dist-cli/chunks/{chunk-YMBQBKKA.js → chunk-D2BBJUEY.js} +1 -1
  26. package/dist-cli/chunks/chunk-DGDBEXXQ.js +1 -0
  27. package/dist-cli/chunks/{chunk-3SUIAUIY.js → chunk-IBSEFPPL.js} +1 -1
  28. package/dist-cli/chunks/{chunk-ZPQY5DBY.js → chunk-JFLNZGDS.js} +2 -2
  29. package/dist-cli/chunks/{chunk-4UATZVHM.js → chunk-JHYLPDCC.js} +2 -2
  30. package/dist-cli/chunks/{chunk-XDDO46ZW.js → chunk-JS3NH2SJ.js} +1 -1
  31. package/dist-cli/chunks/{chunk-UXZRHPX6.js → chunk-JS7SSYDG.js} +2 -2
  32. package/dist-cli/chunks/{chunk-HWJ52K4J.js → chunk-JXO6UPGI.js} +1 -1
  33. package/dist-cli/chunks/{chunk-MLLINRL2.js → chunk-LTZPVG65.js} +1 -1
  34. package/dist-cli/chunks/{chunk-GJQGKFLY.js → chunk-NOLQYF76.js} +1 -1
  35. package/dist-cli/chunks/{chunk-2J67UJXT.js → chunk-NYGESF6F.js} +1 -1
  36. package/dist-cli/chunks/{chunk-QK76RK6J.js → chunk-NZWTC6K6.js} +1 -1
  37. package/dist-cli/chunks/{chunk-NPZPBSZD.js → chunk-PAU64XFG.js} +1 -1
  38. package/dist-cli/chunks/{chunk-IKJSGKUB.js → chunk-PL3ALTWB.js} +2 -2
  39. package/dist-cli/chunks/{chunk-ZG2A6LCL.js → chunk-QWZFOMCI.js} +2 -2
  40. package/dist-cli/chunks/{chunk-Y3OHYOFS.js → chunk-SNLUVL3H.js} +2 -2
  41. package/dist-cli/chunks/{chunk-KSF72FPP.js → chunk-SU3JJ7ER.js} +2 -2
  42. package/dist-cli/chunks/{chunk-XBK3XAKL.js → chunk-TVFHGWTW.js} +2 -2
  43. package/dist-cli/chunks/{chunk-JCQEG4R6.js → chunk-UBJQDMDG.js} +2 -2
  44. package/dist-cli/chunks/{chunk-VW643HG5.js → chunk-UJN3FMEX.js} +2 -2
  45. package/dist-cli/chunks/chunk-WKG5J4RD.js +2 -0
  46. package/dist-cli/chunks/{chunk-IISA6UXR.js → chunk-WRHJEI7Y.js} +1 -1
  47. package/dist-cli/chunks/{chunk-4UGD4KJM.js → chunk-WUEKKZ7Z.js} +2 -2
  48. package/dist-cli/chunks/{chunk-5D4PHINP.js → chunk-Y2637KG7.js} +1 -1
  49. package/dist-cli/chunks/chunk-YU6CNUJD.js +2 -0
  50. package/dist-cli/chunks/{chunk-46S56FJJ.js → chunk-YVDSGGOT.js} +1 -1
  51. package/dist-cli/chunks/{chunk-WM73SGMM.js → chunk-Z4IMGLHM.js} +2 -2
  52. package/dist-cli/chunks/{chunk-4PQ36DTJ.js → chunk-ZUTVEJVA.js} +3 -3
  53. package/dist-cli/chunks/cli-version-HENS6BZI.js +2 -0
  54. package/dist-cli/chunks/{compat-KWM6HXJD.js → compat-MNTQH57R.js} +3 -3
  55. package/dist-cli/chunks/{control-PVZRPH57.js → control-WQ7XEPCI.js} +2 -2
  56. package/dist-cli/chunks/{cpu-profile-3YLLRNVG.js → cpu-profile-P27HBXOI.js} +2 -2
  57. package/dist-cli/chunks/daemon-WUAZELEI.js +2 -0
  58. package/dist-cli/chunks/{debug-TD4EVFT7.js → debug-ES4A3SZQ.js} +3 -3
  59. package/dist-cli/chunks/{detox-S7M5WN3L.js → detox-Q36B2553.js} +2 -2
  60. package/dist-cli/chunks/{device-WR7GA4RN.js → device-NA7TB4E6.js} +2 -2
  61. package/dist-cli/chunks/{diagnose-JZMNR25X.js → diagnose-DKW5WI3X.js} +2 -2
  62. package/dist-cli/chunks/drivers-RFOOGIRC.js +2 -0
  63. package/dist-cli/chunks/{electron-V2YDDVKJ.js → electron-6C2VDAZW.js} +3 -3
  64. package/dist-cli/chunks/flow-GSHP52QS.js +2 -0
  65. package/dist-cli/chunks/help-J6PF4PZX.js +2 -0
  66. package/dist-cli/chunks/{hints-OK373YOJ.js → hints-W7ZZ6KZE.js} +2 -2
  67. package/dist-cli/chunks/{home-paths-IFY5UTLL.js → home-paths-K4347S7C.js} +2 -2
  68. package/dist-cli/chunks/{inspect-LRIJ7MQT.js → inspect-ZPHNFMEX.js} +4 -4
  69. package/dist-cli/chunks/{install-desktop-ESQL2Q2T.js → install-desktop-ZCCPJMOF.js} +3 -3
  70. package/dist-cli/chunks/{keys-IHG2YEL3.js → keys-XM67H4SM.js} +2 -2
  71. package/dist-cli/chunks/{login-CYIWYJGG.js → login-O4OGJKYL.js} +4 -4
  72. package/dist-cli/chunks/{logout-NALFLZWI.js → logout-DWCBRMLM.js} +2 -2
  73. package/dist-cli/chunks/{maestro-QKSXVPWG.js → maestro-MEWENIGQ.js} +2 -2
  74. package/dist-cli/chunks/optional-demo-registry-O3XS3WXJ.js +2 -0
  75. package/dist-cli/chunks/{preview-XCQGBN2I.js → preview-VPWG4462.js} +2 -2
  76. package/dist-cli/chunks/{profile-RDAPVU7K.js → profile-R4CSGXYJ.js} +2 -2
  77. package/dist-cli/chunks/{react-MM373YNE.js → react-5LFUOYV5.js} +2 -2
  78. package/dist-cli/chunks/{record-SQA376Z7.js → record-MHAAYOWF.js} +2 -2
  79. package/dist-cli/chunks/runtime-R2PRKIZM.js +2 -0
  80. package/dist-cli/chunks/{screenshot-FCKW6JV6.js → screenshot-XAEO7EBF.js} +2 -2
  81. package/dist-cli/chunks/{screenshot-mode-QVRUJXZ3.js → screenshot-mode-QNR5ESKN.js} +2 -2
  82. package/dist-cli/chunks/{screenshots-ITBCSBZS.js → screenshots-Z6OSENKY.js} +2 -2
  83. package/dist-cli/chunks/{screenshots-capture-H4EAYFH3.js → screenshots-capture-3DJPYJUD.js} +2 -2
  84. package/dist-cli/chunks/{serve-3GHYSGJR.js → serve-IVTQFOFI.js} +16 -16
  85. package/dist-cli/chunks/{setup-ME5SRHWD.js → setup-AMRSL4IK.js} +2 -2
  86. package/dist-cli/chunks/{skills-E5JE3SAI.js → skills-K4DG2CIH.js} +2 -2
  87. package/dist-cli/chunks/{slides-D37ML4LI.js → slides-UIH7KXFR.js} +2 -2
  88. package/dist-cli/chunks/store-2JY2VLVA.js +2 -0
  89. package/dist-cli/chunks/telemetry-KNKROOT5.js +2 -0
  90. package/dist-cli/chunks/{test-CWWQJG5K.js → test-XUJ2V5ZX.js} +3 -3
  91. package/dist-cli/chunks/{three-mode-WESGARG5.js → three-mode-P6HSLJMD.js} +2 -2
  92. package/dist-cli/chunks/{timeline-RUVZASG4.js → timeline-YSUY4PHV.js} +2 -2
  93. package/dist-cli/chunks/{upgrade-DKWD6TSY.js → upgrade-YZMDFQIH.js} +2 -2
  94. package/dist-cli/chunks/upload-TIH2LID6.js +2 -0
  95. package/dist-cli/chunks/{version-G45RLONC.js → version-5QAMZ5CK.js} +2 -2
  96. package/dist-cli/chunks/{web-X2HCJQQE.js → web-LM3JSBQF.js} +2 -2
  97. package/dist-cli/chunks/{what-happened-5DBVOXKC.js → what-happened-NYVQ7KER.js} +2 -2
  98. package/dist-cli/chunks/{whoami-ZDT3RQOC.js → whoami-AAHH72FM.js} +2 -2
  99. package/dist-lib/agent-daemon-client.cjs +10 -1
  100. package/dist-lib/agent-events.cjs +1 -1
  101. package/dist-lib/agent-sessions.cjs +1 -1
  102. package/dist-lib/attached-projects.cjs +1 -1
  103. package/dist-lib/auth/shared-session.cjs +1 -1
  104. package/dist-lib/backend-origin.cjs +1 -1
  105. package/dist-lib/beta.cjs +1 -1
  106. package/dist-lib/beta.mjs +1 -1
  107. package/dist-lib/bridge-constants.cjs +7 -1
  108. package/dist-lib/cli-constants.cjs +1 -1
  109. package/dist-lib/config.cjs +1 -1
  110. package/dist-lib/detox/index.cjs +1 -1
  111. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  112. package/dist-lib/home-paths.cjs +1 -1
  113. package/dist-lib/host/bridge-host.cjs +126 -12
  114. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  115. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  116. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  117. package/dist-lib/host/websocket-proxy.cjs +1 -1
  118. package/dist-lib/index.cjs +1 -1
  119. package/dist-lib/jump-to-source-babel.cjs +1 -1
  120. package/dist-lib/menu.cjs +1 -1
  121. package/dist-lib/menu.mjs +1 -1
  122. package/dist-lib/metro.cjs +1 -1
  123. package/dist-lib/profiles.cjs +1 -1
  124. package/dist-lib/render-mode.cjs +1 -1
  125. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  126. package/dist-lib/sdk.cjs +1 -1
  127. package/dist-lib/sdk.mjs +1 -1
  128. package/dist-lib/skills.cjs +237 -102
  129. package/dist-lib/vite.cjs +1 -1
  130. package/package.json +7 -1
  131. package/src/agent-daemon-client.ts +13 -0
  132. package/src/agent-identity.ts +21 -0
  133. package/src/agentbus-prompt.ts +80 -0
  134. package/src/bridge-constants.ts +9 -0
  135. package/src/host/agent-host.ts +42 -0
  136. package/src/host/bridge-host.ts +14 -1
  137. package/src/native-seam-manifest.ts +11 -0
  138. package/dist-cli/chunks/beta-7FRVMDBH.js +0 -2
  139. package/dist-cli/chunks/chunk-3G5EE3ST.js +0 -2
  140. package/dist-cli/chunks/chunk-HCKTFQLK.js +0 -2
  141. package/dist-cli/chunks/chunk-ODISDSXU.js +0 -1
  142. package/dist-cli/chunks/chunk-RAESCYIA.js +0 -4
  143. package/dist-cli/chunks/chunk-URQSBUTU.js +0 -1
  144. package/dist-cli/chunks/cli-version-HCYSKPJO.js +0 -2
  145. package/dist-cli/chunks/daemon-2DT4QAJ4.js +0 -2
  146. package/dist-cli/chunks/drivers-UMQTPEMU.js +0 -2
  147. package/dist-cli/chunks/flow-CKXTFJJ7.js +0 -2
  148. package/dist-cli/chunks/help-OEMLUQMD.js +0 -2
  149. package/dist-cli/chunks/optional-demo-registry-CIEW2ET7.js +0 -2
  150. package/dist-cli/chunks/runtime-CUNVH66R.js +0 -2
  151. package/dist-cli/chunks/store-UW5HH6DW.js +0 -2
  152. package/dist-cli/chunks/telemetry-KSBNWXNE.js +0 -2
  153. package/dist-cli/chunks/upload-LYANGCPB.js +0 -2
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.175 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.177 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -5530,9 +5530,9 @@ var init_registry = __esm({
5530
5530
  versions: [
5531
5531
  {
5532
5532
  range: ">=1.0.0",
5533
- coverage: 0.85,
5534
- note: "load-safe noop \u2014 Editor passes children through",
5535
- missing: "no native markdown editing \u2014 recommended swap: marked/markdown-it + textarea on web"
5533
+ coverage: 0.65,
5534
+ note: "native seam for EnrichedMarkdownText/EnrichedMarkdown/EnrichedMarkdownTextInput generated host components; upstream JS wrapper and Streamdown integration run unchanged",
5535
+ missing: "native MD4C fidelity, selection menus, spoilers, math, images, and editable rich-markdown commands are simplified"
5536
5536
  }
5537
5537
  ]
5538
5538
  },
@@ -9962,6 +9962,12 @@ function resolveSootsimBridgePortForRuntimeLocation(input = {}) {
9962
9962
  const hrefUrl = parseHrefUrl(input.href);
9963
9963
  const httpPort = parsePort(input.httpPort) ?? parsePort(hrefUrl?.port);
9964
9964
  if (httpPort === null) return DEFAULT_SOOTSIM_BRIDGE_PORT;
9965
+ if (hrefUrl?.pathname.startsWith("/sootsim") && (hrefUrl.searchParams.has("embed") || hrefUrl.searchParams.has("nativePreview"))) {
9966
+ return resolveSootsimBridgePortForHttpPort({
9967
+ httpPort,
9968
+ baseHttpPort: SOOTBEAN_DEV_HTTP_BASE_PORT
9969
+ });
9970
+ }
9965
9971
  if (hrefUrl?.pathname.startsWith("/sootsim") && httpPort >= SOOTSIM_SITE_DEV_HTTP_BASE_PORT && httpPort <= SOOTSIM_SITE_DEV_HTTP_BASE_PORT + MAX_LOCAL_DEV_PORT_OFFSET) {
9966
9972
  return resolveSootsimBridgePortForHttpPort({
9967
9973
  httpPort,
@@ -10100,10 +10106,10 @@ function tcpPing(port, timeout = TCP_GATE_MS) {
10100
10106
  sock.connect(port, "localhost");
10101
10107
  });
10102
10108
  }
10103
- function httpGet(port, path9, method = "GET", timeout = TIMEOUT_MS, headers = {}) {
10109
+ function httpGet(port, path10, method = "GET", timeout = TIMEOUT_MS, headers = {}) {
10104
10110
  return new Promise((resolve6) => {
10105
10111
  const req = import_http.default.request(
10106
- { hostname: "localhost", port, path: path9, method, timeout, headers },
10112
+ { hostname: "localhost", port, path: path10, method, timeout, headers },
10107
10113
  (res) => {
10108
10114
  let body = "";
10109
10115
  res.on("data", (c) => body += c.toString());
@@ -11718,6 +11724,97 @@ var init_agent_sessions = __esm({
11718
11724
  }
11719
11725
  });
11720
11726
 
11727
+ // src/agent-identity.ts
11728
+ function agentbusSessionIdFromCliIdentity(identity) {
11729
+ if (!identity?.startsWith("AGENTBUS_SESSION:")) return null;
11730
+ const sessionId = identity.slice("AGENTBUS_SESSION:".length).trim();
11731
+ if (!AGENTBUS_SESSION_RE.test(sessionId)) return null;
11732
+ return sessionId;
11733
+ }
11734
+ function isValidAgentbusSessionId(sessionId) {
11735
+ return AGENTBUS_SESSION_RE.test(sessionId);
11736
+ }
11737
+ var AGENTBUS_SESSION_RE;
11738
+ var init_agent_identity = __esm({
11739
+ "src/agent-identity.ts"() {
11740
+ "use strict";
11741
+ AGENTBUS_SESSION_RE = /^[A-Za-z0-9._:-]{1,160}$/;
11742
+ }
11743
+ });
11744
+
11745
+ // src/agentbus-prompt.ts
11746
+ function formatAgentbusPromptText(prompt) {
11747
+ return typeof prompt.text === "string" ? prompt.text.trim() : "";
11748
+ }
11749
+ function resolveAgentbusCommand(explicit) {
11750
+ const fromArg = explicit?.trim();
11751
+ if (fromArg) return fromArg;
11752
+ const fromEnv = process.env.AGENTBUS_COMMAND?.trim();
11753
+ if (fromEnv) return fromEnv;
11754
+ const localBin = import_node_path4.default.join(import_node_os2.default.homedir(), ".local", "bin", "agentbus");
11755
+ if (import_node_fs5.default.existsSync(localBin)) return localBin;
11756
+ return "agentbus";
11757
+ }
11758
+ async function sendPromptToAgentbusSession(input) {
11759
+ const sessionId = input.sessionId.trim();
11760
+ if (!isValidAgentbusSessionId(sessionId)) {
11761
+ throw new Error(`invalid agentbus session id: ${sessionId || "<empty>"}`);
11762
+ }
11763
+ const text = formatAgentbusPromptText(input.prompt);
11764
+ if (!text) {
11765
+ throw new Error("prompt text is empty");
11766
+ }
11767
+ const command = resolveAgentbusCommand(input.command);
11768
+ const timeoutMs = input.timeoutMs ?? 15e3;
11769
+ await new Promise((resolve6, reject) => {
11770
+ const child = (0, import_node_child_process2.spawn)(command, ["send", sessionId, text], {
11771
+ stdio: ["ignore", "ignore", "pipe"],
11772
+ env: process.env
11773
+ });
11774
+ let stderr = "";
11775
+ const timer = setTimeout(() => {
11776
+ try {
11777
+ child.kill("SIGTERM");
11778
+ } catch {
11779
+ }
11780
+ reject(new Error(`agentbus send timed out after ${Math.round(timeoutMs / 1e3)}s`));
11781
+ }, timeoutMs);
11782
+ child.stderr?.setEncoding("utf8");
11783
+ child.stderr?.on("data", (chunk) => {
11784
+ if (stderr.length < 4e3) stderr += String(chunk);
11785
+ });
11786
+ child.on("error", (err) => {
11787
+ clearTimeout(timer);
11788
+ reject(err);
11789
+ });
11790
+ child.on("exit", (code, signal) => {
11791
+ clearTimeout(timer);
11792
+ if (code === 0) {
11793
+ resolve6();
11794
+ return;
11795
+ }
11796
+ const detail = stderr.trim();
11797
+ reject(
11798
+ new Error(
11799
+ detail || `agentbus send exited with ${signal ? `signal ${signal}` : `code ${code ?? "unknown"}`}`
11800
+ )
11801
+ );
11802
+ });
11803
+ });
11804
+ }
11805
+ var import_node_child_process2, import_node_fs5, import_node_os2, import_node_path4;
11806
+ var init_agentbus_prompt = __esm({
11807
+ "src/agentbus-prompt.ts"() {
11808
+ "use strict";
11809
+ import_node_child_process2 = require("node:child_process");
11810
+ import_node_fs5 = __toESM(require("node:fs"), 1);
11811
+ import_node_os2 = __toESM(require("node:os"), 1);
11812
+ import_node_path4 = __toESM(require("node:path"), 1);
11813
+ init_agent_identity();
11814
+ init_agent_identity();
11815
+ }
11816
+ });
11817
+
11721
11818
  // src/host/agent-host.ts
11722
11819
  function defaultExcludePorts() {
11723
11820
  return [
@@ -11732,14 +11829,15 @@ function mapFrameworkToProjectFramework(fw) {
11732
11829
  if (fw === "one" || fw === "vxrn") return "one";
11733
11830
  return "unknown";
11734
11831
  }
11735
- var import_node_fs5, import_node_path4, WS_OPEN, AgentHost;
11832
+ var import_node_fs6, import_node_path5, WS_OPEN, AgentHost;
11736
11833
  var init_agent_host = __esm({
11737
11834
  "src/host/agent-host.ts"() {
11738
11835
  "use strict";
11739
- import_node_fs5 = __toESM(require("node:fs"), 1);
11740
- import_node_path4 = __toESM(require("node:path"), 1);
11836
+ import_node_fs6 = __toESM(require("node:fs"), 1);
11837
+ import_node_path5 = __toESM(require("node:path"), 1);
11741
11838
  init_dev_server_scanner();
11742
11839
  init_agent_sessions();
11840
+ init_agentbus_prompt();
11743
11841
  init_attached_projects();
11744
11842
  WS_OPEN = 1;
11745
11843
  AgentHost = class {
@@ -11839,6 +11937,8 @@ var init_agent_host = __esm({
11839
11937
  return listSessions(msg.projectId ? String(msg.projectId) : void 0);
11840
11938
  case "agent:start-session":
11841
11939
  return this.doStartSession(msg.input ?? {});
11940
+ case "agent:send-claimed-prompt":
11941
+ return this.sendClaimedPrompt(msg);
11842
11942
  case "agent:send-prompt": {
11843
11943
  const sessionId = String(msg.sessionId);
11844
11944
  const session = findSessionById(sessionId);
@@ -11870,6 +11970,28 @@ var init_agent_host = __esm({
11870
11970
  }
11871
11971
  }
11872
11972
  // --- operation impls ---
11973
+ async sendClaimedPrompt(msg) {
11974
+ const simId = typeof msg.simId === "string" ? msg.simId.trim() : "";
11975
+ if (!simId) {
11976
+ throw new AgentSessionError("NO_SIM", "agent:send-claimed-prompt requires simId");
11977
+ }
11978
+ const lease = this.opts.resolveCliLease?.(simId) ?? null;
11979
+ if (!lease || lease.kind !== "cli" || lease.expiresAt <= Date.now()) {
11980
+ throw new AgentSessionError("NO_CLAIM", `sim ${simId} has no active CLI claim`);
11981
+ }
11982
+ const sessionId = agentbusSessionIdFromCliIdentity(lease.cliIdentityKey);
11983
+ if (!sessionId) {
11984
+ throw new AgentSessionError(
11985
+ "UNSUPPORTED_CLAIM",
11986
+ `sim ${simId} is claimed by a CLI identity that is not promptable`
11987
+ );
11988
+ }
11989
+ await sendPromptToAgentbusSession({
11990
+ sessionId,
11991
+ prompt: this.normalizePromptEnvelope(msg)
11992
+ });
11993
+ return { ok: true, routed: "agentbus", sessionId };
11994
+ }
11873
11995
  async doStartSession(input) {
11874
11996
  const project = findProjectById(input.projectId);
11875
11997
  if (!project) {
@@ -11899,7 +12021,7 @@ var init_agent_host = __esm({
11899
12021
  );
11900
12022
  const project = upsertProject({
11901
12023
  cwd: match.cwd,
11902
- name: match.projectName ?? import_node_path4.default.basename(match.cwd),
12024
+ name: match.projectName ?? import_node_path5.default.basename(match.cwd),
11903
12025
  preferredProvider: input.provider ?? existing?.preferredProvider,
11904
12026
  sourceRoots: existing?.sourceRoots ?? [match.cwd],
11905
12027
  knownBundleUrls,
@@ -11910,18 +12032,18 @@ var init_agent_host = __esm({
11910
12032
  }
11911
12033
  getTranscript(sessionId) {
11912
12034
  const p = transcriptPath(sessionId);
11913
- if (!import_node_fs5.default.existsSync(p)) {
12035
+ if (!import_node_fs6.default.existsSync(p)) {
11914
12036
  return { error: "transcript not found", code: "NO_TRANSCRIPT" };
11915
12037
  }
11916
- return import_node_fs5.default.readFileSync(p, "utf8");
12038
+ return import_node_fs6.default.readFileSync(p, "utf8");
11917
12039
  }
11918
12040
  getPaths() {
11919
12041
  const dir = getUserDataDir();
11920
12042
  return {
11921
12043
  userDataDir: dir,
11922
- storeFile: import_node_path4.default.join(dir, "attached-projects.json"),
11923
- sessionsDir: import_node_path4.default.join(dir, "sessions"),
11924
- transcriptsDir: import_node_path4.default.join(dir, "transcripts")
12044
+ storeFile: import_node_path5.default.join(dir, "attached-projects.json"),
12045
+ sessionsDir: import_node_path5.default.join(dir, "sessions"),
12046
+ transcriptsDir: import_node_path5.default.join(dir, "transcripts")
11925
12047
  };
11926
12048
  }
11927
12049
  // --- subscription management ---
@@ -12961,7 +13083,18 @@ var init_bridge_host = __esm({
12961
13083
  this.shouldWriteDevLockfile = opts.writeDevLockfile === true;
12962
13084
  this.portFallbackCount = Math.max(1, opts.portFallbackCount ?? 10);
12963
13085
  this.openUrlHandler = opts.openUrl;
12964
- this.agentHost = new AgentHost({ getExcludePorts: opts.agentScanExcludes });
13086
+ this.agentHost = new AgentHost({
13087
+ getExcludePorts: opts.agentScanExcludes,
13088
+ resolveCliLease: (simId) => {
13089
+ const sim = this.sims.get(simId);
13090
+ const lease = sim ? this.getActiveLease(sim) : null;
13091
+ return lease ? {
13092
+ kind: lease.kind,
13093
+ cliIdentityKey: lease.cliIdentityKey,
13094
+ expiresAt: lease.expiresAt
13095
+ } : null;
13096
+ }
13097
+ });
12965
13098
  this.sootbeanOrigin = opts.sootbeanOrigin?.replace(/\/$/, "") || null;
12966
13099
  this.simIdleReapTtlMs = opts.simIdleReapTtlMs ?? _SootSimBridgeHost.SIM_IDLE_REAP_TTL_MS;
12967
13100
  this.automationSimIdleReapTtlMs = opts.automationSimIdleReapTtlMs ?? _SootSimBridgeHost.AUTOMATION_SIM_IDLE_REAP_TTL_MS;
@@ -14781,6 +14914,8 @@ var init_current_sim = __esm({
14781
14914
  IDENTITY_ENV_VARS = [
14782
14915
  "SOOTSIM_CLI_IDENTITY",
14783
14916
  // explicit override — fastest path, skips all pid lookups
14917
+ "AGENTBUS_SESSION",
14918
+ // agentbus session id; lets sootsim route prompt-bar followups back to this agent
14784
14919
  "CLAUDE_CODE_SESSION_ID",
14785
14920
  // claude code, if ever set
14786
14921
  "CODEX_THREAD_ID",
@@ -15135,11 +15270,11 @@ async function evalInBridge(bridge, code, opts = {}) {
15135
15270
  if (opts.acquireLock) payload.acquireLock = true;
15136
15271
  return bridge.send(payload);
15137
15272
  }
15138
- async function callInBridge(bridge, path9, ...args) {
15139
- return bridge.send({ type: "call", path: path9, args });
15273
+ async function callInBridge(bridge, path10, ...args) {
15274
+ return bridge.send({ type: "call", path: path10, args });
15140
15275
  }
15141
- async function callInBridgeWrite(bridge, path9, ...args) {
15142
- return bridge.send({ type: "call", path: path9, args, acquireLock: true });
15276
+ async function callInBridgeWrite(bridge, path10, ...args) {
15277
+ return bridge.send({ type: "call", path: path10, args, acquireLock: true });
15143
15278
  }
15144
15279
  var import_ws3, BridgeSimLockedError;
15145
15280
  var init_ws_bridge = __esm({
@@ -16142,14 +16277,14 @@ process.stdin.on('end', async () => {
16142
16277
  function getBaseDir() {
16143
16278
  const explicit = process.env[SESSION_FILE_ENV];
16144
16279
  if (explicit?.trim()) {
16145
- return (0, import_node_path5.dirname)((0, import_node_path5.resolve)(explicit));
16280
+ return (0, import_node_path6.dirname)((0, import_node_path6.resolve)(explicit));
16146
16281
  }
16147
16282
  return electronUserDataDir();
16148
16283
  }
16149
16284
  function getSharedDesktopAuthFilePath() {
16150
16285
  const explicit = process.env[SESSION_FILE_ENV];
16151
- if (explicit?.trim()) return (0, import_node_path5.resolve)(explicit);
16152
- return (0, import_node_path5.join)(getBaseDir(), "desktop-auth.json");
16286
+ if (explicit?.trim()) return (0, import_node_path6.resolve)(explicit);
16287
+ return (0, import_node_path6.join)(getBaseDir(), "desktop-auth.json");
16153
16288
  }
16154
16289
  function normalizeUser(input) {
16155
16290
  if (!input || typeof input !== "object") return null;
@@ -16195,26 +16330,26 @@ function normalizeSession(input) {
16195
16330
  }
16196
16331
  function readSharedDesktopAuthSession() {
16197
16332
  const filepath = getSharedDesktopAuthFilePath();
16198
- if (!(0, import_node_fs6.existsSync)(filepath)) return null;
16333
+ if (!(0, import_node_fs7.existsSync)(filepath)) return null;
16199
16334
  try {
16200
- const parsed = JSON.parse((0, import_node_fs6.readFileSync)(filepath, "utf8"));
16335
+ const parsed = JSON.parse((0, import_node_fs7.readFileSync)(filepath, "utf8"));
16201
16336
  const normalized = normalizeSession(parsed);
16202
16337
  if (!normalized) {
16203
- (0, import_node_fs6.rmSync)(filepath, { force: true });
16338
+ (0, import_node_fs7.rmSync)(filepath, { force: true });
16204
16339
  return null;
16205
16340
  }
16206
16341
  return normalized;
16207
16342
  } catch {
16208
- (0, import_node_fs6.rmSync)(filepath, { force: true });
16343
+ (0, import_node_fs7.rmSync)(filepath, { force: true });
16209
16344
  return null;
16210
16345
  }
16211
16346
  }
16212
- var import_node_fs6, import_node_path5, SESSION_VERSION, SESSION_FILE_ENV, DEFAULT_ORIGIN;
16347
+ var import_node_fs7, import_node_path6, SESSION_VERSION, SESSION_FILE_ENV, DEFAULT_ORIGIN;
16213
16348
  var init_shared_session = __esm({
16214
16349
  "src/auth/shared-session.ts"() {
16215
16350
  "use strict";
16216
- import_node_fs6 = require("node:fs");
16217
- import_node_path5 = require("node:path");
16351
+ import_node_fs7 = require("node:fs");
16352
+ import_node_path6 = require("node:path");
16218
16353
  init_home_paths();
16219
16354
  SESSION_VERSION = 1;
16220
16355
  SESSION_FILE_ENV = "SOOTSIM_SHARED_AUTH_FILE";
@@ -16224,13 +16359,13 @@ var init_shared_session = __esm({
16224
16359
 
16225
16360
  // cli/auth.ts
16226
16361
  function credentialsPath() {
16227
- return (0, import_node_path6.join)(electronUserDataDir(), "credentials.json");
16362
+ return (0, import_node_path7.join)(electronUserDataDir(), "credentials.json");
16228
16363
  }
16229
16364
  function readStoredApiKey() {
16230
16365
  const file = credentialsPath();
16231
- if (!(0, import_node_fs7.existsSync)(file)) return null;
16366
+ if (!(0, import_node_fs8.existsSync)(file)) return null;
16232
16367
  try {
16233
- const parsed = JSON.parse((0, import_node_fs7.readFileSync)(file, "utf8"));
16368
+ const parsed = JSON.parse((0, import_node_fs8.readFileSync)(file, "utf8"));
16234
16369
  if (parsed.version !== 1) return null;
16235
16370
  if (typeof parsed.apiKey !== "string" || !parsed.apiKey.startsWith("sk_sootsim_")) {
16236
16371
  return null;
@@ -16286,12 +16421,12 @@ function resolveCliAuth() {
16286
16421
  function authHeaderValue(auth) {
16287
16422
  return auth.kind === "api-key" ? `Bearer ${auth.secret}` : `Bearer ${auth.token}`;
16288
16423
  }
16289
- var import_node_fs7, import_node_path6, GITHUB_TOKEN_PREFIXES;
16424
+ var import_node_fs8, import_node_path7, GITHUB_TOKEN_PREFIXES;
16290
16425
  var init_auth = __esm({
16291
16426
  "cli/auth.ts"() {
16292
16427
  "use strict";
16293
- import_node_fs7 = require("node:fs");
16294
- import_node_path6 = require("node:path");
16428
+ import_node_fs8 = require("node:fs");
16429
+ import_node_path7 = require("node:path");
16295
16430
  init_shared_session();
16296
16431
  init_home_paths();
16297
16432
  GITHUB_TOKEN_PREFIXES = ["ghs_", "ghp_", "gho_", "ghu_", "github_pat_"];
@@ -16481,16 +16616,16 @@ function resolveFlowScreenshotPath(screenshotDir, name) {
16481
16616
  }
16482
16617
  function resolveProjectRelativeFlowBase(flowDir) {
16483
16618
  if (!flowDir) return process.cwd();
16484
- return path7.basename(flowDir) === ".maestro" ? path7.dirname(flowDir) : flowDir;
16619
+ return path8.basename(flowDir) === ".maestro" ? path8.dirname(flowDir) : flowDir;
16485
16620
  }
16486
16621
  function resolveFlowScreenshotPathWithMode(screenshotDir, name, opts) {
16487
16622
  const normalizedName = name.endsWith(".png") ? name : `${name}.png`;
16488
- if (path7.isAbsolute(normalizedName)) return normalizedName;
16623
+ if (path8.isAbsolute(normalizedName)) return normalizedName;
16489
16624
  if (opts.mode === "flow" && /[\\/]/.test(normalizedName)) {
16490
16625
  const baseDir = normalizedName.startsWith("./") || normalizedName.startsWith("../") ? opts.flowDir ?? process.cwd() : resolveProjectRelativeFlowBase(opts.flowDir);
16491
- return path7.resolve(baseDir, normalizedName);
16626
+ return path8.resolve(baseDir, normalizedName);
16492
16627
  }
16493
- return path7.join(screenshotDir, normalizedName);
16628
+ return path8.join(screenshotDir, normalizedName);
16494
16629
  }
16495
16630
  function normalizeFlowScreenshotSpec(step) {
16496
16631
  if (typeof step === "string") {
@@ -16545,12 +16680,12 @@ function parseFlowSteps(content) {
16545
16680
  const parsed = import_yaml.default.parse(candidate);
16546
16681
  return Array.isArray(parsed) ? parsed : [];
16547
16682
  }
16548
- var fs7, path7, import_settings2, import_yaml, DEFAULT_TIMEOUT, SCREEN_W, SCREEN_H, CLI_PERF_SESSION_GLOBAL, SootSimBridgeFlowRunner;
16683
+ var fs8, path8, import_settings2, import_yaml, DEFAULT_TIMEOUT, SCREEN_W, SCREEN_H, CLI_PERF_SESSION_GLOBAL, SootSimBridgeFlowRunner;
16549
16684
  var init_bridge_flow_runner = __esm({
16550
16685
  "cli/bridge-flow-runner.ts"() {
16551
16686
  "use strict";
16552
- fs7 = __toESM(require("fs"), 1);
16553
- path7 = __toESM(require("path"), 1);
16687
+ fs8 = __toESM(require("fs"), 1);
16688
+ path8 = __toESM(require("path"), 1);
16554
16689
  import_settings2 = require("sootsim-engine/settings");
16555
16690
  import_yaml = __toESM(require("yaml"), 1);
16556
16691
  init_frame_compose();
@@ -16772,14 +16907,14 @@ var init_bridge_flow_runner = __esm({
16772
16907
  if (chunks.length === 0) {
16773
16908
  throw new Error("recording requested but no video buffer was produced");
16774
16909
  }
16775
- fs7.mkdirSync(this.opts.recordingOutputDir, { recursive: true });
16910
+ fs8.mkdirSync(this.opts.recordingOutputDir, { recursive: true });
16776
16911
  const videoMime = stopped.mime || this.opts.recordingFormat || "video/webm";
16777
16912
  const extension = videoMime.includes("mp4") ? "mp4" : "webm";
16778
- const outputPath = path7.join(
16913
+ const outputPath = path8.join(
16779
16914
  this.opts.recordingOutputDir,
16780
16915
  `sootsim-${Date.now()}.${extension}`
16781
16916
  );
16782
- fs7.writeFileSync(outputPath, Buffer.concat(chunks));
16917
+ fs8.writeFileSync(outputPath, Buffer.concat(chunks));
16783
16918
  return outputPath;
16784
16919
  }
16785
16920
  async waitForRecordingTail(opts) {
@@ -17192,7 +17327,7 @@ var init_bridge_flow_runner = __esm({
17192
17327
  flowDir: this.opts.flowDir
17193
17328
  }
17194
17329
  );
17195
- fs7.mkdirSync(path7.dirname(outputPath), { recursive: true });
17330
+ fs8.mkdirSync(path8.dirname(outputPath), { recursive: true });
17196
17331
  const layers = spec.layers ?? this.opts.screenshotLayers;
17197
17332
  const screenshotRequest = {
17198
17333
  type: "screenshot",
@@ -17208,11 +17343,11 @@ var init_bridge_flow_runner = __esm({
17208
17343
  throw new Error("could not read current device model for framed screenshot");
17209
17344
  }
17210
17345
  const framed = await composeFramedScreenshot(rawBuffer, model);
17211
- fs7.writeFileSync(outputPath, framed);
17346
+ fs8.writeFileSync(outputPath, framed);
17212
17347
  console.log(`[flow] screenshot: ${outputPath} (frame: ${model})`);
17213
17348
  return;
17214
17349
  }
17215
- fs7.writeFileSync(outputPath, rawBuffer);
17350
+ fs8.writeFileSync(outputPath, rawBuffer);
17216
17351
  console.log(`[flow] screenshot: ${outputPath}`);
17217
17352
  }
17218
17353
  async readCurrentDeviceModel() {
@@ -17227,22 +17362,22 @@ var init_bridge_flow_runner = __esm({
17227
17362
  return model;
17228
17363
  }
17229
17364
  async captureFailureScreenshot(outputPath) {
17230
- fs7.mkdirSync(path7.dirname(outputPath), { recursive: true });
17365
+ fs8.mkdirSync(path8.dirname(outputPath), { recursive: true });
17231
17366
  const dataUrl = await this.bridge.send({
17232
17367
  type: "screenshot",
17233
17368
  simId: this.opts.simId
17234
17369
  });
17235
17370
  const base64 = dataUrl.replace(/^data:image\/png;base64,/, "");
17236
- fs7.writeFileSync(outputPath, Buffer.from(base64, "base64"));
17371
+ fs8.writeFileSync(outputPath, Buffer.from(base64, "base64"));
17237
17372
  }
17238
17373
  // writes a per-failure debug bundle: screenshot + structured describe
17239
17374
  // + a11y tree + console errors/warnings + failed network requests +
17240
17375
  // shell state, all under one directory so post-mortem is one grep away.
17241
17376
  async captureFailureBundle(outputDir, context) {
17242
- fs7.mkdirSync(outputDir, { recursive: true });
17377
+ fs8.mkdirSync(outputDir, { recursive: true });
17243
17378
  const write = (name, content) => {
17244
17379
  try {
17245
- fs7.writeFileSync(path7.join(outputDir, name), content);
17380
+ fs8.writeFileSync(path8.join(outputDir, name), content);
17246
17381
  } catch {
17247
17382
  }
17248
17383
  };
@@ -17743,8 +17878,8 @@ var init_bridge_flow_runner = __esm({
17743
17878
  runScript(target) {
17744
17879
  const spec = typeof target === "string" ? { file: target } : target;
17745
17880
  if (!spec.file) throw new Error("runScript requires a file");
17746
- const scriptPath = path7.resolve(this.opts.flowDir, spec.file);
17747
- const source = fs7.readFileSync(scriptPath, "utf8");
17881
+ const scriptPath = path8.resolve(this.opts.flowDir, spec.file);
17882
+ const source = fs8.readFileSync(scriptPath, "utf8");
17748
17883
  this.js.evaluate(source, { env: spec.env });
17749
17884
  console.log(`[flow] runScript: ${spec.file} done`);
17750
17885
  }
@@ -17983,10 +18118,10 @@ var init_bridge_flow_runner = __esm({
17983
18118
  for (const [k, v] of Object.entries(env)) this.js.putEnv(k, v);
17984
18119
  }
17985
18120
  if (file) {
17986
- const flowPath = path7.resolve(this.opts.flowDir, file);
17987
- const flowContent = fs7.readFileSync(flowPath, "utf8");
18121
+ const flowPath = path8.resolve(this.opts.flowDir, file);
18122
+ const flowContent = fs8.readFileSync(flowPath, "utf8");
17988
18123
  const previousDir = this.opts.flowDir;
17989
- this.opts.flowDir = path7.dirname(flowPath);
18124
+ this.opts.flowDir = path8.dirname(flowPath);
17990
18125
  try {
17991
18126
  await this.runFlow(parseFlowSteps(flowContent));
17992
18127
  } finally {
@@ -18082,8 +18217,8 @@ __export(registry_exports, {
18082
18217
  skillRegistry: () => skillRegistry
18083
18218
  });
18084
18219
  module.exports = __toCommonJS(registry_exports);
18085
- var fs8 = __toESM(require("fs"), 1);
18086
- var path8 = __toESM(require("path"), 1);
18220
+ var fs9 = __toESM(require("fs"), 1);
18221
+ var path9 = __toESM(require("path"), 1);
18087
18222
 
18088
18223
  // src/skills/builtin/a11y-review.ts
18089
18224
  var skill = {
@@ -18101,8 +18236,8 @@ var skill = {
18101
18236
  },
18102
18237
  async execute(params, context) {
18103
18238
  const { chromium } = await import("playwright");
18104
- const path9 = await import("path");
18105
- const fs9 = await import("fs");
18239
+ const path10 = await import("path");
18240
+ const fs10 = await import("fs");
18106
18241
  const browser = await chromium.launch({ channel: "chrome", headless: true });
18107
18242
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
18108
18243
  try {
@@ -18155,9 +18290,9 @@ var skill = {
18155
18290
  warnings: issues.filter((i) => i.severity === "warning").length,
18156
18291
  tree: typeof tree === "string" ? tree : JSON.stringify(tree)
18157
18292
  };
18158
- const reportPath = path9.join(context.outputDir, "a11y-report.json");
18159
- fs9.mkdirSync(path9.dirname(reportPath), { recursive: true });
18160
- fs9.writeFileSync(reportPath, JSON.stringify(report, null, 2));
18293
+ const reportPath = path10.join(context.outputDir, "a11y-report.json");
18294
+ fs10.mkdirSync(path10.dirname(reportPath), { recursive: true });
18295
+ fs10.writeFileSync(reportPath, JSON.stringify(report, null, 2));
18161
18296
  return {
18162
18297
  success: issues.filter((i) => i.severity === "error").length === 0,
18163
18298
  message: `${report.errors} errors, ${report.warnings} warnings across ${report.nodeCount} nodes`,
@@ -18195,8 +18330,8 @@ var skill2 = {
18195
18330
  }
18196
18331
  },
18197
18332
  async execute(params, context) {
18198
- const fs9 = await import("fs");
18199
- const path9 = await import("path");
18333
+ const fs10 = await import("fs");
18334
+ const path10 = await import("path");
18200
18335
  const { POLYFILL_REGISTRY: POLYFILL_REGISTRY2 } = await Promise.resolve().then(() => (init_web(), web_exports));
18201
18336
  if (params.packageName) {
18202
18337
  const entry = POLYFILL_REGISTRY2[params.packageName];
@@ -18214,11 +18349,11 @@ var skill2 = {
18214
18349
  data: { package: params.packageName, status, ...entry }
18215
18350
  };
18216
18351
  }
18217
- const pkgPath = path9.join(context.projectDir, "package.json");
18218
- if (!fs9.existsSync(pkgPath)) {
18352
+ const pkgPath = path10.join(context.projectDir, "package.json");
18353
+ if (!fs10.existsSync(pkgPath)) {
18219
18354
  return { success: false, message: "No package.json found" };
18220
18355
  }
18221
- const pkg = JSON.parse(fs9.readFileSync(pkgPath, "utf8"));
18356
+ const pkg = JSON.parse(fs10.readFileSync(pkgPath, "utf8"));
18222
18357
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
18223
18358
  const results = {
18224
18359
  full: [],
@@ -18236,9 +18371,9 @@ var skill2 = {
18236
18371
  results.unknown.push(dep);
18237
18372
  }
18238
18373
  }
18239
- const reportPath = path9.join(context.outputDir, "compat-report.json");
18240
- fs9.mkdirSync(path9.dirname(reportPath), { recursive: true });
18241
- fs9.writeFileSync(reportPath, JSON.stringify(results, null, 2));
18374
+ const reportPath = path10.join(context.outputDir, "compat-report.json");
18375
+ fs10.mkdirSync(path10.dirname(reportPath), { recursive: true });
18376
+ fs10.writeFileSync(reportPath, JSON.stringify(results, null, 2));
18242
18377
  return {
18243
18378
  success: results.unsupported.length === 0,
18244
18379
  message: `${results.full.length} full, ${results.partial.length} partial, ${results.unsupported.length} unsupported, ${results.unknown.length} unknown`,
@@ -18276,8 +18411,8 @@ var skill3 = {
18276
18411
  },
18277
18412
  async execute(params, context) {
18278
18413
  const { chromium } = await import("playwright");
18279
- const path9 = await import("path");
18280
- const fs9 = await import("fs");
18414
+ const path10 = await import("path");
18415
+ const fs10 = await import("fs");
18281
18416
  const browser = await chromium.launch({ channel: "chrome", headless: true });
18282
18417
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
18283
18418
  try {
@@ -18301,9 +18436,9 @@ var skill3 = {
18301
18436
  ...profile,
18302
18437
  fps: syncCount > 0 ? (syncCount / (duration / 1e3)).toFixed(1) : "0"
18303
18438
  };
18304
- const reportPath = path9.join(context.outputDir, "perf-report.json");
18305
- fs9.mkdirSync(path9.dirname(reportPath), { recursive: true });
18306
- fs9.writeFileSync(reportPath, JSON.stringify(report, null, 2));
18439
+ const reportPath = path10.join(context.outputDir, "perf-report.json");
18440
+ fs10.mkdirSync(path10.dirname(reportPath), { recursive: true });
18441
+ fs10.writeFileSync(reportPath, JSON.stringify(report, null, 2));
18307
18442
  return {
18308
18443
  success: true,
18309
18444
  message: `${report.fps} fps, ${profile.avgSyncMs?.toFixed(1)}ms avg sync, ${nodeCount} nodes`,
@@ -18335,15 +18470,15 @@ var skill4 = {
18335
18470
  },
18336
18471
  async execute(params, context) {
18337
18472
  const { chromium } = await import("playwright");
18338
- const path9 = await import("path");
18339
- const fs9 = await import("fs");
18473
+ const path10 = await import("path");
18474
+ const fs10 = await import("fs");
18340
18475
  const browser = await chromium.launch({ channel: "chrome", headless: true });
18341
18476
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
18342
18477
  try {
18343
18478
  await page.goto(context.url, { waitUntil: "networkidle" });
18344
18479
  await page.waitForTimeout(2e3);
18345
- const outputPath = path9.join(context.outputDir, `${params.name}.png`);
18346
- fs9.mkdirSync(path9.dirname(outputPath), { recursive: true });
18480
+ const outputPath = path10.join(context.outputDir, `${params.name}.png`);
18481
+ fs10.mkdirSync(path10.dirname(outputPath), { recursive: true });
18347
18482
  await page.screenshot({ path: outputPath });
18348
18483
  return {
18349
18484
  success: true,
@@ -18381,8 +18516,8 @@ var skill5 = {
18381
18516
  record: { type: "boolean", description: "Record video of the flow" }
18382
18517
  },
18383
18518
  async execute(params, context) {
18384
- const fs9 = await import("fs");
18385
- const path9 = await import("path");
18519
+ const fs10 = await import("fs");
18520
+ const path10 = await import("path");
18386
18521
  const yaml2 = await import("yaml");
18387
18522
  const { DEFAULT_SOOTSIM_BRIDGE_PORT: DEFAULT_SOOTSIM_BRIDGE_PORT2 } = await Promise.resolve().then(() => (init_bridge_constants(), bridge_constants_exports));
18388
18523
  const { SootSimBridgeHost: SootSimBridgeHost2 } = await Promise.resolve().then(() => (init_bridge_host(), bridge_host_exports));
@@ -18391,7 +18526,7 @@ var skill5 = {
18391
18526
  const host = new SootSimBridgeHost2({ port: DEFAULT_SOOTSIM_BRIDGE_PORT2 });
18392
18527
  host.start({ silent: true });
18393
18528
  try {
18394
- const flowContent = fs9.readFileSync(params.flowPath, "utf8");
18529
+ const flowContent = fs10.readFileSync(params.flowPath, "utf8");
18395
18530
  const fmMatch = flowContent.match(/^---\n([\s\S]*?)\n---\n?/);
18396
18531
  const stepsBody = fmMatch ? flowContent.slice(fmMatch[0].length) : flowContent;
18397
18532
  const steps = yaml2.parse(stepsBody);
@@ -18416,7 +18551,7 @@ var skill5 = {
18416
18551
  });
18417
18552
  const driver = new SootSimBridgeFlowRunner2(bridge, {
18418
18553
  screenshotDir: context.outputDir,
18419
- flowDir: path9.dirname(path9.resolve(params.flowPath)),
18554
+ flowDir: path10.dirname(path10.resolve(params.flowPath)),
18420
18555
  simId,
18421
18556
  recordingOutputDir: params.record ? context.outputDir : void 0
18422
18557
  });
@@ -18438,7 +18573,7 @@ var skill5 = {
18438
18573
  simId,
18439
18574
  videoPath: videoPath || void 0
18440
18575
  },
18441
- artifacts: videoPath ? [{ type: "video", name: path9.basename(videoPath), path: videoPath }] : void 0
18576
+ artifacts: videoPath ? [{ type: "video", name: path10.basename(videoPath), path: videoPath }] : void 0
18442
18577
  };
18443
18578
  } finally {
18444
18579
  try {
@@ -18486,21 +18621,21 @@ var skill6 = {
18486
18621
  },
18487
18622
  async execute(params, context) {
18488
18623
  const { chromium } = await import("playwright");
18489
- const path9 = await import("path");
18490
- const fs9 = await import("fs");
18624
+ const path10 = await import("path");
18625
+ const fs10 = await import("fs");
18491
18626
  const browser = await chromium.launch({ channel: "chrome", headless: true });
18492
18627
  const page = await browser.newPage({ viewport: { width: 500, height: 900 } });
18493
18628
  try {
18494
18629
  await page.goto(context.url, { waitUntil: "networkidle" });
18495
18630
  await page.waitForTimeout(2e3);
18496
- const currentPath = path9.join(context.outputDir, `${params.name}-current.png`);
18497
- fs9.mkdirSync(path9.dirname(currentPath), { recursive: true });
18631
+ const currentPath = path10.join(context.outputDir, `${params.name}-current.png`);
18632
+ fs10.mkdirSync(path10.dirname(currentPath), { recursive: true });
18498
18633
  await page.screenshot({ path: currentPath });
18499
18634
  try {
18500
18635
  const { PNG } = await import("pngjs");
18501
18636
  const pixelmatch = (await import("pixelmatch")).default;
18502
- const baseline = PNG.sync.read(fs9.readFileSync(params.baseline));
18503
- const current = PNG.sync.read(fs9.readFileSync(currentPath));
18637
+ const baseline = PNG.sync.read(fs10.readFileSync(params.baseline));
18638
+ const current = PNG.sync.read(fs10.readFileSync(currentPath));
18504
18639
  const { width, height } = baseline;
18505
18640
  const diff = new PNG({ width, height });
18506
18641
  const numDiffPixels = pixelmatch(
@@ -18511,8 +18646,8 @@ var skill6 = {
18511
18646
  height,
18512
18647
  { threshold: params.threshold || 0.1 }
18513
18648
  );
18514
- const diffPath = path9.join(context.outputDir, `${params.name}-diff.png`);
18515
- fs9.writeFileSync(diffPath, PNG.sync.write(diff));
18649
+ const diffPath = path10.join(context.outputDir, `${params.name}-diff.png`);
18650
+ fs10.writeFileSync(diffPath, PNG.sync.write(diff));
18516
18651
  const totalPixels = width * height;
18517
18652
  const diffPercent = (numDiffPixels / totalPixels * 100).toFixed(2);
18518
18653
  return {
@@ -18576,10 +18711,10 @@ var skillRegistry = {
18576
18711
  },
18577
18712
  // load skills from a project manifest (sootsim-skills.json)
18578
18713
  async loadFromManifest(projectDir) {
18579
- const manifestPath = path8.join(projectDir, "sootsim-skills.json");
18580
- if (!fs8.existsSync(manifestPath)) return;
18714
+ const manifestPath = path9.join(projectDir, "sootsim-skills.json");
18715
+ if (!fs9.existsSync(manifestPath)) return;
18581
18716
  try {
18582
- const manifest = JSON.parse(fs8.readFileSync(manifestPath, "utf8"));
18717
+ const manifest = JSON.parse(fs9.readFileSync(manifestPath, "utf8"));
18583
18718
  if (Array.isArray(manifest.skills)) {
18584
18719
  for (const entry of manifest.skills) {
18585
18720
  if (typeof entry === "string") {
@@ -18590,7 +18725,7 @@ var skillRegistry = {
18590
18725
  }
18591
18726
  } else if (entry.file) {
18592
18727
  try {
18593
- const mod = await import(path8.resolve(projectDir, entry.file));
18728
+ const mod = await import(path9.resolve(projectDir, entry.file));
18594
18729
  if (mod.skill) this.register(mod.skill);
18595
18730
  } catch {
18596
18731
  }
@@ -18603,10 +18738,10 @@ var skillRegistry = {
18603
18738
  // auto-discover skills based on project dependencies
18604
18739
  suggestSkills(projectDir) {
18605
18740
  const suggestions = [];
18606
- const pkgPath = path8.join(projectDir, "package.json");
18607
- if (!fs8.existsSync(pkgPath)) return suggestions;
18741
+ const pkgPath = path9.join(projectDir, "package.json");
18742
+ if (!fs9.existsSync(pkgPath)) return suggestions;
18608
18743
  try {
18609
- const pkg = JSON.parse(fs8.readFileSync(pkgPath, "utf8"));
18744
+ const pkg = JSON.parse(fs9.readFileSync(pkgPath, "utf8"));
18610
18745
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
18611
18746
  if (deps["detox"] || deps["maestro"]) {
18612
18747
  suggestions.push("test-flow");