agent-relay 3.2.2 → 3.2.4

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 (246) hide show
  1. package/bin/agent-relay-broker-darwin-arm64 +0 -0
  2. package/bin/agent-relay-broker-darwin-x64 +0 -0
  3. package/bin/agent-relay-broker-linux-arm64 +0 -0
  4. package/bin/agent-relay-broker-linux-x64 +0 -0
  5. package/dist/index.cjs +1358 -941
  6. package/dist/src/cli/commands/agent-management.d.ts +2 -2
  7. package/dist/src/cli/commands/agent-management.d.ts.map +1 -1
  8. package/dist/src/cli/commands/agent-management.js +41 -240
  9. package/dist/src/cli/commands/agent-management.js.map +1 -1
  10. package/dist/src/cli/commands/messaging.d.ts +1 -1
  11. package/dist/src/cli/commands/messaging.d.ts.map +1 -1
  12. package/dist/src/cli/commands/messaging.js +14 -5
  13. package/dist/src/cli/commands/messaging.js.map +1 -1
  14. package/dist/src/cli/lib/agent-management-listing.d.ts +4 -1
  15. package/dist/src/cli/lib/agent-management-listing.d.ts.map +1 -1
  16. package/dist/src/cli/lib/agent-management-listing.js +27 -2
  17. package/dist/src/cli/lib/agent-management-listing.js.map +1 -1
  18. package/package.json +11 -10
  19. package/packages/acp-bridge/package.json +2 -2
  20. package/packages/config/package.json +1 -1
  21. package/packages/hooks/package.json +4 -4
  22. package/packages/memory/package.json +2 -2
  23. package/packages/openclaw/package.json +2 -2
  24. package/packages/policy/package.json +2 -2
  25. package/packages/sdk/ADAPTER_REVIEW.md +109 -0
  26. package/packages/sdk/dist/client.d.ts +66 -0
  27. package/packages/sdk/dist/client.d.ts.map +1 -1
  28. package/packages/sdk/dist/client.js +230 -0
  29. package/packages/sdk/dist/client.js.map +1 -1
  30. package/packages/sdk/dist/communicate/a2a-bridge.d.ts +25 -0
  31. package/packages/sdk/dist/communicate/a2a-bridge.d.ts.map +1 -0
  32. package/packages/sdk/dist/communicate/a2a-bridge.js +89 -0
  33. package/packages/sdk/dist/communicate/a2a-bridge.js.map +1 -0
  34. package/packages/sdk/dist/communicate/a2a-server.d.ts +31 -0
  35. package/packages/sdk/dist/communicate/a2a-server.d.ts.map +1 -0
  36. package/packages/sdk/dist/communicate/a2a-server.js +220 -0
  37. package/packages/sdk/dist/communicate/a2a-server.js.map +1 -0
  38. package/packages/sdk/dist/communicate/a2a-transport.d.ts +48 -0
  39. package/packages/sdk/dist/communicate/a2a-transport.d.ts.map +1 -0
  40. package/packages/sdk/dist/communicate/a2a-transport.js +302 -0
  41. package/packages/sdk/dist/communicate/a2a-transport.js.map +1 -0
  42. package/packages/sdk/dist/communicate/a2a-types.d.ts +107 -0
  43. package/packages/sdk/dist/communicate/a2a-types.d.ts.map +1 -0
  44. package/packages/sdk/dist/communicate/a2a-types.js +209 -0
  45. package/packages/sdk/dist/communicate/a2a-types.js.map +1 -0
  46. package/packages/sdk/dist/communicate/adapters/claude-sdk.d.ts +28 -0
  47. package/packages/sdk/dist/communicate/adapters/claude-sdk.d.ts.map +1 -0
  48. package/packages/sdk/dist/communicate/adapters/claude-sdk.js +47 -0
  49. package/packages/sdk/dist/communicate/adapters/claude-sdk.js.map +1 -0
  50. package/packages/sdk/dist/communicate/adapters/crewai.d.ts +42 -0
  51. package/packages/sdk/dist/communicate/adapters/crewai.d.ts.map +1 -0
  52. package/packages/sdk/dist/communicate/adapters/crewai.js +95 -0
  53. package/packages/sdk/dist/communicate/adapters/crewai.js.map +1 -0
  54. package/packages/sdk/dist/communicate/adapters/google-adk.d.ts +53 -0
  55. package/packages/sdk/dist/communicate/adapters/google-adk.d.ts.map +1 -0
  56. package/packages/sdk/dist/communicate/adapters/google-adk.js +77 -0
  57. package/packages/sdk/dist/communicate/adapters/google-adk.js.map +1 -0
  58. package/packages/sdk/dist/communicate/adapters/index.d.ts +7 -0
  59. package/packages/sdk/dist/communicate/adapters/index.d.ts.map +1 -0
  60. package/packages/sdk/dist/communicate/adapters/index.js +7 -0
  61. package/packages/sdk/dist/communicate/adapters/index.js.map +1 -0
  62. package/packages/sdk/dist/communicate/adapters/langgraph.d.ts +40 -0
  63. package/packages/sdk/dist/communicate/adapters/langgraph.d.ts.map +1 -0
  64. package/packages/sdk/dist/communicate/adapters/langgraph.js +77 -0
  65. package/packages/sdk/dist/communicate/adapters/langgraph.js.map +1 -0
  66. package/packages/sdk/dist/communicate/adapters/openai-agents.d.ts +25 -0
  67. package/packages/sdk/dist/communicate/adapters/openai-agents.d.ts.map +1 -0
  68. package/packages/sdk/dist/communicate/adapters/openai-agents.js +70 -0
  69. package/packages/sdk/dist/communicate/adapters/openai-agents.js.map +1 -0
  70. package/packages/sdk/dist/communicate/adapters/pi.d.ts +45 -0
  71. package/packages/sdk/dist/communicate/adapters/pi.d.ts.map +1 -0
  72. package/packages/sdk/dist/communicate/adapters/pi.js +59 -0
  73. package/packages/sdk/dist/communicate/adapters/pi.js.map +1 -0
  74. package/packages/sdk/dist/communicate/core.d.ts +58 -0
  75. package/packages/sdk/dist/communicate/core.d.ts.map +1 -0
  76. package/packages/sdk/dist/communicate/core.js +128 -0
  77. package/packages/sdk/dist/communicate/core.js.map +1 -0
  78. package/packages/sdk/dist/communicate/index.d.ts +4 -0
  79. package/packages/sdk/dist/communicate/index.d.ts.map +1 -0
  80. package/packages/sdk/dist/communicate/index.js +4 -0
  81. package/packages/sdk/dist/communicate/index.js.map +1 -0
  82. package/packages/sdk/dist/communicate/transport.d.ts +36 -0
  83. package/packages/sdk/dist/communicate/transport.d.ts.map +1 -0
  84. package/packages/sdk/dist/communicate/transport.js +371 -0
  85. package/packages/sdk/dist/communicate/transport.js.map +1 -0
  86. package/packages/sdk/dist/communicate/types.d.ts +58 -0
  87. package/packages/sdk/dist/communicate/types.d.ts.map +1 -0
  88. package/packages/sdk/dist/communicate/types.js +66 -0
  89. package/packages/sdk/dist/communicate/types.js.map +1 -0
  90. package/packages/sdk/dist/workflows/builder.d.ts +35 -5
  91. package/packages/sdk/dist/workflows/builder.d.ts.map +1 -1
  92. package/packages/sdk/dist/workflows/builder.js +81 -7
  93. package/packages/sdk/dist/workflows/builder.js.map +1 -1
  94. package/packages/sdk/dist/workflows/cli.js +14 -1
  95. package/packages/sdk/dist/workflows/cli.js.map +1 -1
  96. package/packages/sdk/dist/workflows/runner.d.ts +10 -2
  97. package/packages/sdk/dist/workflows/runner.d.ts.map +1 -1
  98. package/packages/sdk/dist/workflows/runner.js +95 -1
  99. package/packages/sdk/dist/workflows/runner.js.map +1 -1
  100. package/packages/sdk/dist/workflows/types.d.ts +11 -0
  101. package/packages/sdk/dist/workflows/types.d.ts.map +1 -1
  102. package/packages/sdk/examples/communicate/claude_sdk_example.ts +5 -0
  103. package/packages/sdk/examples/communicate/pi_example.ts +8 -0
  104. package/packages/sdk/package.json +48 -2
  105. package/packages/sdk/src/__tests__/builder-deterministic.test.ts +132 -0
  106. package/packages/sdk/src/__tests__/communicate/a2a-bridge.test.ts +211 -0
  107. package/packages/sdk/src/__tests__/communicate/a2a-server.test.ts +359 -0
  108. package/packages/sdk/src/__tests__/communicate/a2a-transport.test.ts +537 -0
  109. package/packages/sdk/src/__tests__/communicate/a2a-types.test.ts +297 -0
  110. package/packages/sdk/src/__tests__/communicate/adapters/claude-sdk.test.ts +163 -0
  111. package/packages/sdk/src/__tests__/communicate/adapters/crewai.test.ts +219 -0
  112. package/packages/sdk/src/__tests__/communicate/adapters/e2e-crewai.test.ts +101 -0
  113. package/packages/sdk/src/__tests__/communicate/adapters/e2e-google-adk.test.ts +166 -0
  114. package/packages/sdk/src/__tests__/communicate/adapters/e2e-langgraph.test.ts +181 -0
  115. package/packages/sdk/src/__tests__/communicate/adapters/e2e-openai-agents.test.ts +137 -0
  116. package/packages/sdk/src/__tests__/communicate/adapters/e2e-pi.test.ts +140 -0
  117. package/packages/sdk/src/__tests__/communicate/adapters/google-adk.test.ts +200 -0
  118. package/packages/sdk/src/__tests__/communicate/adapters/langgraph.test.ts +162 -0
  119. package/packages/sdk/src/__tests__/communicate/adapters/openai-agents.test.ts +166 -0
  120. package/packages/sdk/src/__tests__/communicate/adapters/pi.test.ts +140 -0
  121. package/packages/sdk/src/__tests__/communicate/core.test.ts +574 -0
  122. package/packages/sdk/src/__tests__/communicate/integration/cross-framework.test.ts +353 -0
  123. package/packages/sdk/src/__tests__/communicate/transport.test.ts +613 -0
  124. package/packages/sdk/src/__tests__/start-from.test.ts +346 -0
  125. package/packages/sdk/src/client.ts +301 -0
  126. package/packages/sdk/src/communicate/a2a-bridge.ts +111 -0
  127. package/packages/sdk/src/communicate/a2a-server.ts +277 -0
  128. package/packages/sdk/src/communicate/a2a-transport.ts +395 -0
  129. package/packages/sdk/src/communicate/a2a-types.ts +338 -0
  130. package/packages/sdk/src/communicate/adapters/claude-sdk.ts +85 -0
  131. package/packages/sdk/src/communicate/adapters/crewai.ts +141 -0
  132. package/packages/sdk/src/communicate/adapters/google-adk.ts +139 -0
  133. package/packages/sdk/src/communicate/adapters/index.ts +6 -0
  134. package/packages/sdk/src/communicate/adapters/langgraph.ts +112 -0
  135. package/packages/sdk/src/communicate/adapters/openai-agents.ts +113 -0
  136. package/packages/sdk/src/communicate/adapters/pi.ts +105 -0
  137. package/packages/sdk/src/communicate/core.ts +157 -0
  138. package/packages/sdk/src/communicate/index.ts +3 -0
  139. package/packages/sdk/src/communicate/transport.ts +489 -0
  140. package/packages/sdk/src/communicate/types.ts +106 -0
  141. package/packages/sdk/src/examples/workflows/fix-dashboard-user-registration.yaml +182 -0
  142. package/packages/sdk/src/workflows/builder.ts +97 -9
  143. package/packages/sdk/src/workflows/cli.ts +16 -1
  144. package/packages/sdk/src/workflows/runner.ts +110 -1
  145. package/packages/sdk/src/workflows/types.ts +14 -0
  146. package/packages/sdk/tsconfig.build.json +1 -7
  147. package/packages/sdk/tsconfig.json +1 -7
  148. package/packages/sdk-py/README.md +67 -25
  149. package/packages/sdk-py/examples/communicate/agno_example.py +8 -0
  150. package/packages/sdk-py/examples/communicate/claude_sdk_example.py +6 -0
  151. package/packages/sdk-py/examples/communicate/crewai_example.py +7 -0
  152. package/packages/sdk-py/examples/communicate/google_adk_example.py +7 -0
  153. package/packages/sdk-py/examples/communicate/openai_agents_example.py +8 -0
  154. package/packages/sdk-py/examples/communicate/swarms_example.py +7 -0
  155. package/packages/sdk-py/pyproject.toml +12 -1
  156. package/packages/sdk-py/src/agent_relay/__init__.py +8 -0
  157. package/packages/sdk-py/src/agent_relay/builder.py +65 -26
  158. package/packages/sdk-py/src/agent_relay/communicate/__init__.py +6 -0
  159. package/packages/sdk-py/src/agent_relay/communicate/a2a_bridge.py +138 -0
  160. package/packages/sdk-py/src/agent_relay/communicate/a2a_server.py +242 -0
  161. package/packages/sdk-py/src/agent_relay/communicate/a2a_transport.py +366 -0
  162. package/packages/sdk-py/src/agent_relay/communicate/a2a_types.py +294 -0
  163. package/packages/sdk-py/src/agent_relay/communicate/adapters/__init__.py +10 -0
  164. package/packages/sdk-py/src/agent_relay/communicate/adapters/agno.py +74 -0
  165. package/packages/sdk-py/src/agent_relay/communicate/adapters/claude_sdk.py +78 -0
  166. package/packages/sdk-py/src/agent_relay/communicate/adapters/crewai.py +143 -0
  167. package/packages/sdk-py/src/agent_relay/communicate/adapters/google_adk.py +69 -0
  168. package/packages/sdk-py/src/agent_relay/communicate/adapters/openai_agents.py +86 -0
  169. package/packages/sdk-py/src/agent_relay/communicate/adapters/pi.py +175 -0
  170. package/packages/sdk-py/src/agent_relay/communicate/adapters/swarms.py +44 -0
  171. package/packages/sdk-py/src/agent_relay/communicate/core.py +293 -0
  172. package/packages/sdk-py/src/agent_relay/communicate/transport.py +502 -0
  173. package/packages/sdk-py/src/agent_relay/communicate/types.py +89 -0
  174. package/packages/sdk-py/src/agent_relay/types.py +2 -1
  175. package/packages/sdk-py/tests/communicate/__init__.py +0 -0
  176. package/packages/sdk-py/tests/communicate/adapters/__init__.py +0 -0
  177. package/packages/sdk-py/tests/communicate/adapters/e2e_test_agno.py +154 -0
  178. package/packages/sdk-py/tests/communicate/adapters/e2e_test_claude_sdk.py +428 -0
  179. package/packages/sdk-py/tests/communicate/adapters/e2e_test_crewai.py +234 -0
  180. package/packages/sdk-py/tests/communicate/adapters/e2e_test_google_adk.py +182 -0
  181. package/packages/sdk-py/tests/communicate/adapters/e2e_test_langgraph.py +262 -0
  182. package/packages/sdk-py/tests/communicate/adapters/e2e_test_openai_agents.py +88 -0
  183. package/packages/sdk-py/tests/communicate/adapters/e2e_test_pi.py +156 -0
  184. package/packages/sdk-py/tests/communicate/adapters/e2e_test_swarms.py +239 -0
  185. package/packages/sdk-py/tests/communicate/adapters/test_agno.py +140 -0
  186. package/packages/sdk-py/tests/communicate/adapters/test_claude_sdk.py +147 -0
  187. package/packages/sdk-py/tests/communicate/adapters/test_crewai.py +136 -0
  188. package/packages/sdk-py/tests/communicate/adapters/test_google_adk.py +125 -0
  189. package/packages/sdk-py/tests/communicate/adapters/test_openai_agents.py +99 -0
  190. package/packages/sdk-py/tests/communicate/adapters/test_pi.py +270 -0
  191. package/packages/sdk-py/tests/communicate/adapters/test_swarms.py +113 -0
  192. package/packages/sdk-py/tests/communicate/conftest.py +555 -0
  193. package/packages/sdk-py/tests/communicate/integration/__init__.py +1 -0
  194. package/packages/sdk-py/tests/communicate/integration/test_cross_framework.py +331 -0
  195. package/packages/sdk-py/tests/communicate/integration/test_end_to_end.py +151 -0
  196. package/packages/sdk-py/tests/communicate/test_a2a_bridge.py +363 -0
  197. package/packages/sdk-py/tests/communicate/test_a2a_server.py +346 -0
  198. package/packages/sdk-py/tests/communicate/test_a2a_transport.py +561 -0
  199. package/packages/sdk-py/tests/communicate/test_a2a_types.py +342 -0
  200. package/packages/sdk-py/tests/communicate/test_auto_detect.py +67 -0
  201. package/packages/sdk-py/tests/communicate/test_core.py +331 -0
  202. package/packages/sdk-py/tests/communicate/test_transport.py +373 -0
  203. package/packages/sdk-py/tests/communicate/test_types.py +285 -0
  204. package/packages/sdk-py/tests/test_builder_deterministic.py +118 -0
  205. package/packages/telemetry/package.json +1 -1
  206. package/packages/trajectory/package.json +2 -2
  207. package/packages/user-directory/package.json +2 -2
  208. package/packages/utils/package.json +2 -2
  209. package/packages/sdk/dist/__tests__/completion-pipeline.test.d.ts +0 -14
  210. package/packages/sdk/dist/__tests__/completion-pipeline.test.d.ts.map +0 -1
  211. package/packages/sdk/dist/__tests__/completion-pipeline.test.js +0 -1476
  212. package/packages/sdk/dist/__tests__/completion-pipeline.test.js.map +0 -1
  213. package/packages/sdk/dist/__tests__/contract-fixtures.test.d.ts +0 -2
  214. package/packages/sdk/dist/__tests__/contract-fixtures.test.d.ts.map +0 -1
  215. package/packages/sdk/dist/__tests__/contract-fixtures.test.js +0 -152
  216. package/packages/sdk/dist/__tests__/contract-fixtures.test.js.map +0 -1
  217. package/packages/sdk/dist/__tests__/e2e-owner-review.test.d.ts +0 -16
  218. package/packages/sdk/dist/__tests__/e2e-owner-review.test.d.ts.map +0 -1
  219. package/packages/sdk/dist/__tests__/e2e-owner-review.test.js +0 -640
  220. package/packages/sdk/dist/__tests__/e2e-owner-review.test.js.map +0 -1
  221. package/packages/sdk/dist/__tests__/facade.test.d.ts +0 -2
  222. package/packages/sdk/dist/__tests__/facade.test.d.ts.map +0 -1
  223. package/packages/sdk/dist/__tests__/facade.test.js +0 -305
  224. package/packages/sdk/dist/__tests__/facade.test.js.map +0 -1
  225. package/packages/sdk/dist/__tests__/integration.test.d.ts +0 -2
  226. package/packages/sdk/dist/__tests__/integration.test.d.ts.map +0 -1
  227. package/packages/sdk/dist/__tests__/integration.test.js +0 -205
  228. package/packages/sdk/dist/__tests__/integration.test.js.map +0 -1
  229. package/packages/sdk/dist/__tests__/pty.test.d.ts +0 -2
  230. package/packages/sdk/dist/__tests__/pty.test.d.ts.map +0 -1
  231. package/packages/sdk/dist/__tests__/pty.test.js +0 -20
  232. package/packages/sdk/dist/__tests__/pty.test.js.map +0 -1
  233. package/packages/sdk/dist/__tests__/quickstart.test.d.ts +0 -2
  234. package/packages/sdk/dist/__tests__/quickstart.test.d.ts.map +0 -1
  235. package/packages/sdk/dist/__tests__/quickstart.test.js +0 -176
  236. package/packages/sdk/dist/__tests__/quickstart.test.js.map +0 -1
  237. package/packages/sdk/dist/__tests__/spawn-from-env.test.d.ts +0 -2
  238. package/packages/sdk/dist/__tests__/spawn-from-env.test.d.ts.map +0 -1
  239. package/packages/sdk/dist/__tests__/spawn-from-env.test.js +0 -222
  240. package/packages/sdk/dist/__tests__/spawn-from-env.test.js.map +0 -1
  241. package/packages/sdk/dist/__tests__/unit.test.d.ts +0 -2
  242. package/packages/sdk/dist/__tests__/unit.test.d.ts.map +0 -1
  243. package/packages/sdk/dist/__tests__/unit.test.js +0 -357
  244. package/packages/sdk/dist/__tests__/unit.test.js.map +0 -1
  245. package/packages/sdk-py/agent_relay/__init__.py +0 -21
  246. package/packages/sdk-py/agent_relay/models.py +0 -398
package/dist/index.cjs CHANGED
@@ -35,13 +35,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
35
35
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
36
36
 
37
37
  // packages/config/src/bridge-utils.ts
38
- var import_node_child_process2, import_node_util, execAsync;
38
+ var import_node_child_process, import_node_util, execAsync;
39
39
  var init_bridge_utils = __esm({
40
40
  "packages/config/src/bridge-utils.ts"() {
41
41
  "use strict";
42
- import_node_child_process2 = require("node:child_process");
42
+ import_node_child_process = require("node:child_process");
43
43
  import_node_util = require("node:util");
44
- execAsync = (0, import_node_util.promisify)(import_node_child_process2.exec);
44
+ execAsync = (0, import_node_util.promisify)(import_node_child_process.exec);
45
45
  }
46
46
  });
47
47
 
@@ -6885,14 +6885,14 @@ var require_parser = __commonJS({
6885
6885
  case "scalar":
6886
6886
  case "single-quoted-scalar":
6887
6887
  case "double-quoted-scalar": {
6888
- const fs9 = this.flowScalar(this.type);
6888
+ const fs10 = this.flowScalar(this.type);
6889
6889
  if (atNextItem || it.value) {
6890
- map2.items.push({ start, key: fs9, sep: [] });
6890
+ map2.items.push({ start, key: fs10, sep: [] });
6891
6891
  this.onKeyLine = true;
6892
6892
  } else if (it.sep) {
6893
- this.stack.push(fs9);
6893
+ this.stack.push(fs10);
6894
6894
  } else {
6895
- Object.assign(it, { key: fs9, sep: [] });
6895
+ Object.assign(it, { key: fs10, sep: [] });
6896
6896
  this.onKeyLine = true;
6897
6897
  }
6898
6898
  return;
@@ -7020,13 +7020,13 @@ var require_parser = __commonJS({
7020
7020
  case "scalar":
7021
7021
  case "single-quoted-scalar":
7022
7022
  case "double-quoted-scalar": {
7023
- const fs9 = this.flowScalar(this.type);
7023
+ const fs10 = this.flowScalar(this.type);
7024
7024
  if (!it || it.value)
7025
- fc.items.push({ start: [], key: fs9, sep: [] });
7025
+ fc.items.push({ start: [], key: fs10, sep: [] });
7026
7026
  else if (it.sep)
7027
- this.stack.push(fs9);
7027
+ this.stack.push(fs10);
7028
7028
  else
7029
- Object.assign(it, { key: fs9, sep: [] });
7029
+ Object.assign(it, { key: fs10, sep: [] });
7030
7030
  return;
7031
7031
  }
7032
7032
  case "flow-map-end":
@@ -7467,11 +7467,11 @@ var init_types = __esm({
7467
7467
  });
7468
7468
 
7469
7469
  // packages/memory/dist/adapters/inmemory.js
7470
- var import_node_crypto10, InMemoryAdapter;
7470
+ var import_node_crypto11, InMemoryAdapter;
7471
7471
  var init_inmemory = __esm({
7472
7472
  "packages/memory/dist/adapters/inmemory.js"() {
7473
7473
  "use strict";
7474
- import_node_crypto10 = require("node:crypto");
7474
+ import_node_crypto11 = require("node:crypto");
7475
7475
  InMemoryAdapter = class {
7476
7476
  type = "inmemory";
7477
7477
  memories = /* @__PURE__ */ new Map();
@@ -7486,7 +7486,7 @@ var init_inmemory = __esm({
7486
7486
  async init() {
7487
7487
  }
7488
7488
  async add(content, options) {
7489
- const id = (0, import_node_crypto10.randomUUID)();
7489
+ const id = (0, import_node_crypto11.randomUUID)();
7490
7490
  const now = Date.now();
7491
7491
  const entry = {
7492
7492
  id,
@@ -8825,6 +8825,7 @@ __export(index_exports, {
8825
8825
  HOOK_ABI_VERSION: () => HOOK_ABI_VERSION,
8826
8826
  HookEmitter: () => HookEmitter,
8827
8827
  HookRegistry: () => HookRegistry,
8828
+ HttpAgentRelayClient: () => HttpAgentRelayClient,
8828
8829
  InMemoryAdapter: () => InMemoryAdapter,
8829
8830
  InMemoryWorkflowDb: () => InMemoryWorkflowDb,
8830
8831
  JsonFileWorkflowDb: () => JsonFileWorkflowDb,
@@ -8951,623 +8952,12 @@ var PROTOCOL_VERSION = 1;
8951
8952
 
8952
8953
  // packages/sdk/dist/client.js
8953
8954
  var import_node_events = require("node:events");
8954
- var import_node_child_process = require("node:child_process");
8955
+ var import_node_child_process2 = require("node:child_process");
8955
8956
  var import_node_readline = require("node:readline");
8956
- var import_node_fs = __toESM(require("node:fs"), 1);
8957
- var import_node_os = __toESM(require("node:os"), 1);
8958
- var import_node_path = __toESM(require("node:path"), 1);
8957
+ var import_node_fs2 = __toESM(require("node:fs"), 1);
8958
+ var import_node_os3 = __toESM(require("node:os"), 1);
8959
+ var import_node_path3 = __toESM(require("node:path"), 1);
8959
8960
  var import_node_url = require("node:url");
8960
- var AgentRelayProtocolError = class extends Error {
8961
- code;
8962
- retryable;
8963
- data;
8964
- constructor(payload) {
8965
- super(payload.message);
8966
- this.name = "AgentRelayProtocolError";
8967
- this.code = payload.code;
8968
- this.retryable = payload.retryable;
8969
- this.data = payload.data;
8970
- }
8971
- };
8972
- var AgentRelayProcessError = class extends Error {
8973
- constructor(message) {
8974
- super(message);
8975
- this.name = "AgentRelayProcessError";
8976
- }
8977
- };
8978
- function isHeadlessProvider(value) {
8979
- return value === "claude" || value === "opencode";
8980
- }
8981
- var AgentRelayClient = class _AgentRelayClient {
8982
- options;
8983
- child;
8984
- stdoutRl;
8985
- stderrRl;
8986
- lastStderrLine;
8987
- requestSeq = 0;
8988
- pending = /* @__PURE__ */ new Map();
8989
- startingPromise;
8990
- eventListeners = /* @__PURE__ */ new Set();
8991
- stderrListeners = /* @__PURE__ */ new Set();
8992
- eventBuffer = [];
8993
- maxBufferSize = 1e3;
8994
- exitPromise;
8995
- /** The workspace key returned by the broker in its hello_ack response. */
8996
- workspaceKey;
8997
- constructor(options = {}) {
8998
- this.options = {
8999
- binaryPath: options.binaryPath ?? resolveDefaultBinaryPath(),
9000
- binaryArgs: options.binaryArgs ?? [],
9001
- brokerName: options.brokerName ?? (import_node_path.default.basename(options.cwd ?? process.cwd()) || "project"),
9002
- channels: options.channels ?? ["general"],
9003
- cwd: options.cwd ?? process.cwd(),
9004
- env: options.env ?? process.env,
9005
- requestTimeoutMs: options.requestTimeoutMs ?? 1e4,
9006
- shutdownTimeoutMs: options.shutdownTimeoutMs ?? 3e3,
9007
- clientName: options.clientName ?? "@agent-relay/sdk",
9008
- clientVersion: options.clientVersion ?? "0.1.0"
9009
- };
9010
- }
9011
- static async start(options = {}) {
9012
- const client = new _AgentRelayClient(options);
9013
- await client.start();
9014
- return client;
9015
- }
9016
- onEvent(listener) {
9017
- this.eventListeners.add(listener);
9018
- return () => {
9019
- this.eventListeners.delete(listener);
9020
- };
9021
- }
9022
- queryEvents(filter) {
9023
- let events = [...this.eventBuffer];
9024
- if (filter?.kind) {
9025
- events = events.filter((event) => event.kind === filter.kind);
9026
- }
9027
- if (filter?.name) {
9028
- events = events.filter((event) => "name" in event && event.name === filter.name);
9029
- }
9030
- const since = filter?.since;
9031
- if (since !== void 0) {
9032
- events = events.filter((event) => "timestamp" in event && typeof event.timestamp === "number" && event.timestamp >= since);
9033
- }
9034
- const limit = filter?.limit;
9035
- if (limit !== void 0) {
9036
- events = events.slice(-limit);
9037
- }
9038
- return events;
9039
- }
9040
- getLastEvent(kind, name) {
9041
- for (let i = this.eventBuffer.length - 1; i >= 0; i -= 1) {
9042
- const event = this.eventBuffer[i];
9043
- if (event.kind === kind && (!name || "name" in event && event.name === name)) {
9044
- return event;
9045
- }
9046
- }
9047
- return void 0;
9048
- }
9049
- onBrokerStderr(listener) {
9050
- this.stderrListeners.add(listener);
9051
- return () => {
9052
- this.stderrListeners.delete(listener);
9053
- };
9054
- }
9055
- get brokerPid() {
9056
- return this.child?.pid;
9057
- }
9058
- async start() {
9059
- if (this.child) {
9060
- return;
9061
- }
9062
- if (this.startingPromise) {
9063
- return this.startingPromise;
9064
- }
9065
- this.startingPromise = this.startInternal();
9066
- try {
9067
- await this.startingPromise;
9068
- } finally {
9069
- this.startingPromise = void 0;
9070
- }
9071
- }
9072
- /**
9073
- * Pre-register a batch of agents with Relaycast before their steps execute.
9074
- * The broker warms its token cache in parallel; subsequent spawn_agent calls
9075
- * hit the cache rather than waiting on individual HTTP registrations.
9076
- * Fire-and-forget from the caller's perspective — broker responds immediately
9077
- * and registers in the background.
9078
- */
9079
- async preflightAgents(agents) {
9080
- if (agents.length === 0)
9081
- return;
9082
- await this.start();
9083
- await this.requestOk("preflight_agents", { agents });
9084
- }
9085
- async spawnPty(input) {
9086
- await this.start();
9087
- const args = buildPtyArgsWithModel(input.cli, input.args ?? [], input.model);
9088
- const agent = {
9089
- name: input.name,
9090
- runtime: "pty",
9091
- cli: input.cli,
9092
- args,
9093
- channels: input.channels ?? [],
9094
- model: input.model,
9095
- cwd: input.cwd ?? this.options.cwd,
9096
- team: input.team,
9097
- shadow_of: input.shadowOf,
9098
- shadow_mode: input.shadowMode,
9099
- restart_policy: input.restartPolicy
9100
- };
9101
- const result = await this.requestOk("spawn_agent", {
9102
- agent,
9103
- ...input.task != null ? { initial_task: input.task } : {},
9104
- ...input.idleThresholdSecs != null ? { idle_threshold_secs: input.idleThresholdSecs } : {},
9105
- ...input.continueFrom != null ? { continue_from: input.continueFrom } : {},
9106
- ...input.skipRelayPrompt != null ? { skip_relay_prompt: input.skipRelayPrompt } : {}
9107
- });
9108
- return result;
9109
- }
9110
- async spawnHeadless(input) {
9111
- await this.start();
9112
- const agent = {
9113
- name: input.name,
9114
- runtime: "headless",
9115
- provider: input.provider,
9116
- args: input.args ?? [],
9117
- channels: input.channels ?? []
9118
- };
9119
- const result = await this.requestOk("spawn_agent", {
9120
- agent,
9121
- ...input.task != null ? { initial_task: input.task } : {},
9122
- ...input.skipRelayPrompt != null ? { skip_relay_prompt: input.skipRelayPrompt } : {}
9123
- });
9124
- return result;
9125
- }
9126
- async spawnProvider(input) {
9127
- const transport = input.transport ?? (input.provider === "opencode" ? "headless" : "pty");
9128
- if (transport === "headless") {
9129
- if (!isHeadlessProvider(input.provider)) {
9130
- throw new AgentRelayProcessError(`provider '${input.provider}' does not support headless transport (supported: claude, opencode)`);
9131
- }
9132
- return this.spawnHeadless({
9133
- name: input.name,
9134
- provider: input.provider,
9135
- args: input.args,
9136
- channels: input.channels,
9137
- task: input.task,
9138
- skipRelayPrompt: input.skipRelayPrompt
9139
- });
9140
- }
9141
- return this.spawnPty({
9142
- name: input.name,
9143
- cli: input.provider,
9144
- args: input.args,
9145
- channels: input.channels,
9146
- task: input.task,
9147
- model: input.model,
9148
- cwd: input.cwd,
9149
- team: input.team,
9150
- shadowOf: input.shadowOf,
9151
- shadowMode: input.shadowMode,
9152
- idleThresholdSecs: input.idleThresholdSecs,
9153
- restartPolicy: input.restartPolicy,
9154
- continueFrom: input.continueFrom,
9155
- skipRelayPrompt: input.skipRelayPrompt
9156
- });
9157
- }
9158
- async spawnClaude(input) {
9159
- return this.spawnProvider({ ...input, provider: "claude" });
9160
- }
9161
- async spawnOpencode(input) {
9162
- return this.spawnProvider({ ...input, provider: "opencode" });
9163
- }
9164
- async release(name, reason) {
9165
- await this.start();
9166
- return this.requestOk("release_agent", { name, reason });
9167
- }
9168
- async sendInput(name, data) {
9169
- await this.start();
9170
- return this.requestOk("send_input", { name, data });
9171
- }
9172
- async setModel(name, model, opts) {
9173
- await this.start();
9174
- return this.requestOk("set_model", {
9175
- name,
9176
- model,
9177
- timeout_ms: opts?.timeoutMs
9178
- });
9179
- }
9180
- async getMetrics(agent) {
9181
- await this.start();
9182
- return this.requestOk("get_metrics", { agent });
9183
- }
9184
- async getCrashInsights() {
9185
- await this.start();
9186
- return this.requestOk("get_crash_insights", {});
9187
- }
9188
- async sendMessage(input) {
9189
- await this.start();
9190
- try {
9191
- return await this.requestOk("send_message", {
9192
- to: input.to,
9193
- text: input.text,
9194
- from: input.from,
9195
- thread_id: input.threadId,
9196
- workspace_id: input.workspaceId,
9197
- workspace_alias: input.workspaceAlias,
9198
- priority: input.priority,
9199
- data: input.data
9200
- });
9201
- } catch (error48) {
9202
- if (error48 instanceof AgentRelayProtocolError && error48.code === "unsupported_operation") {
9203
- return { event_id: "unsupported_operation", targets: [] };
9204
- }
9205
- throw error48;
9206
- }
9207
- }
9208
- async listAgents() {
9209
- await this.start();
9210
- const result = await this.requestOk("list_agents", {});
9211
- return result.agents;
9212
- }
9213
- async getStatus() {
9214
- await this.start();
9215
- return this.requestOk("get_status", {});
9216
- }
9217
- async shutdown() {
9218
- if (!this.child) {
9219
- return;
9220
- }
9221
- void this.requestOk("shutdown", {}).catch(() => {
9222
- });
9223
- const child = this.child;
9224
- const wait = this.exitPromise ?? Promise.resolve();
9225
- const waitForExit = async (timeoutMs) => {
9226
- let timer;
9227
- const result = await Promise.race([
9228
- wait.then(() => true),
9229
- new Promise((resolve3) => {
9230
- timer = setTimeout(() => resolve3(false), timeoutMs);
9231
- })
9232
- ]);
9233
- if (timer !== void 0)
9234
- clearTimeout(timer);
9235
- return result;
9236
- };
9237
- if (await waitForExit(this.options.shutdownTimeoutMs)) {
9238
- return;
9239
- }
9240
- if (child.exitCode === null && child.signalCode === null) {
9241
- child.kill("SIGTERM");
9242
- }
9243
- if (await waitForExit(1e3)) {
9244
- return;
9245
- }
9246
- if (child.exitCode === null && child.signalCode === null) {
9247
- child.kill("SIGKILL");
9248
- }
9249
- await waitForExit(1e3);
9250
- }
9251
- async waitForExit() {
9252
- if (!this.child) {
9253
- return;
9254
- }
9255
- await this.exitPromise;
9256
- }
9257
- async startInternal() {
9258
- const resolvedBinary = expandTilde(this.options.binaryPath);
9259
- if (isExplicitPath(this.options.binaryPath) && !import_node_fs.default.existsSync(resolvedBinary)) {
9260
- throw new AgentRelayProcessError(`broker binary not found: ${this.options.binaryPath}`);
9261
- }
9262
- this.lastStderrLine = void 0;
9263
- const args = [
9264
- "init",
9265
- "--name",
9266
- this.options.brokerName,
9267
- ...this.options.channels.length > 0 ? ["--channels", this.options.channels.join(",")] : [],
9268
- ...this.options.binaryArgs
9269
- ];
9270
- const env = { ...this.options.env };
9271
- if (isExplicitPath(this.options.binaryPath)) {
9272
- const binDir = import_node_path.default.dirname(import_node_path.default.resolve(resolvedBinary));
9273
- const currentPath = env.PATH ?? env.Path ?? "";
9274
- if (!currentPath.split(import_node_path.default.delimiter).includes(binDir)) {
9275
- env.PATH = `${binDir}${import_node_path.default.delimiter}${currentPath}`;
9276
- }
9277
- }
9278
- console.error(`[broker] Starting: ${resolvedBinary} ${args.join(" ")}`);
9279
- const child = (0, import_node_child_process.spawn)(resolvedBinary, args, {
9280
- cwd: this.options.cwd,
9281
- env,
9282
- stdio: "pipe"
9283
- });
9284
- this.child = child;
9285
- this.stdoutRl = (0, import_node_readline.createInterface)({ input: child.stdout, crlfDelay: Infinity });
9286
- this.stderrRl = (0, import_node_readline.createInterface)({ input: child.stderr, crlfDelay: Infinity });
9287
- this.stdoutRl.on("line", (line) => {
9288
- this.handleStdoutLine(line);
9289
- });
9290
- this.stderrRl.on("line", (line) => {
9291
- const trimmed = line.trim();
9292
- if (trimmed) {
9293
- this.lastStderrLine = trimmed;
9294
- }
9295
- for (const listener of this.stderrListeners) {
9296
- listener(line);
9297
- }
9298
- });
9299
- this.exitPromise = new Promise((resolve3) => {
9300
- child.once("close", (code, signal) => {
9301
- const detail = this.lastStderrLine ? `: ${this.lastStderrLine}` : "";
9302
- const error48 = new AgentRelayProcessError(`broker exited (code=${code ?? "null"}, signal=${signal ?? "null"})${detail}`);
9303
- this.failAllPending(error48);
9304
- this.disposeProcessHandles();
9305
- resolve3();
9306
- });
9307
- child.once("error", (error48) => {
9308
- this.failAllPending(error48);
9309
- this.disposeProcessHandles();
9310
- resolve3();
9311
- });
9312
- });
9313
- const helloAck = await this.requestHello();
9314
- console.error("[broker] Broker ready (hello handshake complete)");
9315
- if (helloAck.workspace_key) {
9316
- this.workspaceKey = helloAck.workspace_key;
9317
- }
9318
- }
9319
- disposeProcessHandles() {
9320
- this.stdoutRl?.close();
9321
- this.stderrRl?.close();
9322
- this.stdoutRl = void 0;
9323
- this.stderrRl = void 0;
9324
- this.lastStderrLine = void 0;
9325
- this.child = void 0;
9326
- this.exitPromise = void 0;
9327
- }
9328
- failAllPending(error48) {
9329
- for (const pending of this.pending.values()) {
9330
- clearTimeout(pending.timeout);
9331
- pending.reject(error48);
9332
- }
9333
- this.pending.clear();
9334
- }
9335
- handleStdoutLine(line) {
9336
- let parsed;
9337
- try {
9338
- parsed = JSON.parse(line);
9339
- } catch {
9340
- return;
9341
- }
9342
- if (!parsed || typeof parsed !== "object") {
9343
- return;
9344
- }
9345
- if (parsed.v !== PROTOCOL_VERSION || typeof parsed.type !== "string") {
9346
- return;
9347
- }
9348
- const envelope = {
9349
- v: parsed.v,
9350
- type: parsed.type,
9351
- request_id: parsed.request_id,
9352
- payload: parsed.payload
9353
- };
9354
- if (envelope.type === "event") {
9355
- const payload = envelope.payload;
9356
- this.eventBuffer.push(payload);
9357
- if (this.eventBuffer.length > this.maxBufferSize) {
9358
- this.eventBuffer.shift();
9359
- }
9360
- for (const listener of this.eventListeners) {
9361
- listener(payload);
9362
- }
9363
- return;
9364
- }
9365
- if (!envelope.request_id) {
9366
- return;
9367
- }
9368
- const pending = this.pending.get(envelope.request_id);
9369
- if (!pending) {
9370
- return;
9371
- }
9372
- if (envelope.type === "error") {
9373
- clearTimeout(pending.timeout);
9374
- this.pending.delete(envelope.request_id);
9375
- pending.reject(new AgentRelayProtocolError(envelope.payload));
9376
- return;
9377
- }
9378
- if (envelope.type !== pending.expectedType) {
9379
- clearTimeout(pending.timeout);
9380
- this.pending.delete(envelope.request_id);
9381
- pending.reject(new AgentRelayProcessError(`unexpected response type '${envelope.type}' for request '${envelope.request_id}' (expected '${pending.expectedType}')`));
9382
- return;
9383
- }
9384
- clearTimeout(pending.timeout);
9385
- this.pending.delete(envelope.request_id);
9386
- pending.resolve(envelope);
9387
- }
9388
- async requestHello() {
9389
- const payload = {
9390
- client_name: this.options.clientName,
9391
- client_version: this.options.clientVersion
9392
- };
9393
- const frame = await this.sendRequest("hello", payload, "hello_ack");
9394
- return frame.payload;
9395
- }
9396
- async requestOk(type, payload) {
9397
- const frame = await this.sendRequest(type, payload, "ok");
9398
- const result = frame.payload;
9399
- return result.result;
9400
- }
9401
- async sendRequest(type, payload, expectedType) {
9402
- if (!this.child) {
9403
- throw new AgentRelayProcessError("broker is not running");
9404
- }
9405
- const requestId = `req_${++this.requestSeq}`;
9406
- const message = {
9407
- v: PROTOCOL_VERSION,
9408
- type,
9409
- request_id: requestId,
9410
- payload
9411
- };
9412
- const responsePromise = new Promise((resolve3, reject) => {
9413
- const timeout = setTimeout(() => {
9414
- this.pending.delete(requestId);
9415
- reject(new AgentRelayProcessError(`request timed out after ${this.options.requestTimeoutMs}ms (type='${type}', request_id='${requestId}')`));
9416
- }, this.options.requestTimeoutMs);
9417
- this.pending.set(requestId, {
9418
- expectedType,
9419
- resolve: resolve3,
9420
- reject,
9421
- timeout
9422
- });
9423
- });
9424
- const line = `${JSON.stringify(message)}
9425
- `;
9426
- if (!this.child.stdin.write(line)) {
9427
- await (0, import_node_events.once)(this.child.stdin, "drain");
9428
- }
9429
- return responsePromise;
9430
- }
9431
- };
9432
- var CLI_MODEL_FLAG_CLIS = /* @__PURE__ */ new Set(["claude", "codex", "gemini", "goose", "aider"]);
9433
- var CLI_DEFAULT_ARGS = {
9434
- codex: ["-c", "check_for_update_on_startup=false"]
9435
- };
9436
- function buildPtyArgsWithModel(cli, args, model) {
9437
- const cliName = cli.split(":")[0].trim().toLowerCase();
9438
- const defaultArgs = CLI_DEFAULT_ARGS[cliName] ?? [];
9439
- const baseArgs = [...defaultArgs, ...args];
9440
- if (!model) {
9441
- return baseArgs;
9442
- }
9443
- if (!CLI_MODEL_FLAG_CLIS.has(cliName)) {
9444
- return baseArgs;
9445
- }
9446
- if (hasModelArg(baseArgs)) {
9447
- return baseArgs;
9448
- }
9449
- return ["--model", model, ...baseArgs];
9450
- }
9451
- function hasModelArg(args) {
9452
- for (let i = 0; i < args.length; i += 1) {
9453
- const arg = args[i];
9454
- if (arg === "--model") {
9455
- return true;
9456
- }
9457
- if (arg.startsWith("--model=")) {
9458
- return true;
9459
- }
9460
- }
9461
- return false;
9462
- }
9463
- function expandTilde(p) {
9464
- if (p === "~" || p.startsWith("~/") || p.startsWith("~\\")) {
9465
- const home = import_node_os.default.homedir();
9466
- return import_node_path.default.join(home, p.slice(2));
9467
- }
9468
- return p;
9469
- }
9470
- function isExplicitPath(binaryPath) {
9471
- return binaryPath.includes("/") || binaryPath.includes("\\") || binaryPath.startsWith(".") || binaryPath.startsWith("~");
9472
- }
9473
- function detectPlatformSuffix() {
9474
- const platformMap = {
9475
- darwin: { arm64: "darwin-arm64", x64: "darwin-x64" },
9476
- linux: { arm64: "linux-arm64", x64: "linux-x64" },
9477
- win32: { x64: "win32-x64" }
9478
- };
9479
- return platformMap[process.platform]?.[process.arch] ?? null;
9480
- }
9481
- function getLatestVersionSync() {
9482
- try {
9483
- const result = (0, import_node_child_process.execSync)("curl -fsSL https://api.github.com/repos/AgentWorkforce/relay/releases/latest", {
9484
- timeout: 15e3,
9485
- stdio: ["pipe", "pipe", "pipe"]
9486
- }).toString();
9487
- const match = result.match(/"tag_name"\s*:\s*"([^"]+)"/);
9488
- if (!match?.[1])
9489
- return null;
9490
- return match[1].replace(/^openclaw-/, "").replace(/^v/, "");
9491
- } catch {
9492
- return null;
9493
- }
9494
- }
9495
- function installBrokerBinary() {
9496
- const suffix = detectPlatformSuffix();
9497
- if (!suffix) {
9498
- throw new AgentRelayProcessError(`Unsupported platform: ${process.platform}-${process.arch}`);
9499
- }
9500
- const homeDir = process.env.HOME || process.env.USERPROFILE || "";
9501
- const installDir = import_node_path.default.join(homeDir, ".agent-relay", "bin");
9502
- const brokerExe = process.platform === "win32" ? "agent-relay-broker.exe" : "agent-relay-broker";
9503
- const targetPath = import_node_path.default.join(installDir, brokerExe);
9504
- console.log(`[agent-relay] Broker binary not found, installing for ${suffix}...`);
9505
- const version2 = getLatestVersionSync();
9506
- if (!version2) {
9507
- throw new AgentRelayProcessError("Failed to fetch latest agent-relay version from GitHub.\nInstall manually: curl -fsSL https://raw.githubusercontent.com/AgentWorkforce/relay/main/install.sh | bash");
9508
- }
9509
- const binaryName = `agent-relay-broker-${suffix}`;
9510
- const downloadUrl = `https://github.com/AgentWorkforce/relay/releases/download/v${version2}/${binaryName}`;
9511
- console.log(`[agent-relay] Downloading v${version2} from ${downloadUrl}`);
9512
- try {
9513
- import_node_fs.default.mkdirSync(installDir, { recursive: true });
9514
- (0, import_node_child_process.execSync)(`curl -fsSL "${downloadUrl}" -o "${targetPath}"`, {
9515
- timeout: 6e4,
9516
- stdio: ["pipe", "pipe", "pipe"]
9517
- });
9518
- import_node_fs.default.chmodSync(targetPath, 493);
9519
- if (process.platform === "darwin") {
9520
- try {
9521
- (0, import_node_child_process.execSync)(`xattr -d com.apple.quarantine "${targetPath}" 2>/dev/null || true`, {
9522
- timeout: 1e4,
9523
- stdio: ["pipe", "pipe", "pipe"]
9524
- });
9525
- } catch {
9526
- }
9527
- try {
9528
- (0, import_node_child_process.execSync)(`codesign --force --sign - "${targetPath}"`, {
9529
- timeout: 1e4,
9530
- stdio: ["pipe", "pipe", "pipe"]
9531
- });
9532
- } catch {
9533
- }
9534
- }
9535
- (0, import_node_child_process.execSync)(`"${targetPath}" --help`, { timeout: 1e4, stdio: ["pipe", "pipe", "pipe"] });
9536
- } catch (err) {
9537
- try {
9538
- import_node_fs.default.unlinkSync(targetPath);
9539
- } catch {
9540
- }
9541
- const message = err instanceof Error ? err.message : String(err);
9542
- throw new AgentRelayProcessError(`Failed to install broker binary: ${message}
9543
- Install manually: curl -fsSL https://raw.githubusercontent.com/AgentWorkforce/relay/main/install.sh | bash`);
9544
- }
9545
- console.log(`[agent-relay] Broker installed to ${targetPath}`);
9546
- return targetPath;
9547
- }
9548
- function resolveDefaultBinaryPath() {
9549
- const brokerExe = process.platform === "win32" ? "agent-relay-broker.exe" : "agent-relay-broker";
9550
- const moduleDir = import_node_path.default.dirname((0, import_node_url.fileURLToPath)(import_meta_url));
9551
- const workspaceRelease = import_node_path.default.resolve(moduleDir, "..", "..", "..", "target", "release", brokerExe);
9552
- if (import_node_fs.default.existsSync(workspaceRelease)) {
9553
- return workspaceRelease;
9554
- }
9555
- const binDir = import_node_path.default.resolve(moduleDir, "..", "bin");
9556
- const suffix = detectPlatformSuffix();
9557
- if (suffix) {
9558
- const ext = process.platform === "win32" ? ".exe" : "";
9559
- const platformBinary = import_node_path.default.join(binDir, `agent-relay-broker-${suffix}${ext}`);
9560
- if (import_node_fs.default.existsSync(platformBinary)) {
9561
- return platformBinary;
9562
- }
9563
- }
9564
- const homeDir = process.env.HOME || process.env.USERPROFILE || "";
9565
- const standaloneBroker = import_node_path.default.join(homeDir, ".agent-relay", "bin", brokerExe);
9566
- if (import_node_fs.default.existsSync(standaloneBroker)) {
9567
- return standaloneBroker;
9568
- }
9569
- return installBrokerBinary();
9570
- }
9571
8961
 
9572
8962
  // packages/config/src/relay-config.ts
9573
8963
  var DEFAULT_CONNECTION_CONFIG = {
@@ -9580,28 +8970,66 @@ var DEFAULT_CONNECTION_CONFIG = {
9580
8970
  };
9581
8971
 
9582
8972
  // packages/config/src/bridge-config.ts
9583
- var import_node_path3 = __toESM(require("node:path"), 1);
9584
- var import_node_os3 = __toESM(require("node:os"), 1);
9585
-
9586
- // packages/config/src/project-namespace.ts
9587
8973
  var import_node_path2 = __toESM(require("node:path"), 1);
9588
8974
  var import_node_os2 = __toESM(require("node:os"), 1);
8975
+
8976
+ // packages/config/src/project-namespace.ts
8977
+ var import_node_crypto = __toESM(require("node:crypto"), 1);
8978
+ var import_node_path = __toESM(require("node:path"), 1);
8979
+ var import_node_fs = __toESM(require("node:fs"), 1);
8980
+ var import_node_os = __toESM(require("node:os"), 1);
9589
8981
  function getGlobalBaseDir() {
9590
8982
  if (process.env.AGENT_RELAY_DATA_DIR) {
9591
8983
  return process.env.AGENT_RELAY_DATA_DIR;
9592
8984
  }
9593
8985
  const xdgDataHome = process.env.XDG_DATA_HOME;
9594
8986
  if (xdgDataHome) {
9595
- return import_node_path2.default.join(xdgDataHome, "agent-relay");
8987
+ return import_node_path.default.join(xdgDataHome, "agent-relay");
9596
8988
  }
9597
- return import_node_path2.default.join(import_node_os2.default.homedir(), ".agent-relay");
8989
+ return import_node_path.default.join(import_node_os.default.homedir(), ".agent-relay");
9598
8990
  }
9599
8991
  var GLOBAL_BASE_DIR = getGlobalBaseDir();
8992
+ var PROJECT_DATA_DIR = ".agent-relay";
8993
+ function hashPath(projectPath) {
8994
+ const normalized = import_node_path.default.resolve(projectPath);
8995
+ const hash2 = import_node_crypto.default.createHash("sha256").update(normalized).digest("hex");
8996
+ return hash2.substring(0, 12);
8997
+ }
8998
+ function findProjectRoot(startDir = process.cwd()) {
8999
+ if (process.env.AGENT_RELAY_PROJECT) {
9000
+ return import_node_path.default.resolve(process.env.AGENT_RELAY_PROJECT);
9001
+ }
9002
+ let current = import_node_path.default.resolve(startDir);
9003
+ const root = import_node_path.default.parse(current).root;
9004
+ const markers = [".git", "package.json", "Cargo.toml", "go.mod", "pyproject.toml", ".agent-relay"];
9005
+ while (current !== root) {
9006
+ for (const marker of markers) {
9007
+ if (import_node_fs.default.existsSync(import_node_path.default.join(current, marker))) {
9008
+ return current;
9009
+ }
9010
+ }
9011
+ current = import_node_path.default.dirname(current);
9012
+ }
9013
+ return import_node_path.default.resolve(startDir);
9014
+ }
9015
+ function getProjectPaths(projectRoot) {
9016
+ const root = projectRoot ?? findProjectRoot();
9017
+ const projectId = hashPath(root);
9018
+ const dataDir = import_node_path.default.join(root, PROJECT_DATA_DIR);
9019
+ return {
9020
+ dataDir,
9021
+ teamDir: import_node_path.default.join(dataDir, "team"),
9022
+ dbPath: import_node_path.default.join(dataDir, "messages.sqlite"),
9023
+ socketPath: import_node_path.default.join(dataDir, "relay.sock"),
9024
+ projectRoot: root,
9025
+ projectId
9026
+ };
9027
+ }
9600
9028
 
9601
9029
  // packages/config/src/bridge-config.ts
9602
9030
  var CONFIG_PATHS = [
9603
- import_node_path3.default.join(import_node_os3.default.homedir(), ".agent-relay", "bridge.json"),
9604
- import_node_path3.default.join(import_node_os3.default.homedir(), ".config", "agent-relay", "bridge.json")
9031
+ import_node_path2.default.join(import_node_os2.default.homedir(), ".agent-relay", "bridge.json"),
9032
+ import_node_path2.default.join(import_node_os2.default.homedir(), ".config", "agent-relay", "bridge.json")
9605
9033
  ];
9606
9034
 
9607
9035
  // packages/config/src/index.ts
@@ -15501,99 +14929,930 @@ var ModelOptions = {
15501
14929
  Droid: DROID_MODEL_OPTIONS,
15502
14930
  Opencode: OPENCODE_MODEL_OPTIONS
15503
14931
  };
15504
- var SwarmPatterns = {
15505
- /** Central coordinator distributes tasks to workers */
15506
- HUB_SPOKE: "hub-spoke",
15507
- /** Directed acyclic graph with dependencies */
15508
- DAG: "dag",
15509
- /** Parallel execution across multiple agents */
15510
- FAN_OUT: "fan-out",
15511
- /** Sequential processing through stages */
15512
- PIPELINE: "pipeline",
15513
- /** Agents reach agreement before proceeding */
15514
- CONSENSUS: "consensus",
15515
- /** Fully connected peer-to-peer communication */
15516
- MESH: "mesh",
15517
- /** Sequential handoff between agents */
15518
- HANDOFF: "handoff",
15519
- /** Cascading delegation */
15520
- CASCADE: "cascade",
15521
- /** Agents debate to reach conclusion */
15522
- DEBATE: "debate",
15523
- /** Tree-structured coordination */
15524
- HIERARCHICAL: "hierarchical"
14932
+ var SwarmPatterns = {
14933
+ /** Central coordinator distributes tasks to workers */
14934
+ HUB_SPOKE: "hub-spoke",
14935
+ /** Directed acyclic graph with dependencies */
14936
+ DAG: "dag",
14937
+ /** Parallel execution across multiple agents */
14938
+ FAN_OUT: "fan-out",
14939
+ /** Sequential processing through stages */
14940
+ PIPELINE: "pipeline",
14941
+ /** Agents reach agreement before proceeding */
14942
+ CONSENSUS: "consensus",
14943
+ /** Fully connected peer-to-peer communication */
14944
+ MESH: "mesh",
14945
+ /** Sequential handoff between agents */
14946
+ HANDOFF: "handoff",
14947
+ /** Cascading delegation */
14948
+ CASCADE: "cascade",
14949
+ /** Agents debate to reach conclusion */
14950
+ DEBATE: "debate",
14951
+ /** Tree-structured coordination */
14952
+ HIERARCHICAL: "hierarchical"
14953
+ };
14954
+ var CLIRegistry = {
14955
+ claude: {
14956
+ name: "Claude Code",
14957
+ package: "@anthropic-ai/claude-code",
14958
+ version: "2.1.72",
14959
+ install: "npm install -g @anthropic-ai/claude-code",
14960
+ npmLink: "https://www.npmjs.com/package/@anthropic-ai"
14961
+ },
14962
+ codex: {
14963
+ name: "Codex CLI",
14964
+ package: "@openai/codex",
14965
+ version: "0.114.0",
14966
+ install: "npm install -g @openai/codex",
14967
+ npmLink: "https://www.npmjs.com/package/@openai/codex"
14968
+ },
14969
+ gemini: {
14970
+ name: "Gemini CLI",
14971
+ package: "@google/gemini-cli",
14972
+ version: "0.33.0",
14973
+ install: "npm install -g @google/gemini-cli",
14974
+ npmLink: "https://www.npmjs.com/package/@google/gemini-cli"
14975
+ },
14976
+ cursor: {
14977
+ name: "Cursor",
14978
+ package: "cursor",
14979
+ version: "2026.02.27-e7d2ef6",
14980
+ install: "Download from cursor.com",
14981
+ npmLink: void 0
14982
+ },
14983
+ droid: {
14984
+ name: "Droid",
14985
+ package: "droid",
14986
+ version: "0.1.0",
14987
+ install: "Download from droid.dev",
14988
+ npmLink: void 0
14989
+ },
14990
+ opencode: {
14991
+ name: "OpenCode",
14992
+ package: "opencode-ai",
14993
+ version: "1.2.24",
14994
+ install: "npm install -g opencode-ai",
14995
+ npmLink: "https://www.npmjs.com/package/opencode-ai"
14996
+ },
14997
+ aider: {
14998
+ name: "Aider",
14999
+ package: "aider-chat",
15000
+ version: "0.72.1",
15001
+ install: "pip install aider-chat",
15002
+ npmLink: void 0
15003
+ },
15004
+ goose: {
15005
+ name: "Goose",
15006
+ package: "goose-ai",
15007
+ version: "1.0.16",
15008
+ install: "pip install goose-ai",
15009
+ npmLink: void 0
15010
+ }
15011
+ };
15012
+ var DefaultModels = {
15013
+ claude: "sonnet",
15014
+ codex: "gpt-5.4",
15015
+ gemini: "gemini-3.1-pro-preview",
15016
+ cursor: "opus-4.6-thinking",
15017
+ droid: "opus-4.6-fast",
15018
+ opencode: "openai/gpt-5.2"
15019
+ };
15020
+
15021
+ // packages/sdk/dist/client.js
15022
+ var AgentRelayProtocolError = class extends Error {
15023
+ code;
15024
+ retryable;
15025
+ data;
15026
+ constructor(payload) {
15027
+ super(payload.message);
15028
+ this.name = "AgentRelayProtocolError";
15029
+ this.code = payload.code;
15030
+ this.retryable = payload.retryable;
15031
+ this.data = payload.data;
15032
+ }
15033
+ };
15034
+ var AgentRelayProcessError = class extends Error {
15035
+ constructor(message) {
15036
+ super(message);
15037
+ this.name = "AgentRelayProcessError";
15038
+ }
15039
+ };
15040
+ function isHeadlessProvider(value) {
15041
+ return value === "claude" || value === "opencode";
15042
+ }
15043
+ var AgentRelayClient = class _AgentRelayClient {
15044
+ options;
15045
+ child;
15046
+ stdoutRl;
15047
+ stderrRl;
15048
+ lastStderrLine;
15049
+ requestSeq = 0;
15050
+ pending = /* @__PURE__ */ new Map();
15051
+ startingPromise;
15052
+ eventListeners = /* @__PURE__ */ new Set();
15053
+ stderrListeners = /* @__PURE__ */ new Set();
15054
+ eventBuffer = [];
15055
+ maxBufferSize = 1e3;
15056
+ exitPromise;
15057
+ /** The workspace key returned by the broker in its hello_ack response. */
15058
+ workspaceKey;
15059
+ constructor(options = {}) {
15060
+ this.options = {
15061
+ binaryPath: options.binaryPath ?? resolveDefaultBinaryPath(),
15062
+ binaryArgs: options.binaryArgs ?? [],
15063
+ brokerName: options.brokerName ?? (import_node_path3.default.basename(options.cwd ?? process.cwd()) || "project"),
15064
+ channels: options.channels ?? ["general"],
15065
+ cwd: options.cwd ?? process.cwd(),
15066
+ env: options.env ?? process.env,
15067
+ requestTimeoutMs: options.requestTimeoutMs ?? 1e4,
15068
+ shutdownTimeoutMs: options.shutdownTimeoutMs ?? 3e3,
15069
+ clientName: options.clientName ?? "@agent-relay/sdk",
15070
+ clientVersion: options.clientVersion ?? "0.1.0"
15071
+ };
15072
+ }
15073
+ static async start(options = {}) {
15074
+ const client = new _AgentRelayClient(options);
15075
+ await client.start();
15076
+ return client;
15077
+ }
15078
+ onEvent(listener) {
15079
+ this.eventListeners.add(listener);
15080
+ return () => {
15081
+ this.eventListeners.delete(listener);
15082
+ };
15083
+ }
15084
+ queryEvents(filter) {
15085
+ let events = [...this.eventBuffer];
15086
+ if (filter?.kind) {
15087
+ events = events.filter((event) => event.kind === filter.kind);
15088
+ }
15089
+ if (filter?.name) {
15090
+ events = events.filter((event) => "name" in event && event.name === filter.name);
15091
+ }
15092
+ const since = filter?.since;
15093
+ if (since !== void 0) {
15094
+ events = events.filter((event) => "timestamp" in event && typeof event.timestamp === "number" && event.timestamp >= since);
15095
+ }
15096
+ const limit = filter?.limit;
15097
+ if (limit !== void 0) {
15098
+ events = events.slice(-limit);
15099
+ }
15100
+ return events;
15101
+ }
15102
+ getLastEvent(kind, name) {
15103
+ for (let i = this.eventBuffer.length - 1; i >= 0; i -= 1) {
15104
+ const event = this.eventBuffer[i];
15105
+ if (event.kind === kind && (!name || "name" in event && event.name === name)) {
15106
+ return event;
15107
+ }
15108
+ }
15109
+ return void 0;
15110
+ }
15111
+ onBrokerStderr(listener) {
15112
+ this.stderrListeners.add(listener);
15113
+ return () => {
15114
+ this.stderrListeners.delete(listener);
15115
+ };
15116
+ }
15117
+ get brokerPid() {
15118
+ return this.child?.pid;
15119
+ }
15120
+ async start() {
15121
+ if (this.child) {
15122
+ return;
15123
+ }
15124
+ if (this.startingPromise) {
15125
+ return this.startingPromise;
15126
+ }
15127
+ this.startingPromise = this.startInternal();
15128
+ try {
15129
+ await this.startingPromise;
15130
+ } finally {
15131
+ this.startingPromise = void 0;
15132
+ }
15133
+ }
15134
+ /**
15135
+ * Pre-register a batch of agents with Relaycast before their steps execute.
15136
+ * The broker warms its token cache in parallel; subsequent spawn_agent calls
15137
+ * hit the cache rather than waiting on individual HTTP registrations.
15138
+ * Fire-and-forget from the caller's perspective — broker responds immediately
15139
+ * and registers in the background.
15140
+ */
15141
+ async preflightAgents(agents) {
15142
+ if (agents.length === 0)
15143
+ return;
15144
+ await this.start();
15145
+ await this.requestOk("preflight_agents", { agents });
15146
+ }
15147
+ async spawnPty(input) {
15148
+ await this.start();
15149
+ const args = buildPtyArgsWithModel(input.cli, input.args ?? [], input.model);
15150
+ const agent = {
15151
+ name: input.name,
15152
+ runtime: "pty",
15153
+ cli: input.cli,
15154
+ args,
15155
+ channels: input.channels ?? [],
15156
+ model: input.model,
15157
+ cwd: input.cwd ?? this.options.cwd,
15158
+ team: input.team,
15159
+ shadow_of: input.shadowOf,
15160
+ shadow_mode: input.shadowMode,
15161
+ restart_policy: input.restartPolicy
15162
+ };
15163
+ const result = await this.requestOk("spawn_agent", {
15164
+ agent,
15165
+ ...input.task != null ? { initial_task: input.task } : {},
15166
+ ...input.idleThresholdSecs != null ? { idle_threshold_secs: input.idleThresholdSecs } : {},
15167
+ ...input.continueFrom != null ? { continue_from: input.continueFrom } : {},
15168
+ ...input.skipRelayPrompt != null ? { skip_relay_prompt: input.skipRelayPrompt } : {}
15169
+ });
15170
+ return result;
15171
+ }
15172
+ async spawnHeadless(input) {
15173
+ await this.start();
15174
+ const agent = {
15175
+ name: input.name,
15176
+ runtime: "headless",
15177
+ provider: input.provider,
15178
+ args: input.args ?? [],
15179
+ channels: input.channels ?? []
15180
+ };
15181
+ const result = await this.requestOk("spawn_agent", {
15182
+ agent,
15183
+ ...input.task != null ? { initial_task: input.task } : {},
15184
+ ...input.skipRelayPrompt != null ? { skip_relay_prompt: input.skipRelayPrompt } : {}
15185
+ });
15186
+ return result;
15187
+ }
15188
+ async spawnProvider(input) {
15189
+ const transport = input.transport ?? (input.provider === "opencode" ? "headless" : "pty");
15190
+ if (transport === "headless") {
15191
+ if (!isHeadlessProvider(input.provider)) {
15192
+ throw new AgentRelayProcessError(`provider '${input.provider}' does not support headless transport (supported: claude, opencode)`);
15193
+ }
15194
+ return this.spawnHeadless({
15195
+ name: input.name,
15196
+ provider: input.provider,
15197
+ args: input.args,
15198
+ channels: input.channels,
15199
+ task: input.task,
15200
+ skipRelayPrompt: input.skipRelayPrompt
15201
+ });
15202
+ }
15203
+ return this.spawnPty({
15204
+ name: input.name,
15205
+ cli: input.provider,
15206
+ args: input.args,
15207
+ channels: input.channels,
15208
+ task: input.task,
15209
+ model: input.model,
15210
+ cwd: input.cwd,
15211
+ team: input.team,
15212
+ shadowOf: input.shadowOf,
15213
+ shadowMode: input.shadowMode,
15214
+ idleThresholdSecs: input.idleThresholdSecs,
15215
+ restartPolicy: input.restartPolicy,
15216
+ continueFrom: input.continueFrom,
15217
+ skipRelayPrompt: input.skipRelayPrompt
15218
+ });
15219
+ }
15220
+ async spawnClaude(input) {
15221
+ return this.spawnProvider({ ...input, provider: "claude" });
15222
+ }
15223
+ async spawnOpencode(input) {
15224
+ return this.spawnProvider({ ...input, provider: "opencode" });
15225
+ }
15226
+ async release(name, reason) {
15227
+ await this.start();
15228
+ return this.requestOk("release_agent", { name, reason });
15229
+ }
15230
+ async sendInput(name, data) {
15231
+ await this.start();
15232
+ return this.requestOk("send_input", { name, data });
15233
+ }
15234
+ async setModel(name, model, opts) {
15235
+ await this.start();
15236
+ return this.requestOk("set_model", {
15237
+ name,
15238
+ model,
15239
+ timeout_ms: opts?.timeoutMs
15240
+ });
15241
+ }
15242
+ async getMetrics(agent) {
15243
+ await this.start();
15244
+ return this.requestOk("get_metrics", { agent });
15245
+ }
15246
+ async getCrashInsights() {
15247
+ await this.start();
15248
+ return this.requestOk("get_crash_insights", {});
15249
+ }
15250
+ async sendMessage(input) {
15251
+ await this.start();
15252
+ try {
15253
+ return await this.requestOk("send_message", {
15254
+ to: input.to,
15255
+ text: input.text,
15256
+ from: input.from,
15257
+ thread_id: input.threadId,
15258
+ workspace_id: input.workspaceId,
15259
+ workspace_alias: input.workspaceAlias,
15260
+ priority: input.priority,
15261
+ data: input.data
15262
+ });
15263
+ } catch (error48) {
15264
+ if (error48 instanceof AgentRelayProtocolError && error48.code === "unsupported_operation") {
15265
+ return { event_id: "unsupported_operation", targets: [] };
15266
+ }
15267
+ throw error48;
15268
+ }
15269
+ }
15270
+ async listAgents() {
15271
+ await this.start();
15272
+ const result = await this.requestOk("list_agents", {});
15273
+ return result.agents;
15274
+ }
15275
+ async getStatus() {
15276
+ await this.start();
15277
+ return this.requestOk("get_status", {});
15278
+ }
15279
+ async shutdown() {
15280
+ if (!this.child) {
15281
+ return;
15282
+ }
15283
+ void this.requestOk("shutdown", {}).catch(() => {
15284
+ });
15285
+ const child = this.child;
15286
+ const wait = this.exitPromise ?? Promise.resolve();
15287
+ const waitForExit = async (timeoutMs) => {
15288
+ let timer;
15289
+ const result = await Promise.race([
15290
+ wait.then(() => true),
15291
+ new Promise((resolve3) => {
15292
+ timer = setTimeout(() => resolve3(false), timeoutMs);
15293
+ })
15294
+ ]);
15295
+ if (timer !== void 0)
15296
+ clearTimeout(timer);
15297
+ return result;
15298
+ };
15299
+ if (await waitForExit(this.options.shutdownTimeoutMs)) {
15300
+ return;
15301
+ }
15302
+ if (child.exitCode === null && child.signalCode === null) {
15303
+ child.kill("SIGTERM");
15304
+ }
15305
+ if (await waitForExit(1e3)) {
15306
+ return;
15307
+ }
15308
+ if (child.exitCode === null && child.signalCode === null) {
15309
+ child.kill("SIGKILL");
15310
+ }
15311
+ await waitForExit(1e3);
15312
+ }
15313
+ async waitForExit() {
15314
+ if (!this.child) {
15315
+ return;
15316
+ }
15317
+ await this.exitPromise;
15318
+ }
15319
+ async startInternal() {
15320
+ const resolvedBinary = expandTilde(this.options.binaryPath);
15321
+ if (isExplicitPath(this.options.binaryPath) && !import_node_fs2.default.existsSync(resolvedBinary)) {
15322
+ throw new AgentRelayProcessError(`broker binary not found: ${this.options.binaryPath}`);
15323
+ }
15324
+ this.lastStderrLine = void 0;
15325
+ const args = [
15326
+ "init",
15327
+ "--name",
15328
+ this.options.brokerName,
15329
+ ...this.options.channels.length > 0 ? ["--channels", this.options.channels.join(",")] : [],
15330
+ ...this.options.binaryArgs
15331
+ ];
15332
+ const env = { ...this.options.env };
15333
+ if (isExplicitPath(this.options.binaryPath)) {
15334
+ const binDir = import_node_path3.default.dirname(import_node_path3.default.resolve(resolvedBinary));
15335
+ const currentPath = env.PATH ?? env.Path ?? "";
15336
+ if (!currentPath.split(import_node_path3.default.delimiter).includes(binDir)) {
15337
+ env.PATH = `${binDir}${import_node_path3.default.delimiter}${currentPath}`;
15338
+ }
15339
+ }
15340
+ console.error(`[broker] Starting: ${resolvedBinary} ${args.join(" ")}`);
15341
+ const child = (0, import_node_child_process2.spawn)(resolvedBinary, args, {
15342
+ cwd: this.options.cwd,
15343
+ env,
15344
+ stdio: "pipe"
15345
+ });
15346
+ this.child = child;
15347
+ this.stdoutRl = (0, import_node_readline.createInterface)({ input: child.stdout, crlfDelay: Infinity });
15348
+ this.stderrRl = (0, import_node_readline.createInterface)({ input: child.stderr, crlfDelay: Infinity });
15349
+ this.stdoutRl.on("line", (line) => {
15350
+ this.handleStdoutLine(line);
15351
+ });
15352
+ this.stderrRl.on("line", (line) => {
15353
+ const trimmed = line.trim();
15354
+ if (trimmed) {
15355
+ this.lastStderrLine = trimmed;
15356
+ }
15357
+ for (const listener of this.stderrListeners) {
15358
+ listener(line);
15359
+ }
15360
+ });
15361
+ this.exitPromise = new Promise((resolve3) => {
15362
+ child.once("close", (code, signal) => {
15363
+ const detail = this.lastStderrLine ? `: ${this.lastStderrLine}` : "";
15364
+ const error48 = new AgentRelayProcessError(`broker exited (code=${code ?? "null"}, signal=${signal ?? "null"})${detail}`);
15365
+ this.failAllPending(error48);
15366
+ this.disposeProcessHandles();
15367
+ resolve3();
15368
+ });
15369
+ child.once("error", (error48) => {
15370
+ this.failAllPending(error48);
15371
+ this.disposeProcessHandles();
15372
+ resolve3();
15373
+ });
15374
+ });
15375
+ const helloAck = await this.requestHello();
15376
+ console.error("[broker] Broker ready (hello handshake complete)");
15377
+ if (helloAck.workspace_key) {
15378
+ this.workspaceKey = helloAck.workspace_key;
15379
+ }
15380
+ }
15381
+ disposeProcessHandles() {
15382
+ this.stdoutRl?.close();
15383
+ this.stderrRl?.close();
15384
+ this.stdoutRl = void 0;
15385
+ this.stderrRl = void 0;
15386
+ this.lastStderrLine = void 0;
15387
+ this.child = void 0;
15388
+ this.exitPromise = void 0;
15389
+ }
15390
+ failAllPending(error48) {
15391
+ for (const pending of this.pending.values()) {
15392
+ clearTimeout(pending.timeout);
15393
+ pending.reject(error48);
15394
+ }
15395
+ this.pending.clear();
15396
+ }
15397
+ handleStdoutLine(line) {
15398
+ let parsed;
15399
+ try {
15400
+ parsed = JSON.parse(line);
15401
+ } catch {
15402
+ return;
15403
+ }
15404
+ if (!parsed || typeof parsed !== "object") {
15405
+ return;
15406
+ }
15407
+ if (parsed.v !== PROTOCOL_VERSION || typeof parsed.type !== "string") {
15408
+ return;
15409
+ }
15410
+ const envelope = {
15411
+ v: parsed.v,
15412
+ type: parsed.type,
15413
+ request_id: parsed.request_id,
15414
+ payload: parsed.payload
15415
+ };
15416
+ if (envelope.type === "event") {
15417
+ const payload = envelope.payload;
15418
+ this.eventBuffer.push(payload);
15419
+ if (this.eventBuffer.length > this.maxBufferSize) {
15420
+ this.eventBuffer.shift();
15421
+ }
15422
+ for (const listener of this.eventListeners) {
15423
+ listener(payload);
15424
+ }
15425
+ return;
15426
+ }
15427
+ if (!envelope.request_id) {
15428
+ return;
15429
+ }
15430
+ const pending = this.pending.get(envelope.request_id);
15431
+ if (!pending) {
15432
+ return;
15433
+ }
15434
+ if (envelope.type === "error") {
15435
+ clearTimeout(pending.timeout);
15436
+ this.pending.delete(envelope.request_id);
15437
+ pending.reject(new AgentRelayProtocolError(envelope.payload));
15438
+ return;
15439
+ }
15440
+ if (envelope.type !== pending.expectedType) {
15441
+ clearTimeout(pending.timeout);
15442
+ this.pending.delete(envelope.request_id);
15443
+ pending.reject(new AgentRelayProcessError(`unexpected response type '${envelope.type}' for request '${envelope.request_id}' (expected '${pending.expectedType}')`));
15444
+ return;
15445
+ }
15446
+ clearTimeout(pending.timeout);
15447
+ this.pending.delete(envelope.request_id);
15448
+ pending.resolve(envelope);
15449
+ }
15450
+ async requestHello() {
15451
+ const payload = {
15452
+ client_name: this.options.clientName,
15453
+ client_version: this.options.clientVersion
15454
+ };
15455
+ const frame = await this.sendRequest("hello", payload, "hello_ack");
15456
+ return frame.payload;
15457
+ }
15458
+ async requestOk(type, payload) {
15459
+ const frame = await this.sendRequest(type, payload, "ok");
15460
+ const result = frame.payload;
15461
+ return result.result;
15462
+ }
15463
+ async sendRequest(type, payload, expectedType) {
15464
+ if (!this.child) {
15465
+ throw new AgentRelayProcessError("broker is not running");
15466
+ }
15467
+ const requestId = `req_${++this.requestSeq}`;
15468
+ const message = {
15469
+ v: PROTOCOL_VERSION,
15470
+ type,
15471
+ request_id: requestId,
15472
+ payload
15473
+ };
15474
+ const responsePromise = new Promise((resolve3, reject) => {
15475
+ const timeout = setTimeout(() => {
15476
+ this.pending.delete(requestId);
15477
+ reject(new AgentRelayProcessError(`request timed out after ${this.options.requestTimeoutMs}ms (type='${type}', request_id='${requestId}')`));
15478
+ }, this.options.requestTimeoutMs);
15479
+ this.pending.set(requestId, {
15480
+ expectedType,
15481
+ resolve: resolve3,
15482
+ reject,
15483
+ timeout
15484
+ });
15485
+ });
15486
+ const line = `${JSON.stringify(message)}
15487
+ `;
15488
+ if (!this.child.stdin.write(line)) {
15489
+ await (0, import_node_events.once)(this.child.stdin, "drain");
15490
+ }
15491
+ return responsePromise;
15492
+ }
15493
+ };
15494
+ var CLI_MODEL_FLAG_CLIS = /* @__PURE__ */ new Set(["claude", "codex", "gemini", "goose", "aider"]);
15495
+ var CLI_DEFAULT_ARGS = {
15496
+ codex: ["-c", "check_for_update_on_startup=false"]
15525
15497
  };
15526
- var CLIRegistry = {
15527
- claude: {
15528
- name: "Claude Code",
15529
- package: "@anthropic-ai/claude-code",
15530
- version: "2.1.72",
15531
- install: "npm install -g @anthropic-ai/claude-code",
15532
- npmLink: "https://www.npmjs.com/package/@anthropic-ai"
15533
- },
15534
- codex: {
15535
- name: "Codex CLI",
15536
- package: "@openai/codex",
15537
- version: "0.114.0",
15538
- install: "npm install -g @openai/codex",
15539
- npmLink: "https://www.npmjs.com/package/@openai/codex"
15540
- },
15541
- gemini: {
15542
- name: "Gemini CLI",
15543
- package: "@google/gemini-cli",
15544
- version: "0.33.0",
15545
- install: "npm install -g @google/gemini-cli",
15546
- npmLink: "https://www.npmjs.com/package/@google/gemini-cli"
15547
- },
15548
- cursor: {
15549
- name: "Cursor",
15550
- package: "cursor",
15551
- version: "2026.02.27-e7d2ef6",
15552
- install: "Download from cursor.com",
15553
- npmLink: void 0
15554
- },
15555
- droid: {
15556
- name: "Droid",
15557
- package: "droid",
15558
- version: "0.1.0",
15559
- install: "Download from droid.dev",
15560
- npmLink: void 0
15561
- },
15562
- opencode: {
15563
- name: "OpenCode",
15564
- package: "opencode-ai",
15565
- version: "1.2.24",
15566
- install: "npm install -g opencode-ai",
15567
- npmLink: "https://www.npmjs.com/package/opencode-ai"
15568
- },
15569
- aider: {
15570
- name: "Aider",
15571
- package: "aider-chat",
15572
- version: "0.72.1",
15573
- install: "pip install aider-chat",
15574
- npmLink: void 0
15575
- },
15576
- goose: {
15577
- name: "Goose",
15578
- package: "goose-ai",
15579
- version: "1.0.16",
15580
- install: "pip install goose-ai",
15581
- npmLink: void 0
15498
+ function buildPtyArgsWithModel(cli, args, model) {
15499
+ const cliName = cli.split(":")[0].trim().toLowerCase();
15500
+ const defaultArgs = CLI_DEFAULT_ARGS[cliName] ?? [];
15501
+ const baseArgs = [...defaultArgs, ...args];
15502
+ if (!model) {
15503
+ return baseArgs;
15504
+ }
15505
+ if (!CLI_MODEL_FLAG_CLIS.has(cliName)) {
15506
+ return baseArgs;
15507
+ }
15508
+ if (hasModelArg(baseArgs)) {
15509
+ return baseArgs;
15510
+ }
15511
+ return ["--model", model, ...baseArgs];
15512
+ }
15513
+ function hasModelArg(args) {
15514
+ for (let i = 0; i < args.length; i += 1) {
15515
+ const arg = args[i];
15516
+ if (arg === "--model") {
15517
+ return true;
15518
+ }
15519
+ if (arg.startsWith("--model=")) {
15520
+ return true;
15521
+ }
15522
+ }
15523
+ return false;
15524
+ }
15525
+ function expandTilde(p) {
15526
+ if (p === "~" || p.startsWith("~/") || p.startsWith("~\\")) {
15527
+ const home = import_node_os3.default.homedir();
15528
+ return import_node_path3.default.join(home, p.slice(2));
15529
+ }
15530
+ return p;
15531
+ }
15532
+ function isExplicitPath(binaryPath) {
15533
+ return binaryPath.includes("/") || binaryPath.includes("\\") || binaryPath.startsWith(".") || binaryPath.startsWith("~");
15534
+ }
15535
+ function detectPlatformSuffix() {
15536
+ const platformMap = {
15537
+ darwin: { arm64: "darwin-arm64", x64: "darwin-x64" },
15538
+ linux: { arm64: "linux-arm64", x64: "linux-x64" },
15539
+ win32: { x64: "win32-x64" }
15540
+ };
15541
+ return platformMap[process.platform]?.[process.arch] ?? null;
15542
+ }
15543
+ function getLatestVersionSync() {
15544
+ try {
15545
+ const result = (0, import_node_child_process2.execSync)("curl -fsSL https://api.github.com/repos/AgentWorkforce/relay/releases/latest", {
15546
+ timeout: 15e3,
15547
+ stdio: ["pipe", "pipe", "pipe"]
15548
+ }).toString();
15549
+ const match = result.match(/"tag_name"\s*:\s*"([^"]+)"/);
15550
+ if (!match?.[1])
15551
+ return null;
15552
+ return match[1].replace(/^openclaw-/, "").replace(/^v/, "");
15553
+ } catch {
15554
+ return null;
15555
+ }
15556
+ }
15557
+ function installBrokerBinary() {
15558
+ const suffix = detectPlatformSuffix();
15559
+ if (!suffix) {
15560
+ throw new AgentRelayProcessError(`Unsupported platform: ${process.platform}-${process.arch}`);
15561
+ }
15562
+ const homeDir = process.env.HOME || process.env.USERPROFILE || "";
15563
+ const installDir = import_node_path3.default.join(homeDir, ".agent-relay", "bin");
15564
+ const brokerExe = process.platform === "win32" ? "agent-relay-broker.exe" : "agent-relay-broker";
15565
+ const targetPath = import_node_path3.default.join(installDir, brokerExe);
15566
+ console.log(`[agent-relay] Broker binary not found, installing for ${suffix}...`);
15567
+ const version2 = getLatestVersionSync();
15568
+ if (!version2) {
15569
+ throw new AgentRelayProcessError("Failed to fetch latest agent-relay version from GitHub.\nInstall manually: curl -fsSL https://raw.githubusercontent.com/AgentWorkforce/relay/main/install.sh | bash");
15570
+ }
15571
+ const binaryName = `agent-relay-broker-${suffix}`;
15572
+ const downloadUrl = `https://github.com/AgentWorkforce/relay/releases/download/v${version2}/${binaryName}`;
15573
+ console.log(`[agent-relay] Downloading v${version2} from ${downloadUrl}`);
15574
+ try {
15575
+ import_node_fs2.default.mkdirSync(installDir, { recursive: true });
15576
+ (0, import_node_child_process2.execSync)(`curl -fsSL "${downloadUrl}" -o "${targetPath}"`, {
15577
+ timeout: 6e4,
15578
+ stdio: ["pipe", "pipe", "pipe"]
15579
+ });
15580
+ import_node_fs2.default.chmodSync(targetPath, 493);
15581
+ if (process.platform === "darwin") {
15582
+ try {
15583
+ (0, import_node_child_process2.execSync)(`xattr -d com.apple.quarantine "${targetPath}" 2>/dev/null || true`, {
15584
+ timeout: 1e4,
15585
+ stdio: ["pipe", "pipe", "pipe"]
15586
+ });
15587
+ } catch {
15588
+ }
15589
+ try {
15590
+ (0, import_node_child_process2.execSync)(`codesign --force --sign - "${targetPath}"`, {
15591
+ timeout: 1e4,
15592
+ stdio: ["pipe", "pipe", "pipe"]
15593
+ });
15594
+ } catch {
15595
+ }
15596
+ }
15597
+ (0, import_node_child_process2.execSync)(`"${targetPath}" --help`, { timeout: 1e4, stdio: ["pipe", "pipe", "pipe"] });
15598
+ } catch (err) {
15599
+ try {
15600
+ import_node_fs2.default.unlinkSync(targetPath);
15601
+ } catch {
15602
+ }
15603
+ const message = err instanceof Error ? err.message : String(err);
15604
+ throw new AgentRelayProcessError(`Failed to install broker binary: ${message}
15605
+ Install manually: curl -fsSL https://raw.githubusercontent.com/AgentWorkforce/relay/main/install.sh | bash`);
15606
+ }
15607
+ console.log(`[agent-relay] Broker installed to ${targetPath}`);
15608
+ return targetPath;
15609
+ }
15610
+ function resolveDefaultBinaryPath() {
15611
+ const brokerExe = process.platform === "win32" ? "agent-relay-broker.exe" : "agent-relay-broker";
15612
+ const moduleDir = import_node_path3.default.dirname((0, import_node_url.fileURLToPath)(import_meta_url));
15613
+ const workspaceRelease = import_node_path3.default.resolve(moduleDir, "..", "..", "..", "target", "release", brokerExe);
15614
+ if (import_node_fs2.default.existsSync(workspaceRelease)) {
15615
+ return workspaceRelease;
15616
+ }
15617
+ const binDir = import_node_path3.default.resolve(moduleDir, "..", "bin");
15618
+ const suffix = detectPlatformSuffix();
15619
+ if (suffix) {
15620
+ const ext = process.platform === "win32" ? ".exe" : "";
15621
+ const platformBinary = import_node_path3.default.join(binDir, `agent-relay-broker-${suffix}${ext}`);
15622
+ if (import_node_fs2.default.existsSync(platformBinary)) {
15623
+ return platformBinary;
15624
+ }
15625
+ }
15626
+ const homeDir = process.env.HOME || process.env.USERPROFILE || "";
15627
+ const standaloneBroker = import_node_path3.default.join(homeDir, ".agent-relay", "bin", brokerExe);
15628
+ if (import_node_fs2.default.existsSync(standaloneBroker)) {
15629
+ return standaloneBroker;
15630
+ }
15631
+ return installBrokerBinary();
15632
+ }
15633
+ var DEFAULT_DASHBOARD_PORT = (() => {
15634
+ const envPort = typeof process !== "undefined" ? process.env.AGENT_RELAY_DASHBOARD_PORT : void 0;
15635
+ if (envPort) {
15636
+ const parsed = Number.parseInt(envPort, 10);
15637
+ if (Number.isFinite(parsed) && parsed > 0)
15638
+ return parsed;
15639
+ }
15640
+ return 3888;
15641
+ })();
15642
+ var HTTP_MAX_PORT_SCAN = 25;
15643
+ var HTTP_AUTOSTART_TIMEOUT_MS = 1e4;
15644
+ var HTTP_AUTOSTART_POLL_MS = 250;
15645
+ function sanitizeBrokerName(name) {
15646
+ return name.replace(/[^\p{L}\p{N}-]/gu, "-");
15647
+ }
15648
+ function brokerPidFilename(projectRoot) {
15649
+ const brokerName = import_node_path3.default.basename(projectRoot) || "project";
15650
+ return `broker-${sanitizeBrokerName(brokerName)}.pid`;
15651
+ }
15652
+ var HttpAgentRelayClient = class _HttpAgentRelayClient {
15653
+ port;
15654
+ apiKey;
15655
+ constructor(options) {
15656
+ this.port = options.port;
15657
+ this.apiKey = options.apiKey;
15658
+ }
15659
+ /**
15660
+ * Connect to an already-running broker on the given port.
15661
+ */
15662
+ static async connectHttp(port, options) {
15663
+ const client = new _HttpAgentRelayClient({ port, apiKey: options?.apiKey });
15664
+ await client.healthCheck();
15665
+ return client;
15666
+ }
15667
+ /**
15668
+ * Discover a running broker for the current project and connect to it.
15669
+ * Reads the broker PID file, verifies the process is alive, scans ports
15670
+ * for the HTTP API, and returns a connected client.
15671
+ */
15672
+ static async discoverAndConnect(options) {
15673
+ const cwd = options?.cwd ?? process.cwd();
15674
+ const apiKey = options?.apiKey ?? process.env.RELAY_BROKER_API_KEY?.trim();
15675
+ const autoStart = options?.autoStart ?? false;
15676
+ const paths = getProjectPaths(cwd);
15677
+ const preferredApiPort = DEFAULT_DASHBOARD_PORT + 1;
15678
+ const pidFilePath = import_node_path3.default.join(paths.dataDir, brokerPidFilename(paths.projectRoot));
15679
+ const legacyPidPath = import_node_path3.default.join(paths.dataDir, "broker.pid");
15680
+ let brokerRunning = false;
15681
+ for (const pidPath of [pidFilePath, legacyPidPath]) {
15682
+ if (import_node_fs2.default.existsSync(pidPath)) {
15683
+ const pidStr = import_node_fs2.default.readFileSync(pidPath, "utf-8").trim();
15684
+ const pid = Number.parseInt(pidStr, 10);
15685
+ if (Number.isFinite(pid) && pid > 0) {
15686
+ try {
15687
+ process.kill(pid, 0);
15688
+ brokerRunning = true;
15689
+ break;
15690
+ } catch {
15691
+ }
15692
+ }
15693
+ }
15694
+ }
15695
+ if (brokerRunning) {
15696
+ const port = await _HttpAgentRelayClient.scanForBrokerPort(preferredApiPort);
15697
+ if (port !== null) {
15698
+ return new _HttpAgentRelayClient({ port, apiKey });
15699
+ }
15700
+ throw new AgentRelayProcessError("broker is running for this project, but its local API is unavailable");
15701
+ }
15702
+ if (!autoStart) {
15703
+ throw new AgentRelayProcessError("broker is not running for this project");
15704
+ }
15705
+ const brokerBinary = options?.brokerBinaryPath ?? resolveDefaultBinaryPath();
15706
+ const child = (0, import_node_child_process2.spawn)(brokerBinary, ["init", "--persist", "--api-port", String(preferredApiPort)], {
15707
+ cwd: paths.projectRoot,
15708
+ env: process.env,
15709
+ detached: true,
15710
+ stdio: "ignore"
15711
+ });
15712
+ child.unref();
15713
+ const startedAt = Date.now();
15714
+ while (Date.now() - startedAt < HTTP_AUTOSTART_TIMEOUT_MS) {
15715
+ const port = await _HttpAgentRelayClient.scanForBrokerPort(preferredApiPort);
15716
+ if (port !== null) {
15717
+ return new _HttpAgentRelayClient({ port, apiKey });
15718
+ }
15719
+ await new Promise((resolve3) => setTimeout(resolve3, HTTP_AUTOSTART_POLL_MS));
15720
+ }
15721
+ throw new AgentRelayProcessError(`broker did not become ready within ${HTTP_AUTOSTART_TIMEOUT_MS}ms`);
15722
+ }
15723
+ static async scanForBrokerPort(startPort) {
15724
+ for (let i = 0; i < HTTP_MAX_PORT_SCAN; i++) {
15725
+ const port = startPort + i;
15726
+ try {
15727
+ const res = await fetch(`http://127.0.0.1:${port}/health`);
15728
+ if (!res.ok)
15729
+ continue;
15730
+ const payload = await res.json().catch(() => null);
15731
+ if (payload?.service === "agent-relay-listen") {
15732
+ return port;
15733
+ }
15734
+ } catch {
15735
+ }
15736
+ }
15737
+ return null;
15738
+ }
15739
+ async request(pathname, init) {
15740
+ const headers = new Headers(init?.headers);
15741
+ if (this.apiKey && !headers.has("x-api-key") && !headers.has("authorization")) {
15742
+ headers.set("x-api-key", this.apiKey);
15743
+ }
15744
+ const response = await fetch(`http://127.0.0.1:${this.port}${pathname}`, {
15745
+ ...init,
15746
+ headers
15747
+ });
15748
+ const text = await response.text();
15749
+ let payload;
15750
+ try {
15751
+ payload = text ? JSON.parse(text) : void 0;
15752
+ } catch {
15753
+ payload = text;
15754
+ }
15755
+ if (!response.ok) {
15756
+ const msg = _HttpAgentRelayClient.extractErrorMessage(response, payload);
15757
+ throw new AgentRelayProcessError(msg);
15758
+ }
15759
+ return payload;
15760
+ }
15761
+ static extractErrorMessage(response, payload) {
15762
+ if (typeof payload === "string" && payload.trim())
15763
+ return payload.trim();
15764
+ const p = payload;
15765
+ if (typeof p?.error === "string")
15766
+ return p.error;
15767
+ if (typeof p?.error?.message === "string")
15768
+ return p.error.message;
15769
+ if (typeof p?.message === "string" && p.message.trim())
15770
+ return p.message.trim();
15771
+ return `${response.status} ${response.statusText}`.trim();
15772
+ }
15773
+ async healthCheck() {
15774
+ return this.request("/health");
15775
+ }
15776
+ /** No-op — broker is already running. */
15777
+ async start() {
15778
+ }
15779
+ /** No-op — don't kill an externally-managed broker. */
15780
+ async shutdown() {
15781
+ }
15782
+ async spawnPty(input) {
15783
+ const payload = await this.request("/api/spawn", {
15784
+ method: "POST",
15785
+ headers: { "content-type": "application/json" },
15786
+ body: JSON.stringify({
15787
+ name: input.name,
15788
+ cli: input.cli,
15789
+ model: input.model,
15790
+ args: input.args ?? [],
15791
+ task: input.task,
15792
+ channels: input.channels ?? [],
15793
+ cwd: input.cwd,
15794
+ team: input.team,
15795
+ shadowOf: input.shadowOf,
15796
+ shadowMode: input.shadowMode,
15797
+ continueFrom: input.continueFrom,
15798
+ idleThresholdSecs: input.idleThresholdSecs,
15799
+ restartPolicy: input.restartPolicy,
15800
+ skipRelayPrompt: input.skipRelayPrompt
15801
+ })
15802
+ });
15803
+ return {
15804
+ name: typeof payload?.name === "string" ? payload.name : input.name,
15805
+ runtime: "pty"
15806
+ };
15807
+ }
15808
+ async sendMessage(input) {
15809
+ return this.request("/api/send", {
15810
+ method: "POST",
15811
+ headers: { "content-type": "application/json" },
15812
+ body: JSON.stringify({
15813
+ to: input.to,
15814
+ text: input.text,
15815
+ from: input.from,
15816
+ threadId: input.threadId,
15817
+ workspaceId: input.workspaceId,
15818
+ workspaceAlias: input.workspaceAlias,
15819
+ priority: input.priority,
15820
+ data: input.data
15821
+ })
15822
+ });
15823
+ }
15824
+ async listAgents() {
15825
+ const payload = await this.request("/api/spawned", { method: "GET" });
15826
+ return Array.isArray(payload?.agents) ? payload.agents : [];
15827
+ }
15828
+ async release(name, reason) {
15829
+ const payload = await this.request(`/api/spawned/${encodeURIComponent(name)}`, {
15830
+ method: "DELETE",
15831
+ ...reason ? { headers: { "content-type": "application/json" }, body: JSON.stringify({ reason }) } : {}
15832
+ });
15833
+ return { name: typeof payload?.name === "string" ? payload.name : name };
15834
+ }
15835
+ async setModel(name, model, opts) {
15836
+ const payload = await this.request(`/api/spawned/${encodeURIComponent(name)}/model`, {
15837
+ method: "POST",
15838
+ headers: { "content-type": "application/json" },
15839
+ body: JSON.stringify({ model, timeoutMs: opts?.timeoutMs })
15840
+ });
15841
+ return {
15842
+ name,
15843
+ model: typeof payload?.model === "string" ? payload.model : model,
15844
+ success: payload?.success !== false
15845
+ };
15846
+ }
15847
+ async getConfig() {
15848
+ return this.request("/api/config");
15582
15849
  }
15583
- };
15584
- var DefaultModels = {
15585
- claude: "sonnet",
15586
- codex: "gpt-5.4",
15587
- gemini: "gemini-3.1-pro-preview",
15588
- cursor: "opus-4.6-thinking",
15589
- droid: "opus-4.6-fast",
15590
- opencode: "openai/gpt-5.2"
15591
15850
  };
15592
15851
 
15593
- // node_modules/@relaycast/sdk/dist/version.js
15852
+ // packages/sdk/node_modules/@relaycast/sdk/dist/version.js
15594
15853
  var SDK_VERSION = "0.4.2";
15595
15854
 
15596
- // node_modules/@relaycast/sdk/node_modules/zod/v4/classic/external.js
15855
+ // packages/sdk/node_modules/zod/v4/classic/external.js
15597
15856
  var external_exports2 = {};
15598
15857
  __export(external_exports2, {
15599
15858
  $brand: () => $brand,
@@ -15834,7 +16093,7 @@ __export(external_exports2, {
15834
16093
  xor: () => xor
15835
16094
  });
15836
16095
 
15837
- // node_modules/@relaycast/sdk/node_modules/zod/v4/core/index.js
16096
+ // packages/sdk/node_modules/zod/v4/core/index.js
15838
16097
  var core_exports2 = {};
15839
16098
  __export(core_exports2, {
15840
16099
  $ZodAny: () => $ZodAny,
@@ -16112,7 +16371,7 @@ __export(core_exports2, {
16112
16371
  version: () => version
16113
16372
  });
16114
16373
 
16115
- // node_modules/@relaycast/sdk/node_modules/zod/v4/core/core.js
16374
+ // packages/sdk/node_modules/zod/v4/core/core.js
16116
16375
  var NEVER2 = Object.freeze({
16117
16376
  status: "aborted"
16118
16377
  });
@@ -16187,7 +16446,7 @@ function config(newConfig) {
16187
16446
  return globalConfig;
16188
16447
  }
16189
16448
 
16190
- // node_modules/@relaycast/sdk/node_modules/zod/v4/core/util.js
16449
+ // packages/sdk/node_modules/zod/v4/core/util.js
16191
16450
  var util_exports = {};
16192
16451
  __export(util_exports, {
16193
16452
  BIGINT_FORMAT_RANGES: () => BIGINT_FORMAT_RANGES,
@@ -16866,7 +17125,7 @@ var Class = class {
16866
17125
  }
16867
17126
  };
16868
17127
 
16869
- // node_modules/@relaycast/sdk/node_modules/zod/v4/core/errors.js
17128
+ // packages/sdk/node_modules/zod/v4/core/errors.js
16870
17129
  var initializer = (inst, def) => {
16871
17130
  inst.name = "$ZodError";
16872
17131
  Object.defineProperty(inst, "_zod", {
@@ -17002,7 +17261,7 @@ function prettifyError(error48) {
17002
17261
  return lines.join("\n");
17003
17262
  }
17004
17263
 
17005
- // node_modules/@relaycast/sdk/node_modules/zod/v4/core/parse.js
17264
+ // packages/sdk/node_modules/zod/v4/core/parse.js
17006
17265
  var _parse = (_Err) => (schema, value, _ctx, _params) => {
17007
17266
  const ctx = _ctx ? Object.assign(_ctx, { async: false }) : { async: false };
17008
17267
  const result = schema._zod.run({ value, issues: [] }, ctx);
@@ -17090,7 +17349,7 @@ var _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {
17090
17349
  };
17091
17350
  var safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync($ZodRealError);
17092
17351
 
17093
- // node_modules/@relaycast/sdk/node_modules/zod/v4/core/regexes.js
17352
+ // packages/sdk/node_modules/zod/v4/core/regexes.js
17094
17353
  var regexes_exports = {};
17095
17354
  __export(regexes_exports, {
17096
17355
  base64: () => base64,
@@ -17247,7 +17506,7 @@ var sha512_hex = /^[0-9a-fA-F]{128}$/;
17247
17506
  var sha512_base64 = /* @__PURE__ */ fixedBase64(86, "==");
17248
17507
  var sha512_base64url = /* @__PURE__ */ fixedBase64url(86);
17249
17508
 
17250
- // node_modules/@relaycast/sdk/node_modules/zod/v4/core/checks.js
17509
+ // packages/sdk/node_modules/zod/v4/core/checks.js
17251
17510
  var $ZodCheck = /* @__PURE__ */ $constructor("$ZodCheck", (inst, def) => {
17252
17511
  var _a2;
17253
17512
  inst._zod ?? (inst._zod = {});
@@ -17795,7 +18054,7 @@ var $ZodCheckOverwrite = /* @__PURE__ */ $constructor("$ZodCheckOverwrite", (ins
17795
18054
  };
17796
18055
  });
17797
18056
 
17798
- // node_modules/@relaycast/sdk/node_modules/zod/v4/core/doc.js
18057
+ // packages/sdk/node_modules/zod/v4/core/doc.js
17799
18058
  var Doc = class {
17800
18059
  constructor(args = []) {
17801
18060
  this.content = [];
@@ -17831,14 +18090,14 @@ var Doc = class {
17831
18090
  }
17832
18091
  };
17833
18092
 
17834
- // node_modules/@relaycast/sdk/node_modules/zod/v4/core/versions.js
18093
+ // packages/sdk/node_modules/zod/v4/core/versions.js
17835
18094
  var version = {
17836
18095
  major: 4,
17837
18096
  minor: 3,
17838
18097
  patch: 6
17839
18098
  };
17840
18099
 
17841
- // node_modules/@relaycast/sdk/node_modules/zod/v4/core/schemas.js
18100
+ // packages/sdk/node_modules/zod/v4/core/schemas.js
17842
18101
  var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
17843
18102
  var _a2;
17844
18103
  inst ?? (inst = {});
@@ -19809,7 +20068,7 @@ function handleRefineResult(result, payload, input, inst) {
19809
20068
  }
19810
20069
  }
19811
20070
 
19812
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/index.js
20071
+ // packages/sdk/node_modules/zod/v4/locales/index.js
19813
20072
  var locales_exports = {};
19814
20073
  __export(locales_exports, {
19815
20074
  ar: () => ar_default,
@@ -19863,7 +20122,7 @@ __export(locales_exports, {
19863
20122
  zhTW: () => zh_TW_default
19864
20123
  });
19865
20124
 
19866
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ar.js
20125
+ // packages/sdk/node_modules/zod/v4/locales/ar.js
19867
20126
  var error = () => {
19868
20127
  const Sizable = {
19869
20128
  string: { unit: "\u062D\u0631\u0641", verb: "\u0623\u0646 \u064A\u062D\u0648\u064A" },
@@ -19970,7 +20229,7 @@ function ar_default() {
19970
20229
  };
19971
20230
  }
19972
20231
 
19973
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/az.js
20232
+ // packages/sdk/node_modules/zod/v4/locales/az.js
19974
20233
  var error2 = () => {
19975
20234
  const Sizable = {
19976
20235
  string: { unit: "simvol", verb: "olmal\u0131d\u0131r" },
@@ -20076,7 +20335,7 @@ function az_default() {
20076
20335
  };
20077
20336
  }
20078
20337
 
20079
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/be.js
20338
+ // packages/sdk/node_modules/zod/v4/locales/be.js
20080
20339
  function getBelarusianPlural(count, one, few, many) {
20081
20340
  const absCount = Math.abs(count);
20082
20341
  const lastDigit = absCount % 10;
@@ -20233,7 +20492,7 @@ function be_default() {
20233
20492
  };
20234
20493
  }
20235
20494
 
20236
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/bg.js
20495
+ // packages/sdk/node_modules/zod/v4/locales/bg.js
20237
20496
  var error4 = () => {
20238
20497
  const Sizable = {
20239
20498
  string: { unit: "\u0441\u0438\u043C\u0432\u043E\u043B\u0430", verb: "\u0434\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430" },
@@ -20354,7 +20613,7 @@ function bg_default() {
20354
20613
  };
20355
20614
  }
20356
20615
 
20357
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ca.js
20616
+ // packages/sdk/node_modules/zod/v4/locales/ca.js
20358
20617
  var error5 = () => {
20359
20618
  const Sizable = {
20360
20619
  string: { unit: "car\xE0cters", verb: "contenir" },
@@ -20463,7 +20722,7 @@ function ca_default() {
20463
20722
  };
20464
20723
  }
20465
20724
 
20466
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/cs.js
20725
+ // packages/sdk/node_modules/zod/v4/locales/cs.js
20467
20726
  var error6 = () => {
20468
20727
  const Sizable = {
20469
20728
  string: { unit: "znak\u016F", verb: "m\xEDt" },
@@ -20575,7 +20834,7 @@ function cs_default() {
20575
20834
  };
20576
20835
  }
20577
20836
 
20578
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/da.js
20837
+ // packages/sdk/node_modules/zod/v4/locales/da.js
20579
20838
  var error7 = () => {
20580
20839
  const Sizable = {
20581
20840
  string: { unit: "tegn", verb: "havde" },
@@ -20691,7 +20950,7 @@ function da_default() {
20691
20950
  };
20692
20951
  }
20693
20952
 
20694
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/de.js
20953
+ // packages/sdk/node_modules/zod/v4/locales/de.js
20695
20954
  var error8 = () => {
20696
20955
  const Sizable = {
20697
20956
  string: { unit: "Zeichen", verb: "zu haben" },
@@ -20800,7 +21059,7 @@ function de_default() {
20800
21059
  };
20801
21060
  }
20802
21061
 
20803
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/en.js
21062
+ // packages/sdk/node_modules/zod/v4/locales/en.js
20804
21063
  var error9 = () => {
20805
21064
  const Sizable = {
20806
21065
  string: { unit: "characters", verb: "to have" },
@@ -20909,7 +21168,7 @@ function en_default2() {
20909
21168
  };
20910
21169
  }
20911
21170
 
20912
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/eo.js
21171
+ // packages/sdk/node_modules/zod/v4/locales/eo.js
20913
21172
  var error10 = () => {
20914
21173
  const Sizable = {
20915
21174
  string: { unit: "karaktrojn", verb: "havi" },
@@ -21019,7 +21278,7 @@ function eo_default() {
21019
21278
  };
21020
21279
  }
21021
21280
 
21022
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/es.js
21281
+ // packages/sdk/node_modules/zod/v4/locales/es.js
21023
21282
  var error11 = () => {
21024
21283
  const Sizable = {
21025
21284
  string: { unit: "caracteres", verb: "tener" },
@@ -21152,7 +21411,7 @@ function es_default() {
21152
21411
  };
21153
21412
  }
21154
21413
 
21155
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/fa.js
21414
+ // packages/sdk/node_modules/zod/v4/locales/fa.js
21156
21415
  var error12 = () => {
21157
21416
  const Sizable = {
21158
21417
  string: { unit: "\u06A9\u0627\u0631\u0627\u06A9\u062A\u0631", verb: "\u062F\u0627\u0634\u062A\u0647 \u0628\u0627\u0634\u062F" },
@@ -21267,7 +21526,7 @@ function fa_default() {
21267
21526
  };
21268
21527
  }
21269
21528
 
21270
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/fi.js
21529
+ // packages/sdk/node_modules/zod/v4/locales/fi.js
21271
21530
  var error13 = () => {
21272
21531
  const Sizable = {
21273
21532
  string: { unit: "merkki\xE4", subject: "merkkijonon" },
@@ -21380,7 +21639,7 @@ function fi_default() {
21380
21639
  };
21381
21640
  }
21382
21641
 
21383
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/fr.js
21642
+ // packages/sdk/node_modules/zod/v4/locales/fr.js
21384
21643
  var error14 = () => {
21385
21644
  const Sizable = {
21386
21645
  string: { unit: "caract\xE8res", verb: "avoir" },
@@ -21489,7 +21748,7 @@ function fr_default() {
21489
21748
  };
21490
21749
  }
21491
21750
 
21492
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/fr-CA.js
21751
+ // packages/sdk/node_modules/zod/v4/locales/fr-CA.js
21493
21752
  var error15 = () => {
21494
21753
  const Sizable = {
21495
21754
  string: { unit: "caract\xE8res", verb: "avoir" },
@@ -21597,7 +21856,7 @@ function fr_CA_default() {
21597
21856
  };
21598
21857
  }
21599
21858
 
21600
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/he.js
21859
+ // packages/sdk/node_modules/zod/v4/locales/he.js
21601
21860
  var error16 = () => {
21602
21861
  const TypeNames = {
21603
21862
  string: { label: "\u05DE\u05D7\u05E8\u05D5\u05D6\u05EA", gender: "f" },
@@ -21792,7 +22051,7 @@ function he_default() {
21792
22051
  };
21793
22052
  }
21794
22053
 
21795
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/hu.js
22054
+ // packages/sdk/node_modules/zod/v4/locales/hu.js
21796
22055
  var error17 = () => {
21797
22056
  const Sizable = {
21798
22057
  string: { unit: "karakter", verb: "legyen" },
@@ -21901,7 +22160,7 @@ function hu_default() {
21901
22160
  };
21902
22161
  }
21903
22162
 
21904
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/hy.js
22163
+ // packages/sdk/node_modules/zod/v4/locales/hy.js
21905
22164
  function getArmenianPlural(count, one, many) {
21906
22165
  return Math.abs(count) === 1 ? one : many;
21907
22166
  }
@@ -22049,7 +22308,7 @@ function hy_default() {
22049
22308
  };
22050
22309
  }
22051
22310
 
22052
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/id.js
22311
+ // packages/sdk/node_modules/zod/v4/locales/id.js
22053
22312
  var error19 = () => {
22054
22313
  const Sizable = {
22055
22314
  string: { unit: "karakter", verb: "memiliki" },
@@ -22156,7 +22415,7 @@ function id_default() {
22156
22415
  };
22157
22416
  }
22158
22417
 
22159
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/is.js
22418
+ // packages/sdk/node_modules/zod/v4/locales/is.js
22160
22419
  var error20 = () => {
22161
22420
  const Sizable = {
22162
22421
  string: { unit: "stafi", verb: "a\xF0 hafa" },
@@ -22266,7 +22525,7 @@ function is_default() {
22266
22525
  };
22267
22526
  }
22268
22527
 
22269
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/it.js
22528
+ // packages/sdk/node_modules/zod/v4/locales/it.js
22270
22529
  var error21 = () => {
22271
22530
  const Sizable = {
22272
22531
  string: { unit: "caratteri", verb: "avere" },
@@ -22375,7 +22634,7 @@ function it_default() {
22375
22634
  };
22376
22635
  }
22377
22636
 
22378
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ja.js
22637
+ // packages/sdk/node_modules/zod/v4/locales/ja.js
22379
22638
  var error22 = () => {
22380
22639
  const Sizable = {
22381
22640
  string: { unit: "\u6587\u5B57", verb: "\u3067\u3042\u308B" },
@@ -22483,7 +22742,7 @@ function ja_default() {
22483
22742
  };
22484
22743
  }
22485
22744
 
22486
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ka.js
22745
+ // packages/sdk/node_modules/zod/v4/locales/ka.js
22487
22746
  var error23 = () => {
22488
22747
  const Sizable = {
22489
22748
  string: { unit: "\u10E1\u10D8\u10DB\u10D1\u10DD\u10DA\u10DD", verb: "\u10E3\u10DC\u10D3\u10D0 \u10E8\u10D4\u10D8\u10EA\u10D0\u10D5\u10D3\u10D4\u10E1" },
@@ -22596,7 +22855,7 @@ function ka_default() {
22596
22855
  };
22597
22856
  }
22598
22857
 
22599
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/km.js
22858
+ // packages/sdk/node_modules/zod/v4/locales/km.js
22600
22859
  var error24 = () => {
22601
22860
  const Sizable = {
22602
22861
  string: { unit: "\u178F\u17BD\u17A2\u1780\u17D2\u179F\u179A", verb: "\u1782\u17BD\u179A\u1798\u17B6\u1793" },
@@ -22707,12 +22966,12 @@ function km_default() {
22707
22966
  };
22708
22967
  }
22709
22968
 
22710
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/kh.js
22969
+ // packages/sdk/node_modules/zod/v4/locales/kh.js
22711
22970
  function kh_default() {
22712
22971
  return km_default();
22713
22972
  }
22714
22973
 
22715
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ko.js
22974
+ // packages/sdk/node_modules/zod/v4/locales/ko.js
22716
22975
  var error25 = () => {
22717
22976
  const Sizable = {
22718
22977
  string: { unit: "\uBB38\uC790", verb: "to have" },
@@ -22824,7 +23083,7 @@ function ko_default() {
22824
23083
  };
22825
23084
  }
22826
23085
 
22827
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/lt.js
23086
+ // packages/sdk/node_modules/zod/v4/locales/lt.js
22828
23087
  var capitalizeFirstCharacter = (text) => {
22829
23088
  return text.charAt(0).toUpperCase() + text.slice(1);
22830
23089
  };
@@ -23028,7 +23287,7 @@ function lt_default() {
23028
23287
  };
23029
23288
  }
23030
23289
 
23031
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/mk.js
23290
+ // packages/sdk/node_modules/zod/v4/locales/mk.js
23032
23291
  var error27 = () => {
23033
23292
  const Sizable = {
23034
23293
  string: { unit: "\u0437\u043D\u0430\u0446\u0438", verb: "\u0434\u0430 \u0438\u043C\u0430\u0430\u0442" },
@@ -23138,7 +23397,7 @@ function mk_default() {
23138
23397
  };
23139
23398
  }
23140
23399
 
23141
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ms.js
23400
+ // packages/sdk/node_modules/zod/v4/locales/ms.js
23142
23401
  var error28 = () => {
23143
23402
  const Sizable = {
23144
23403
  string: { unit: "aksara", verb: "mempunyai" },
@@ -23246,7 +23505,7 @@ function ms_default() {
23246
23505
  };
23247
23506
  }
23248
23507
 
23249
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/nl.js
23508
+ // packages/sdk/node_modules/zod/v4/locales/nl.js
23250
23509
  var error29 = () => {
23251
23510
  const Sizable = {
23252
23511
  string: { unit: "tekens", verb: "heeft" },
@@ -23357,7 +23616,7 @@ function nl_default() {
23357
23616
  };
23358
23617
  }
23359
23618
 
23360
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/no.js
23619
+ // packages/sdk/node_modules/zod/v4/locales/no.js
23361
23620
  var error30 = () => {
23362
23621
  const Sizable = {
23363
23622
  string: { unit: "tegn", verb: "\xE5 ha" },
@@ -23466,7 +23725,7 @@ function no_default() {
23466
23725
  };
23467
23726
  }
23468
23727
 
23469
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ota.js
23728
+ // packages/sdk/node_modules/zod/v4/locales/ota.js
23470
23729
  var error31 = () => {
23471
23730
  const Sizable = {
23472
23731
  string: { unit: "harf", verb: "olmal\u0131d\u0131r" },
@@ -23576,7 +23835,7 @@ function ota_default() {
23576
23835
  };
23577
23836
  }
23578
23837
 
23579
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ps.js
23838
+ // packages/sdk/node_modules/zod/v4/locales/ps.js
23580
23839
  var error32 = () => {
23581
23840
  const Sizable = {
23582
23841
  string: { unit: "\u062A\u0648\u06A9\u064A", verb: "\u0648\u0644\u0631\u064A" },
@@ -23691,7 +23950,7 @@ function ps_default() {
23691
23950
  };
23692
23951
  }
23693
23952
 
23694
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/pl.js
23953
+ // packages/sdk/node_modules/zod/v4/locales/pl.js
23695
23954
  var error33 = () => {
23696
23955
  const Sizable = {
23697
23956
  string: { unit: "znak\xF3w", verb: "mie\u0107" },
@@ -23801,7 +24060,7 @@ function pl_default() {
23801
24060
  };
23802
24061
  }
23803
24062
 
23804
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/pt.js
24063
+ // packages/sdk/node_modules/zod/v4/locales/pt.js
23805
24064
  var error34 = () => {
23806
24065
  const Sizable = {
23807
24066
  string: { unit: "caracteres", verb: "ter" },
@@ -23910,7 +24169,7 @@ function pt_default() {
23910
24169
  };
23911
24170
  }
23912
24171
 
23913
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ru.js
24172
+ // packages/sdk/node_modules/zod/v4/locales/ru.js
23914
24173
  function getRussianPlural(count, one, few, many) {
23915
24174
  const absCount = Math.abs(count);
23916
24175
  const lastDigit = absCount % 10;
@@ -24067,7 +24326,7 @@ function ru_default() {
24067
24326
  };
24068
24327
  }
24069
24328
 
24070
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/sl.js
24329
+ // packages/sdk/node_modules/zod/v4/locales/sl.js
24071
24330
  var error36 = () => {
24072
24331
  const Sizable = {
24073
24332
  string: { unit: "znakov", verb: "imeti" },
@@ -24177,7 +24436,7 @@ function sl_default() {
24177
24436
  };
24178
24437
  }
24179
24438
 
24180
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/sv.js
24439
+ // packages/sdk/node_modules/zod/v4/locales/sv.js
24181
24440
  var error37 = () => {
24182
24441
  const Sizable = {
24183
24442
  string: { unit: "tecken", verb: "att ha" },
@@ -24288,7 +24547,7 @@ function sv_default() {
24288
24547
  };
24289
24548
  }
24290
24549
 
24291
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ta.js
24550
+ // packages/sdk/node_modules/zod/v4/locales/ta.js
24292
24551
  var error38 = () => {
24293
24552
  const Sizable = {
24294
24553
  string: { unit: "\u0B8E\u0BB4\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1\u0B95\u0BCD\u0B95\u0BB3\u0BCD", verb: "\u0B95\u0BCA\u0BA3\u0BCD\u0B9F\u0BBF\u0BB0\u0BC1\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD" },
@@ -24399,7 +24658,7 @@ function ta_default() {
24399
24658
  };
24400
24659
  }
24401
24660
 
24402
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/th.js
24661
+ // packages/sdk/node_modules/zod/v4/locales/th.js
24403
24662
  var error39 = () => {
24404
24663
  const Sizable = {
24405
24664
  string: { unit: "\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23", verb: "\u0E04\u0E27\u0E23\u0E21\u0E35" },
@@ -24510,7 +24769,7 @@ function th_default() {
24510
24769
  };
24511
24770
  }
24512
24771
 
24513
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/tr.js
24772
+ // packages/sdk/node_modules/zod/v4/locales/tr.js
24514
24773
  var error40 = () => {
24515
24774
  const Sizable = {
24516
24775
  string: { unit: "karakter", verb: "olmal\u0131" },
@@ -24616,7 +24875,7 @@ function tr_default() {
24616
24875
  };
24617
24876
  }
24618
24877
 
24619
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/uk.js
24878
+ // packages/sdk/node_modules/zod/v4/locales/uk.js
24620
24879
  var error41 = () => {
24621
24880
  const Sizable = {
24622
24881
  string: { unit: "\u0441\u0438\u043C\u0432\u043E\u043B\u0456\u0432", verb: "\u043C\u0430\u0442\u0438\u043C\u0435" },
@@ -24725,12 +24984,12 @@ function uk_default() {
24725
24984
  };
24726
24985
  }
24727
24986
 
24728
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ua.js
24987
+ // packages/sdk/node_modules/zod/v4/locales/ua.js
24729
24988
  function ua_default() {
24730
24989
  return uk_default();
24731
24990
  }
24732
24991
 
24733
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ur.js
24992
+ // packages/sdk/node_modules/zod/v4/locales/ur.js
24734
24993
  var error42 = () => {
24735
24994
  const Sizable = {
24736
24995
  string: { unit: "\u062D\u0631\u0648\u0641", verb: "\u06C1\u0648\u0646\u0627" },
@@ -24841,7 +25100,7 @@ function ur_default() {
24841
25100
  };
24842
25101
  }
24843
25102
 
24844
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/uz.js
25103
+ // packages/sdk/node_modules/zod/v4/locales/uz.js
24845
25104
  var error43 = () => {
24846
25105
  const Sizable = {
24847
25106
  string: { unit: "belgi", verb: "bo\u2018lishi kerak" },
@@ -24951,7 +25210,7 @@ function uz_default() {
24951
25210
  };
24952
25211
  }
24953
25212
 
24954
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/vi.js
25213
+ // packages/sdk/node_modules/zod/v4/locales/vi.js
24955
25214
  var error44 = () => {
24956
25215
  const Sizable = {
24957
25216
  string: { unit: "k\xFD t\u1EF1", verb: "c\xF3" },
@@ -25060,7 +25319,7 @@ function vi_default() {
25060
25319
  };
25061
25320
  }
25062
25321
 
25063
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/zh-CN.js
25322
+ // packages/sdk/node_modules/zod/v4/locales/zh-CN.js
25064
25323
  var error45 = () => {
25065
25324
  const Sizable = {
25066
25325
  string: { unit: "\u5B57\u7B26", verb: "\u5305\u542B" },
@@ -25170,7 +25429,7 @@ function zh_CN_default() {
25170
25429
  };
25171
25430
  }
25172
25431
 
25173
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/zh-TW.js
25432
+ // packages/sdk/node_modules/zod/v4/locales/zh-TW.js
25174
25433
  var error46 = () => {
25175
25434
  const Sizable = {
25176
25435
  string: { unit: "\u5B57\u5143", verb: "\u64C1\u6709" },
@@ -25278,7 +25537,7 @@ function zh_TW_default() {
25278
25537
  };
25279
25538
  }
25280
25539
 
25281
- // node_modules/@relaycast/sdk/node_modules/zod/v4/locales/yo.js
25540
+ // packages/sdk/node_modules/zod/v4/locales/yo.js
25282
25541
  var error47 = () => {
25283
25542
  const Sizable = {
25284
25543
  string: { unit: "\xE0mi", verb: "n\xED" },
@@ -25386,7 +25645,7 @@ function yo_default() {
25386
25645
  };
25387
25646
  }
25388
25647
 
25389
- // node_modules/@relaycast/sdk/node_modules/zod/v4/core/registries.js
25648
+ // packages/sdk/node_modules/zod/v4/core/registries.js
25390
25649
  var _a;
25391
25650
  var $output = /* @__PURE__ */ Symbol("ZodOutput");
25392
25651
  var $input = /* @__PURE__ */ Symbol("ZodInput");
@@ -25436,7 +25695,7 @@ function registry() {
25436
25695
  (_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());
25437
25696
  var globalRegistry = globalThis.__zod_globalRegistry;
25438
25697
 
25439
- // node_modules/@relaycast/sdk/node_modules/zod/v4/core/api.js
25698
+ // packages/sdk/node_modules/zod/v4/core/api.js
25440
25699
  // @__NO_SIDE_EFFECTS__
25441
25700
  function _string(Class2, params) {
25442
25701
  return new Class2({
@@ -26475,7 +26734,7 @@ function _stringFormat(Class2, format, fnOrRegex, _params = {}) {
26475
26734
  return inst;
26476
26735
  }
26477
26736
 
26478
- // node_modules/@relaycast/sdk/node_modules/zod/v4/core/to-json-schema.js
26737
+ // packages/sdk/node_modules/zod/v4/core/to-json-schema.js
26479
26738
  function initializeContext(params) {
26480
26739
  let target = params?.target ?? "draft-2020-12";
26481
26740
  if (target === "draft-4")
@@ -26827,7 +27086,7 @@ var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) =
26827
27086
  return finalize(ctx, schema);
26828
27087
  };
26829
27088
 
26830
- // node_modules/@relaycast/sdk/node_modules/zod/v4/core/json-schema-processors.js
27089
+ // packages/sdk/node_modules/zod/v4/core/json-schema-processors.js
26831
27090
  var formatMap = {
26832
27091
  guid: "uuid",
26833
27092
  url: "uri",
@@ -27378,7 +27637,7 @@ function toJSONSchema(input, params) {
27378
27637
  return finalize(ctx, input);
27379
27638
  }
27380
27639
 
27381
- // node_modules/@relaycast/sdk/node_modules/zod/v4/core/json-schema-generator.js
27640
+ // packages/sdk/node_modules/zod/v4/core/json-schema-generator.js
27382
27641
  var JSONSchemaGenerator = class {
27383
27642
  /** @deprecated Access via ctx instead */
27384
27643
  get metadataRegistry() {
@@ -27453,10 +27712,10 @@ var JSONSchemaGenerator = class {
27453
27712
  }
27454
27713
  };
27455
27714
 
27456
- // node_modules/@relaycast/sdk/node_modules/zod/v4/core/json-schema.js
27715
+ // packages/sdk/node_modules/zod/v4/core/json-schema.js
27457
27716
  var json_schema_exports = {};
27458
27717
 
27459
- // node_modules/@relaycast/sdk/node_modules/zod/v4/classic/schemas.js
27718
+ // packages/sdk/node_modules/zod/v4/classic/schemas.js
27460
27719
  var schemas_exports2 = {};
27461
27720
  __export(schemas_exports2, {
27462
27721
  ZodAny: () => ZodAny2,
@@ -27625,7 +27884,7 @@ __export(schemas_exports2, {
27625
27884
  xor: () => xor
27626
27885
  });
27627
27886
 
27628
- // node_modules/@relaycast/sdk/node_modules/zod/v4/classic/checks.js
27887
+ // packages/sdk/node_modules/zod/v4/classic/checks.js
27629
27888
  var checks_exports2 = {};
27630
27889
  __export(checks_exports2, {
27631
27890
  endsWith: () => _endsWith,
@@ -27659,7 +27918,7 @@ __export(checks_exports2, {
27659
27918
  uppercase: () => _uppercase
27660
27919
  });
27661
27920
 
27662
- // node_modules/@relaycast/sdk/node_modules/zod/v4/classic/iso.js
27921
+ // packages/sdk/node_modules/zod/v4/classic/iso.js
27663
27922
  var iso_exports = {};
27664
27923
  __export(iso_exports, {
27665
27924
  ZodISODate: () => ZodISODate,
@@ -27700,7 +27959,7 @@ function duration2(params) {
27700
27959
  return _isoDuration(ZodISODuration, params);
27701
27960
  }
27702
27961
 
27703
- // node_modules/@relaycast/sdk/node_modules/zod/v4/classic/errors.js
27962
+ // packages/sdk/node_modules/zod/v4/classic/errors.js
27704
27963
  var initializer2 = (inst, issues) => {
27705
27964
  $ZodError.init(inst, issues);
27706
27965
  inst.name = "ZodError";
@@ -27740,7 +27999,7 @@ var ZodRealError = $constructor("ZodError", initializer2, {
27740
27999
  Parent: Error
27741
28000
  });
27742
28001
 
27743
- // node_modules/@relaycast/sdk/node_modules/zod/v4/classic/parse.js
28002
+ // packages/sdk/node_modules/zod/v4/classic/parse.js
27744
28003
  var parse2 = /* @__PURE__ */ _parse(ZodRealError);
27745
28004
  var parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError);
27746
28005
  var safeParse2 = /* @__PURE__ */ _safeParse(ZodRealError);
@@ -27754,7 +28013,7 @@ var safeDecode2 = /* @__PURE__ */ _safeDecode(ZodRealError);
27754
28013
  var safeEncodeAsync2 = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
27755
28014
  var safeDecodeAsync2 = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
27756
28015
 
27757
- // node_modules/@relaycast/sdk/node_modules/zod/v4/classic/schemas.js
28016
+ // packages/sdk/node_modules/zod/v4/classic/schemas.js
27758
28017
  var ZodType2 = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
27759
28018
  $ZodType.init(inst, def);
27760
28019
  Object.assign(inst["~standard"], {
@@ -28833,7 +29092,7 @@ function preprocess(fn, schema) {
28833
29092
  return pipe(transform(fn), schema);
28834
29093
  }
28835
29094
 
28836
- // node_modules/@relaycast/sdk/node_modules/zod/v4/classic/compat.js
29095
+ // packages/sdk/node_modules/zod/v4/classic/compat.js
28837
29096
  var ZodIssueCode2 = {
28838
29097
  invalid_type: "invalid_type",
28839
29098
  too_big: "too_big",
@@ -28859,7 +29118,7 @@ var ZodFirstPartyTypeKind2;
28859
29118
  /* @__PURE__ */ (function(ZodFirstPartyTypeKind3) {
28860
29119
  })(ZodFirstPartyTypeKind2 || (ZodFirstPartyTypeKind2 = {}));
28861
29120
 
28862
- // node_modules/@relaycast/sdk/node_modules/zod/v4/classic/from-json-schema.js
29121
+ // packages/sdk/node_modules/zod/v4/classic/from-json-schema.js
28863
29122
  var z = {
28864
29123
  ...schemas_exports2,
28865
29124
  ...checks_exports2,
@@ -29333,7 +29592,7 @@ function fromJSONSchema(schema, params) {
29333
29592
  return convertSchema(schema, ctx);
29334
29593
  }
29335
29594
 
29336
- // node_modules/@relaycast/sdk/node_modules/zod/v4/classic/coerce.js
29595
+ // packages/sdk/node_modules/zod/v4/classic/coerce.js
29337
29596
  var coerce_exports = {};
29338
29597
  __export(coerce_exports, {
29339
29598
  bigint: () => bigint3,
@@ -29358,10 +29617,10 @@ function date4(params) {
29358
29617
  return _coercedDate(ZodDate2, params);
29359
29618
  }
29360
29619
 
29361
- // node_modules/@relaycast/sdk/node_modules/zod/v4/classic/external.js
29620
+ // packages/sdk/node_modules/zod/v4/classic/external.js
29362
29621
  config(en_default2());
29363
29622
 
29364
- // node_modules/@relaycast/sdk/node_modules/@relaycast/types/dist/workspace.js
29623
+ // packages/sdk/node_modules/@relaycast/types/dist/workspace.js
29365
29624
  var WorkspaceSchema = external_exports2.object({
29366
29625
  id: external_exports2.string(),
29367
29626
  name: external_exports2.string(),
@@ -29416,7 +29675,7 @@ var TokenRotateResponseSchema = external_exports2.object({
29416
29675
  token: external_exports2.string()
29417
29676
  });
29418
29677
 
29419
- // node_modules/@relaycast/sdk/node_modules/@relaycast/types/dist/agent.js
29678
+ // packages/sdk/node_modules/@relaycast/types/dist/agent.js
29420
29679
  var AgentTypeSchema = external_exports2.enum(["agent", "human", "system"]);
29421
29680
  var AgentStatusSchema = external_exports2.enum(["online", "offline", "away"]);
29422
29681
  var AgentSchema = external_exports2.object({
@@ -29493,7 +29752,7 @@ var ReleaseAgentResponseSchema = external_exports2.object({
29493
29752
  reason: external_exports2.string().nullable()
29494
29753
  });
29495
29754
 
29496
- // node_modules/@relaycast/sdk/node_modules/@relaycast/types/dist/channel.js
29755
+ // packages/sdk/node_modules/@relaycast/types/dist/channel.js
29497
29756
  var ChannelMemberInfoSchema = external_exports2.object({
29498
29757
  agent_id: external_exports2.string(),
29499
29758
  agent_name: external_exports2.string(),
@@ -29540,7 +29799,7 @@ var InviteChannelResponseSchema = external_exports2.object({
29540
29799
  agent: external_exports2.string()
29541
29800
  });
29542
29801
 
29543
- // node_modules/@relaycast/sdk/node_modules/@relaycast/types/dist/file.js
29802
+ // packages/sdk/node_modules/@relaycast/types/dist/file.js
29544
29803
  var FileStatusSchema = external_exports2.enum(["pending", "complete", "deleted"]);
29545
29804
  var FileRecordSchema = external_exports2.object({
29546
29805
  id: external_exports2.string(),
@@ -29587,7 +29846,7 @@ var CompleteUploadResponseSchema = external_exports2.object({
29587
29846
  download_url: external_exports2.string()
29588
29847
  });
29589
29848
 
29590
- // node_modules/@relaycast/sdk/node_modules/@relaycast/types/dist/reaction.js
29849
+ // packages/sdk/node_modules/@relaycast/types/dist/reaction.js
29591
29850
  var ReactionSchema = external_exports2.object({
29592
29851
  id: external_exports2.string(),
29593
29852
  message_id: external_exports2.string(),
@@ -29611,7 +29870,7 @@ var ReactionGroupSchema = external_exports2.object({
29611
29870
  agents: external_exports2.array(external_exports2.string())
29612
29871
  });
29613
29872
 
29614
- // node_modules/@relaycast/sdk/node_modules/@relaycast/types/dist/message.js
29873
+ // packages/sdk/node_modules/@relaycast/types/dist/message.js
29615
29874
  var HeaderBlockSchema = external_exports2.object({
29616
29875
  type: external_exports2.literal("header"),
29617
29876
  text: external_exports2.string()
@@ -29701,7 +29960,7 @@ var SearchMessageResultSchema = external_exports2.object({
29701
29960
  relevance_score: external_exports2.number()
29702
29961
  });
29703
29962
 
29704
- // node_modules/@relaycast/sdk/node_modules/@relaycast/types/dist/receipt.js
29963
+ // packages/sdk/node_modules/@relaycast/types/dist/receipt.js
29705
29964
  var ReadReceiptSchema = external_exports2.object({
29706
29965
  message_id: external_exports2.string(),
29707
29966
  agent_id: external_exports2.string(),
@@ -29718,7 +29977,7 @@ var ChannelReadStatusSchema = external_exports2.object({
29718
29977
  last_read_at: external_exports2.string().nullable()
29719
29978
  });
29720
29979
 
29721
- // node_modules/@relaycast/sdk/node_modules/@relaycast/types/dist/dm.js
29980
+ // packages/sdk/node_modules/@relaycast/types/dist/dm.js
29722
29981
  var DmTypeSchema = external_exports2.enum(["1:1", "group"]);
29723
29982
  var DmConversationSchema = external_exports2.object({
29724
29983
  id: external_exports2.string(),
@@ -29790,7 +30049,7 @@ var GroupDmParticipantResponseSchema = external_exports2.object({
29790
30049
  already_member: external_exports2.boolean()
29791
30050
  });
29792
30051
 
29793
- // node_modules/@relaycast/sdk/node_modules/@relaycast/types/dist/events.js
30052
+ // packages/sdk/node_modules/@relaycast/types/dist/events.js
29794
30053
  var SubscribeEventSchema = external_exports2.object({
29795
30054
  type: external_exports2.literal("subscribe"),
29796
30055
  channels: external_exports2.array(external_exports2.string())
@@ -30001,7 +30260,7 @@ var WsClientEventSchema = external_exports2.discriminatedUnion("type", [
30001
30260
  WsCloseEventSchema
30002
30261
  ]);
30003
30262
 
30004
- // node_modules/@relaycast/sdk/node_modules/@relaycast/types/dist/api.js
30263
+ // packages/sdk/node_modules/@relaycast/types/dist/api.js
30005
30264
  var ApiErrorSchema = external_exports2.object({
30006
30265
  ok: external_exports2.literal(false),
30007
30266
  error: external_exports2.object({
@@ -30027,7 +30286,7 @@ var InboxResponseSchema = external_exports2.object({
30027
30286
  }))
30028
30287
  });
30029
30288
 
30030
- // node_modules/@relaycast/sdk/node_modules/@relaycast/types/dist/webhook.js
30289
+ // packages/sdk/node_modules/@relaycast/types/dist/webhook.js
30031
30290
  var WebhookSchema = external_exports2.object({
30032
30291
  id: external_exports2.string(),
30033
30292
  name: external_exports2.string(),
@@ -30061,7 +30320,7 @@ var WebhookTriggerResponseSchema = external_exports2.object({
30061
30320
  created_at: external_exports2.string()
30062
30321
  });
30063
30322
 
30064
- // node_modules/@relaycast/sdk/node_modules/@relaycast/types/dist/subscription.js
30323
+ // packages/sdk/node_modules/@relaycast/types/dist/subscription.js
30065
30324
  var SubscribableEventTypeSchema = external_exports2.enum([
30066
30325
  "message.created",
30067
30326
  "message.updated",
@@ -30109,7 +30368,7 @@ var CreateSubscriptionResponseSchema = external_exports2.object({
30109
30368
  created_at: external_exports2.string()
30110
30369
  });
30111
30370
 
30112
- // node_modules/@relaycast/sdk/node_modules/@relaycast/types/dist/command.js
30371
+ // packages/sdk/node_modules/@relaycast/types/dist/command.js
30113
30372
  var CommandParameterSchema = external_exports2.object({
30114
30373
  name: external_exports2.string(),
30115
30374
  description: external_exports2.string().optional(),
@@ -30156,7 +30415,7 @@ var CommandInvocationSchema = external_exports2.object({
30156
30415
  created_at: external_exports2.string()
30157
30416
  });
30158
30417
 
30159
- // node_modules/@relaycast/sdk/node_modules/@relaycast/types/dist/telemetry.js
30418
+ // packages/sdk/node_modules/@relaycast/types/dist/telemetry.js
30160
30419
  var TELEMETRY_MAX_PROPERTIES = 64;
30161
30420
  var TELEMETRY_VALUE_MAX_LENGTH = 512;
30162
30421
  var telemetryString = (max) => external_exports2.string().trim().min(1).max(max);
@@ -30259,14 +30518,14 @@ var internalTelemetryEventSchema = telemetryEnvelopeBaseSchema.extend({
30259
30518
  event: telemetryEventSchema
30260
30519
  }).merge(telemetryOriginSchema);
30261
30520
 
30262
- // node_modules/@relaycast/sdk/dist/origin.js
30521
+ // packages/sdk/node_modules/@relaycast/sdk/dist/origin.js
30263
30522
  var SDK_ORIGIN = Object.freeze({
30264
30523
  surface: "sdk",
30265
30524
  client: "@relaycast/sdk",
30266
30525
  version: SDK_VERSION
30267
30526
  });
30268
30527
 
30269
- // node_modules/@relaycast/sdk/dist/casing.js
30528
+ // packages/sdk/node_modules/@relaycast/sdk/dist/casing.js
30270
30529
  function isPlainObject2(value) {
30271
30530
  if (Object.prototype.toString.call(value) !== "[object Object]")
30272
30531
  return false;
@@ -30309,7 +30568,7 @@ function decamelizeKey(key) {
30309
30568
  return toSnakeKey(key);
30310
30569
  }
30311
30570
 
30312
- // node_modules/@relaycast/sdk/dist/ws.js
30571
+ // packages/sdk/node_modules/@relaycast/sdk/dist/ws.js
30313
30572
  var INTERNAL_WS_ORIGIN = /* @__PURE__ */ Symbol("relaycast.internal.ws-origin");
30314
30573
  function readInternalWsOrigin(options) {
30315
30574
  return options[INTERNAL_WS_ORIGIN];
@@ -30573,7 +30832,7 @@ var WsClient = class {
30573
30832
  }
30574
30833
  };
30575
30834
 
30576
- // node_modules/@relaycast/sdk/dist/agent.js
30835
+ // packages/sdk/node_modules/@relaycast/sdk/dist/agent.js
30577
30836
  function stripHash(channel) {
30578
30837
  return channel.startsWith("#") ? channel.slice(1) : channel;
30579
30838
  }
@@ -30882,7 +31141,7 @@ var AgentClient = class {
30882
31141
  };
30883
31142
  };
30884
31143
 
30885
- // node_modules/@relaycast/sdk/dist/errors.js
31144
+ // packages/sdk/node_modules/@relaycast/sdk/dist/errors.js
30886
31145
  var RAW_CODE_MAP = {
30887
31146
  name_conflict: "name_conflict",
30888
31147
  agent_already_exists: "name_conflict",
@@ -30941,7 +31200,7 @@ function relayErrorFromApi(rawCode, message, statusCode) {
30941
31200
  return new RelayError(code, message, { statusCode, rawCode });
30942
31201
  }
30943
31202
 
30944
- // node_modules/@relaycast/sdk/dist/client.js
31203
+ // packages/sdk/node_modules/@relaycast/sdk/dist/client.js
30945
31204
  var INTERNAL_ORIGIN = /* @__PURE__ */ Symbol("relaycast.internal.origin");
30946
31205
  function readInternalOrigin(options) {
30947
31206
  return options[INTERNAL_ORIGIN];
@@ -31136,7 +31395,7 @@ var HttpClient = class _HttpClient {
31136
31395
  }
31137
31396
  };
31138
31397
 
31139
- // node_modules/@relaycast/sdk/dist/identity.js
31398
+ // packages/sdk/node_modules/@relaycast/sdk/dist/identity.js
31140
31399
  var COMPAT_EVENT_NAME = "relaycast.compatibility";
31141
31400
  var emittedCompatibilityEvents = /* @__PURE__ */ new Set();
31142
31401
  function emitCompatibilityTelemetry(event, metadata = {}) {
@@ -31159,7 +31418,7 @@ function isNameConflictError(err) {
31159
31418
  return err instanceof RelayError && err.code === "name_conflict";
31160
31419
  }
31161
31420
 
31162
- // node_modules/@relaycast/sdk/dist/relay.js
31421
+ // packages/sdk/node_modules/@relaycast/sdk/dist/relay.js
31163
31422
  var RelayCast = class {
31164
31423
  client;
31165
31424
  identityHint = null;
@@ -31425,7 +31684,7 @@ function cleanLines(raw) {
31425
31684
  }
31426
31685
 
31427
31686
  // packages/sdk/dist/relay.js
31428
- var import_node_crypto = require("node:crypto");
31687
+ var import_node_crypto2 = require("node:crypto");
31429
31688
  var import_node_path5 = __toESM(require("node:path"), 1);
31430
31689
 
31431
31690
  // packages/sdk/dist/logs.js
@@ -31843,7 +32102,7 @@ var AgentRelay = class {
31843
32102
  if (result?.event_id === "unsupported_operation") {
31844
32103
  return buildUnsupportedOperationMessage(opts.name, input);
31845
32104
  }
31846
- const eventId = result?.event_id ?? (0, import_node_crypto.randomBytes)(8).toString("hex");
32105
+ const eventId = result?.event_id ?? (0, import_node_crypto2.randomBytes)(8).toString("hex");
31847
32106
  const msg = {
31848
32107
  eventId,
31849
32108
  from: opts.name,
@@ -32505,7 +32764,7 @@ var AgentRelay = class {
32505
32764
  if (result?.event_id === "unsupported_operation") {
32506
32765
  return buildUnsupportedOperationMessage(name, input);
32507
32766
  }
32508
- const eventId = result?.event_id ?? (0, import_node_crypto.randomBytes)(8).toString("hex");
32767
+ const eventId = result?.event_id ?? (0, import_node_crypto2.randomBytes)(8).toString("hex");
32509
32768
  const msg = {
32510
32769
  eventId,
32511
32770
  from: name,
@@ -32622,7 +32881,7 @@ var AgentRelay = class {
32622
32881
  };
32623
32882
 
32624
32883
  // packages/sdk/dist/consensus.js
32625
- var import_node_crypto2 = require("node:crypto");
32884
+ var import_node_crypto3 = require("node:crypto");
32626
32885
  var import_node_events2 = require("node:events");
32627
32886
 
32628
32887
  // packages/sdk/dist/consensus-helpers.js
@@ -32759,7 +33018,7 @@ var ConsensusEngine = class extends import_node_events2.EventEmitter {
32759
33018
  }
32760
33019
  // ── Proposal management ──────────────────────────────────────────────────
32761
33020
  createProposal(options) {
32762
- const id = `prop_${Date.now()}_${(0, import_node_crypto2.randomBytes)(4).toString("hex")}`;
33021
+ const id = `prop_${Date.now()}_${(0, import_node_crypto3.randomBytes)(4).toString("hex")}`;
32763
33022
  const now = Date.now();
32764
33023
  const timeoutMs = options.timeoutMs ?? this.config.defaultTimeoutMs;
32765
33024
  const proposal = {
@@ -33427,8 +33686,8 @@ function isAgentStep(step) {
33427
33686
 
33428
33687
  // packages/sdk/dist/workflows/runner.js
33429
33688
  var import_node_child_process3 = require("node:child_process");
33430
- var import_node_crypto4 = require("node:crypto");
33431
- var import_node_fs4 = require("node:fs");
33689
+ var import_node_crypto5 = require("node:crypto");
33690
+ var import_node_fs5 = require("node:fs");
33432
33691
  var import_promises3 = require("node:fs/promises");
33433
33692
  var import_node_path8 = __toESM(require("node:path"), 1);
33434
33693
  var import_yaml2 = __toESM(require_dist(), 1);
@@ -33559,18 +33818,18 @@ async function spawnFromEnv(options = {}) {
33559
33818
  }
33560
33819
 
33561
33820
  // packages/sdk/dist/workflows/custom-steps.js
33562
- var import_node_fs2 = require("node:fs");
33821
+ var import_node_fs3 = require("node:fs");
33563
33822
  var import_node_path6 = __toESM(require("node:path"), 1);
33564
33823
  var import_yaml = __toESM(require_dist(), 1);
33565
33824
  var CUSTOM_STEPS_FILE = ".relay/steps.yaml";
33566
33825
  function loadCustomSteps(cwd) {
33567
33826
  const stepsPath = import_node_path6.default.join(cwd, CUSTOM_STEPS_FILE);
33568
33827
  const steps = /* @__PURE__ */ new Map();
33569
- if (!(0, import_node_fs2.existsSync)(stepsPath)) {
33828
+ if (!(0, import_node_fs3.existsSync)(stepsPath)) {
33570
33829
  return steps;
33571
33830
  }
33572
33831
  try {
33573
- const content = (0, import_node_fs2.readFileSync)(stepsPath, "utf-8");
33832
+ const content = (0, import_node_fs3.readFileSync)(stepsPath, "utf-8");
33574
33833
  if (!content.trim()) {
33575
33834
  return steps;
33576
33835
  }
@@ -33820,7 +34079,7 @@ function resolveAllCustomSteps(steps, customSteps) {
33820
34079
  return steps.map((step) => resolveCustomStep(step, customSteps));
33821
34080
  }
33822
34081
  function customStepsFileExists(cwd) {
33823
- return (0, import_node_fs2.existsSync)(import_node_path6.default.join(cwd, CUSTOM_STEPS_FILE));
34082
+ return (0, import_node_fs3.existsSync)(import_node_path6.default.join(cwd, CUSTOM_STEPS_FILE));
33824
34083
  }
33825
34084
  function getCustomStepsPath(cwd) {
33826
34085
  return import_node_path6.default.join(cwd, CUSTOM_STEPS_FILE);
@@ -33857,8 +34116,8 @@ var InMemoryWorkflowDb = class {
33857
34116
  };
33858
34117
 
33859
34118
  // packages/sdk/dist/workflows/trajectory.js
33860
- var import_node_crypto3 = require("node:crypto");
33861
- var import_node_fs3 = require("node:fs");
34119
+ var import_node_crypto4 = require("node:crypto");
34120
+ var import_node_fs4 = require("node:fs");
33862
34121
  var import_promises2 = require("node:fs/promises");
33863
34122
  var import_node_path7 = __toESM(require("node:path"), 1);
33864
34123
  function classifyFailure(error48) {
@@ -33921,7 +34180,7 @@ var WorkflowTrajectory = class {
33921
34180
  return;
33922
34181
  this.startTime = Date.now();
33923
34182
  this.swarmPattern = pattern ?? "dag";
33924
- const id = `traj_${Date.now()}_${(0, import_node_crypto3.randomBytes)(4).toString("hex")}`;
34183
+ const id = `traj_${Date.now()}_${(0, import_node_crypto4.randomBytes)(4).toString("hex")}`;
33925
34184
  this.trajectory = {
33926
34185
  id,
33927
34186
  version: 1,
@@ -34264,7 +34523,7 @@ var WorkflowTrajectory = class {
34264
34523
  if (!this.trajectory)
34265
34524
  return;
34266
34525
  const chapter = {
34267
- id: `ch_${(0, import_node_crypto3.randomBytes)(4).toString("hex")}`,
34526
+ id: `ch_${(0, import_node_crypto4.randomBytes)(4).toString("hex")}`,
34268
34527
  title,
34269
34528
  agentName,
34270
34529
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -34337,7 +34596,7 @@ var WorkflowTrajectory = class {
34337
34596
  await (0, import_promises2.mkdir)(completedDir, { recursive: true });
34338
34597
  const activePath = import_node_path7.default.join(activeDir, `${this.trajectory.id}.json`);
34339
34598
  const completedPath = import_node_path7.default.join(completedDir, `${this.trajectory.id}.json`);
34340
- if ((0, import_node_fs3.existsSync)(activePath)) {
34599
+ if ((0, import_node_fs4.existsSync)(activePath)) {
34341
34600
  await (0, import_promises2.rename)(activePath, completedPath);
34342
34601
  }
34343
34602
  } catch {
@@ -34475,7 +34734,7 @@ var WorkflowRunner = class _WorkflowRunner {
34475
34734
  const abs = import_node_path8.default.resolve(baseCwd, expanded);
34476
34735
  resolved.set(pd.name, abs);
34477
34736
  const isRequired = pd.required !== false;
34478
- if (!(0, import_node_fs4.existsSync)(abs)) {
34737
+ if (!(0, import_node_fs5.existsSync)(abs)) {
34479
34738
  if (isRequired) {
34480
34739
  errors.push(`Path "${pd.name}" resolves to "${abs}" which does not exist (required)`);
34481
34740
  } else {
@@ -34809,12 +35068,12 @@ ${next}` : next;
34809
35068
  }
34810
35069
  captureFileSnapshot(root) {
34811
35070
  const snapshot = /* @__PURE__ */ new Map();
34812
- if (!(0, import_node_fs4.existsSync)(root))
35071
+ if (!(0, import_node_fs5.existsSync)(root))
34813
35072
  return snapshot;
34814
35073
  const visit = (currentPath) => {
34815
35074
  let entries;
34816
35075
  try {
34817
- entries = (0, import_node_fs4.readdirSync)(currentPath, { withFileTypes: true });
35076
+ entries = (0, import_node_fs5.readdirSync)(currentPath, { withFileTypes: true });
34818
35077
  } catch {
34819
35078
  return;
34820
35079
  }
@@ -34828,7 +35087,7 @@ ${next}` : next;
34828
35087
  continue;
34829
35088
  }
34830
35089
  try {
34831
- const stats = (0, import_node_fs4.statSync)(fullPath);
35090
+ const stats = (0, import_node_fs5.statSync)(fullPath);
34832
35091
  if (!stats.isFile())
34833
35092
  continue;
34834
35093
  snapshot.set(fullPath, { mtimeMs: stats.mtimeMs, size: stats.size });
@@ -34837,7 +35096,7 @@ ${next}` : next;
34837
35096
  }
34838
35097
  };
34839
35098
  try {
34840
- const stats = (0, import_node_fs4.statSync)(root);
35099
+ const stats = (0, import_node_fs5.statSync)(root);
34841
35100
  if (stats.isFile()) {
34842
35101
  snapshot.set(root, { mtimeMs: stats.mtimeMs, size: stats.size });
34843
35102
  return snapshot;
@@ -34958,7 +35217,7 @@ ${next}` : next;
34958
35217
  this.relayApiKey = envKey;
34959
35218
  return;
34960
35219
  }
34961
- const workspaceName = `relay-${channel}-${(0, import_node_crypto4.randomBytes)(4).toString("hex")}`;
35220
+ const workspaceName = `relay-${channel}-${(0, import_node_crypto5.randomBytes)(4).toString("hex")}`;
34962
35221
  const baseUrl = this.relayOptions.env?.RELAYCAST_BASE_URL ?? process.env.RELAYCAST_BASE_URL ?? "https://api.relaycast.dev";
34963
35222
  const res = await fetch(`${baseUrl}/v1/workspaces`, {
34964
35223
  method: "POST",
@@ -35022,7 +35281,7 @@ ${next}` : next;
35022
35281
  } catch (err) {
35023
35282
  if (err instanceof RelayError && err.code === "name_conflict") {
35024
35283
  registration = await rc.agents.register({
35025
- name: `WorkflowRunner-${(0, import_node_crypto4.randomBytes)(4).toString("hex")}`,
35284
+ name: `WorkflowRunner-${(0, import_node_crypto5.randomBytes)(4).toString("hex")}`,
35026
35285
  type: "agent"
35027
35286
  });
35028
35287
  } else {
@@ -35239,14 +35498,14 @@ ${err.suggestion}`);
35239
35498
  for (const agent of resolved.agents) {
35240
35499
  if (agent.cwd) {
35241
35500
  const resolvedCwd = import_node_path8.default.resolve(this.cwd, agent.cwd);
35242
- if (!(0, import_node_fs4.existsSync)(resolvedCwd)) {
35501
+ if (!(0, import_node_fs5.existsSync)(resolvedCwd)) {
35243
35502
  warnings.push(`Agent "${agent.name}" cwd "${agent.cwd}" resolves to "${resolvedCwd}" which does not exist`);
35244
35503
  }
35245
35504
  }
35246
35505
  if (agent.additionalPaths) {
35247
35506
  for (const ap of agent.additionalPaths) {
35248
35507
  const resolvedPath = import_node_path8.default.resolve(this.cwd, ap);
35249
- if (!(0, import_node_fs4.existsSync)(resolvedPath)) {
35508
+ if (!(0, import_node_fs5.existsSync)(resolvedPath)) {
35250
35509
  warnings.push(`Agent "${agent.name}" additionalPath "${ap}" resolves to "${resolvedPath}" which does not exist`);
35251
35510
  }
35252
35511
  }
@@ -35560,7 +35819,7 @@ ${err.suggestion}`);
35560
35819
  }
35561
35820
  // ── Execution ───────────────────────────────────────────────────────────
35562
35821
  /** Execute a named workflow from a validated config. */
35563
- async execute(config2, workflowName, vars) {
35822
+ async execute(config2, workflowName, vars, executeOptions) {
35564
35823
  this.abortController = new AbortController();
35565
35824
  this.paused = false;
35566
35825
  const resolved = vars ? this.resolveVariables(config2, vars) : config2;
@@ -35617,6 +35876,37 @@ ${err.suggestion}`);
35617
35876
  await this.db.insertStep(stepRow);
35618
35877
  stepStates.set(step.name, { row: stepRow });
35619
35878
  }
35879
+ if (executeOptions?.startFrom) {
35880
+ const startFromName = executeOptions.startFrom;
35881
+ const stepNames = new Set(resolvedWorkflow.steps.map((s) => s.name));
35882
+ if (!stepNames.has(startFromName)) {
35883
+ throw new Error(`startFrom step "${startFromName}" not found in workflow. Available steps: ${[...stepNames].join(", ")}`);
35884
+ }
35885
+ const transitiveDeps = this.collectTransitiveDeps(startFromName, resolvedWorkflow.steps);
35886
+ const skippedCount = transitiveDeps.size;
35887
+ const cacheRunId = executeOptions.previousRunId ?? this.findMostRecentRunWithSteps(transitiveDeps);
35888
+ for (const depName of transitiveDeps) {
35889
+ const state = stepStates.get(depName);
35890
+ if (!state)
35891
+ continue;
35892
+ const cachedOutput = cacheRunId ? this.loadStepOutput(cacheRunId, depName) : void 0;
35893
+ if (!cachedOutput) {
35894
+ this.log(`[startFrom] No cached output for skipped step "${depName}" \u2014 using empty string`);
35895
+ }
35896
+ state.row.status = "completed";
35897
+ state.row.output = cachedOutput ?? "";
35898
+ state.row.completedAt = now;
35899
+ await this.db.updateStep(state.row.id, {
35900
+ status: "completed",
35901
+ output: state.row.output,
35902
+ completedAt: now,
35903
+ updatedAt: now
35904
+ });
35905
+ }
35906
+ if (skippedCount > 0) {
35907
+ this.log(`[startFrom] Skipping ${skippedCount} steps, starting from "${startFromName}"`);
35908
+ }
35909
+ }
35620
35910
  return this.runWorkflowCore({
35621
35911
  run,
35622
35912
  workflow: resolvedWorkflow,
@@ -37672,7 +37962,7 @@ DO NOT:
37672
37962
  const { cmd, args } = _WorkflowRunner.buildNonInteractiveCommand(agentDef.cli, taskWithDeliverable, modelArgs);
37673
37963
  const logsDir = this.getWorkerLogsDir();
37674
37964
  const logPath = import_node_path8.default.join(logsDir, `${agentName}.log`);
37675
- const logStream = (0, import_node_fs4.createWriteStream)(logPath, { flags: "a" });
37965
+ const logStream = (0, import_node_fs5.createWriteStream)(logPath, { flags: "a" });
37676
37966
  this.registerWorker(agentName, agentDef.cli, step.task ?? "", void 0, false);
37677
37967
  let stopHeartbeat;
37678
37968
  if (this.relayApiKey) {
@@ -37808,7 +38098,7 @@ DO NOT:
37808
38098
  const taskWithExit = step.task + (relayRegistrationNote ? "\n\n" + relayRegistrationNote : "") + (delegationGuidance ? "\n\n" + delegationGuidance + "\n" : "") + '\n\n---\nIMPORTANT: When you have fully completed this task, you MUST self-terminate by either: (a) calling remove_agent(name: "<your-agent-name>", reason: "task completed") \u2014 preferred, or (b) outputting the exact text "/exit" on its own line as a fallback. Do not wait for further input \u2014 terminate immediately after finishing. Do NOT spawn sub-agents unless the task explicitly requires it.';
37809
38099
  this.ptyOutputBuffers.set(agentName, []);
37810
38100
  const logsDir = this.getWorkerLogsDir();
37811
- const logStream = (0, import_node_fs4.createWriteStream)(import_node_path8.default.join(logsDir, `${agentName}.log`), { flags: "a" });
38101
+ const logStream = (0, import_node_fs5.createWriteStream)(import_node_path8.default.join(logsDir, `${agentName}.log`), { flags: "a" });
37812
38102
  this.ptyLogStreams.set(agentName, logStream);
37813
38103
  this.ptyListeners.set(agentName, (chunk) => {
37814
38104
  const stripped = _WorkflowRunner.stripAnsi(chunk);
@@ -37850,11 +38140,11 @@ DO NOT:
37850
38140
  oldLogStream.end();
37851
38141
  this.ptyLogStreams.delete(oldName);
37852
38142
  try {
37853
- (0, import_node_fs4.renameSync)(oldLogPath, newLogPath);
38143
+ (0, import_node_fs5.renameSync)(oldLogPath, newLogPath);
37854
38144
  } catch {
37855
38145
  }
37856
38146
  }
37857
- const newLogStream = (0, import_node_fs4.createWriteStream)(newLogPath, { flags: "a" });
38147
+ const newLogStream = (0, import_node_fs5.createWriteStream)(newLogPath, { flags: "a" });
37858
38148
  this.ptyLogStreams.set(agent.name, newLogStream);
37859
38149
  const oldListener = this.ptyListeners.get(oldName);
37860
38150
  if (oldListener) {
@@ -37959,7 +38249,7 @@ DO NOT:
37959
38249
  output = ptyChunks.join("");
37960
38250
  } else {
37961
38251
  const summaryPath = import_node_path8.default.join(this.summaryDir, `${step.name}.md`);
37962
- output = (0, import_node_fs4.existsSync)(summaryPath) ? await (0, import_promises3.readFile)(summaryPath, "utf-8") : exitResult === "timeout" ? "Agent completed (released after idle timeout)" : exitResult === "released" ? "Agent completed (idle \u2014 treated as done)" : `Agent exited (${exitResult})`;
38252
+ output = (0, import_node_fs5.existsSync)(summaryPath) ? await (0, import_promises3.readFile)(summaryPath, "utf-8") : exitResult === "timeout" ? "Agent completed (released after idle timeout)" : exitResult === "released" ? "Agent completed (idle \u2014 treated as done)" : `Agent exited (${exitResult})`;
37963
38253
  }
37964
38254
  if (ptyChunks.length === 0) {
37965
38255
  this.captureStepTerminalEvidence(evidenceStepName, { stdout: output, combined: output }, { exitCode: agent?.exitCode, exitSignal: agent?.exitSignal }, {
@@ -38210,7 +38500,7 @@ DO NOT:
38210
38500
  case "exit_code":
38211
38501
  break;
38212
38502
  case "file_exists":
38213
- if (!(0, import_node_fs4.existsSync)(import_node_path8.default.resolve(this.cwd, check2.value))) {
38503
+ if (!(0, import_node_fs5.existsSync)(import_node_path8.default.resolve(this.cwd, check2.value))) {
38214
38504
  return fail(`Verification failed for "${stepName}": file "${check2.value}" does not exist`);
38215
38505
  }
38216
38506
  break;
@@ -38304,6 +38594,33 @@ DO NOT:
38304
38594
  }
38305
38595
  }
38306
38596
  }
38597
+ // ── startFrom dependency resolution ─────────────────────────────────
38598
+ /**
38599
+ * Walk the dependsOn graph backwards from a target step to collect ALL
38600
+ * transitive dependencies (i.e. every step that must complete before
38601
+ * the target step can run). The target step itself is NOT included.
38602
+ */
38603
+ collectTransitiveDeps(targetStep, steps) {
38604
+ const stepMap = /* @__PURE__ */ new Map();
38605
+ for (const s of steps)
38606
+ stepMap.set(s.name, s);
38607
+ const deps = /* @__PURE__ */ new Set();
38608
+ const queue = [...stepMap.get(targetStep)?.dependsOn ?? []];
38609
+ while (queue.length > 0) {
38610
+ const current = queue.shift();
38611
+ if (deps.has(current))
38612
+ continue;
38613
+ deps.add(current);
38614
+ const step = stepMap.get(current);
38615
+ if (step?.dependsOn) {
38616
+ for (const dep of step.dependsOn) {
38617
+ if (!deps.has(dep))
38618
+ queue.push(dep);
38619
+ }
38620
+ }
38621
+ }
38622
+ return deps;
38623
+ }
38307
38624
  // ── Control flow helpers ──────────────────────────────────────────────
38308
38625
  checkAborted() {
38309
38626
  if (this.abortController?.signal.aborted) {
@@ -38549,10 +38866,10 @@ ${excerpt}` : "";
38549
38866
  }
38550
38867
  // ── ID generation ─────────────────────────────────────────────────────
38551
38868
  generateId() {
38552
- return (0, import_node_crypto4.randomBytes)(12).toString("hex");
38869
+ return (0, import_node_crypto5.randomBytes)(12).toString("hex");
38553
38870
  }
38554
38871
  generateShortId() {
38555
- return (0, import_node_crypto4.randomBytes)(4).toString("hex");
38872
+ return (0, import_node_crypto5.randomBytes)(4).toString("hex");
38556
38873
  }
38557
38874
  /** Strip ANSI escape codes from terminal output — delegates to pty.ts canonical regex. */
38558
38875
  static stripAnsi(text) {
@@ -38653,7 +38970,7 @@ ${excerpt}` : "";
38653
38970
  const outputPath = import_node_path8.default.join(this.getStepOutputDir(runId), `${stepName}.md`);
38654
38971
  try {
38655
38972
  const dir = this.getStepOutputDir(runId);
38656
- (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
38973
+ (0, import_node_fs5.mkdirSync)(dir, { recursive: true });
38657
38974
  const cleaned = _WorkflowRunner.stripAnsi(output);
38658
38975
  await (0, import_promises3.writeFile)(outputPath, cleaned);
38659
38976
  } catch {
@@ -38675,13 +38992,42 @@ ${excerpt}` : "";
38675
38992
  ${preview}
38676
38993
  \`\`\``, { stepName });
38677
38994
  }
38995
+ /** Scan .agent-relay/step-outputs/ for the most recent run directory containing the needed steps. */
38996
+ findMostRecentRunWithSteps(stepNames) {
38997
+ try {
38998
+ const baseDir = import_node_path8.default.join(this.cwd, ".agent-relay", "step-outputs");
38999
+ if (!(0, import_node_fs5.existsSync)(baseDir))
39000
+ return void 0;
39001
+ const entries = (0, import_node_fs5.readdirSync)(baseDir);
39002
+ let best;
39003
+ for (const entry of entries) {
39004
+ const dirPath = import_node_path8.default.join(baseDir, entry);
39005
+ try {
39006
+ const stat2 = (0, import_node_fs5.statSync)(dirPath);
39007
+ if (!stat2.isDirectory())
39008
+ continue;
39009
+ const hasAny = [...stepNames].some((name) => (0, import_node_fs5.existsSync)(import_node_path8.default.join(dirPath, `${name}.md`)));
39010
+ if (!hasAny)
39011
+ continue;
39012
+ if (!best || stat2.mtimeMs > best.mtime) {
39013
+ best = { name: entry, mtime: stat2.mtimeMs };
39014
+ }
39015
+ } catch {
39016
+ continue;
39017
+ }
39018
+ }
39019
+ return best?.name;
39020
+ } catch {
39021
+ return void 0;
39022
+ }
39023
+ }
38678
39024
  /** Load persisted step output from disk. */
38679
39025
  loadStepOutput(runId, stepName) {
38680
39026
  try {
38681
39027
  const filePath = import_node_path8.default.join(this.getStepOutputDir(runId), `${stepName}.md`);
38682
- if (!(0, import_node_fs4.existsSync)(filePath))
39028
+ if (!(0, import_node_fs5.existsSync)(filePath))
38683
39029
  return void 0;
38684
- return (0, import_node_fs4.readFileSync)(filePath, "utf-8");
39030
+ return (0, import_node_fs5.readFileSync)(filePath, "utf-8");
38685
39031
  } catch {
38686
39032
  return void 0;
38687
39033
  }
@@ -38689,7 +39035,7 @@ ${preview}
38689
39035
  /** Get or create the worker logs directory (.agent-relay/team/worker-logs) */
38690
39036
  getWorkerLogsDir() {
38691
39037
  const logsDir = import_node_path8.default.join(this.cwd, ".agent-relay", "team", "worker-logs");
38692
- (0, import_node_fs4.mkdirSync)(logsDir, { recursive: true });
39038
+ (0, import_node_fs5.mkdirSync)(logsDir, { recursive: true });
38693
39039
  return logsDir;
38694
39040
  }
38695
39041
  /** Register a spawned agent in workers.json so `agents:kill` can find it. */
@@ -38705,7 +39051,7 @@ ${preview}
38705
39051
  this.activeWorkers.set(agentName, workerEntry);
38706
39052
  this.workersFileLock = this.workersFileLock.then(() => {
38707
39053
  try {
38708
- (0, import_node_fs4.mkdirSync)(import_node_path8.default.dirname(this.workersPath), { recursive: true });
39054
+ (0, import_node_fs5.mkdirSync)(import_node_path8.default.dirname(this.workersPath), { recursive: true });
38709
39055
  const existing = this.readWorkers().filter((w) => w.name !== agentName);
38710
39056
  existing.push({ name: agentName, ...workerEntry });
38711
39057
  this.writeWorkers(existing);
@@ -38727,21 +39073,21 @@ ${preview}
38727
39073
  }
38728
39074
  readWorkers() {
38729
39075
  try {
38730
- if (!(0, import_node_fs4.existsSync)(this.workersPath))
39076
+ if (!(0, import_node_fs5.existsSync)(this.workersPath))
38731
39077
  return [];
38732
- const raw = JSON.parse((0, import_node_fs4.readFileSync)(this.workersPath, "utf-8"));
39078
+ const raw = JSON.parse((0, import_node_fs5.readFileSync)(this.workersPath, "utf-8"));
38733
39079
  return Array.isArray(raw?.workers) ? raw.workers : [];
38734
39080
  } catch {
38735
39081
  return [];
38736
39082
  }
38737
39083
  }
38738
39084
  writeWorkers(workers) {
38739
- (0, import_node_fs4.writeFileSync)(this.workersPath, JSON.stringify({ workers }, null, 2));
39085
+ (0, import_node_fs5.writeFileSync)(this.workersPath, JSON.stringify({ workers }, null, 2));
38740
39086
  }
38741
39087
  };
38742
39088
 
38743
39089
  // packages/sdk/dist/workflows/file-db.js
38744
- var import_node_fs5 = require("node:fs");
39090
+ var import_node_fs6 = require("node:fs");
38745
39091
  var import_node_path9 = __toESM(require("node:path"), 1);
38746
39092
  var JsonFileWorkflowDb = class {
38747
39093
  filePath;
@@ -38751,7 +39097,7 @@ var JsonFileWorkflowDb = class {
38751
39097
  this.filePath = filePath;
38752
39098
  let writable = false;
38753
39099
  try {
38754
- (0, import_node_fs5.mkdirSync)(import_node_path9.default.dirname(filePath), { recursive: true });
39100
+ (0, import_node_fs6.mkdirSync)(import_node_path9.default.dirname(filePath), { recursive: true });
38755
39101
  writable = true;
38756
39102
  } catch {
38757
39103
  }
@@ -38766,7 +39112,7 @@ var JsonFileWorkflowDb = class {
38766
39112
  if (!this.writable)
38767
39113
  return;
38768
39114
  try {
38769
- (0, import_node_fs5.appendFileSync)(this.filePath, JSON.stringify(entry) + "\n", "utf8");
39115
+ (0, import_node_fs6.appendFileSync)(this.filePath, JSON.stringify(entry) + "\n", "utf8");
38770
39116
  } catch {
38771
39117
  }
38772
39118
  }
@@ -38776,7 +39122,7 @@ var JsonFileWorkflowDb = class {
38776
39122
  const steps = /* @__PURE__ */ new Map();
38777
39123
  let raw = "";
38778
39124
  try {
38779
- raw = (0, import_node_fs5.readFileSync)(this.filePath, "utf8");
39125
+ raw = (0, import_node_fs6.readFileSync)(this.filePath, "utf8");
38780
39126
  } catch {
38781
39127
  return { runs, steps };
38782
39128
  }
@@ -38922,6 +39268,11 @@ var WorkflowBuilder = class {
38922
39268
  _agents = [];
38923
39269
  _steps = [];
38924
39270
  _errorHandling;
39271
+ _coordination;
39272
+ _state;
39273
+ _trajectories;
39274
+ _startFrom;
39275
+ _previousRunId;
38925
39276
  constructor(name) {
38926
39277
  this._name = name;
38927
39278
  }
@@ -38955,6 +39306,31 @@ var WorkflowBuilder = class {
38955
39306
  this._idleNudge = config2;
38956
39307
  return this;
38957
39308
  }
39309
+ /** Set workflow coordination settings (barriers, voting threshold, consensus strategy). */
39310
+ coordination(config2) {
39311
+ this._coordination = config2;
39312
+ return this;
39313
+ }
39314
+ /** Configure shared workflow state backend settings. */
39315
+ state(config2) {
39316
+ this._state = config2;
39317
+ return this;
39318
+ }
39319
+ /** Configure trajectory recording, or pass `false` to disable it. */
39320
+ trajectories(config2) {
39321
+ this._trajectories = config2;
39322
+ return this;
39323
+ }
39324
+ /** Start execution from a specific step, skipping all predecessor steps. */
39325
+ startFrom(stepName) {
39326
+ this._startFrom = stepName;
39327
+ return this;
39328
+ }
39329
+ /** Set the previous run ID whose cached step outputs should be used with startFrom. */
39330
+ previousRunId(id) {
39331
+ this._previousRunId = id;
39332
+ return this;
39333
+ }
38958
39334
  /** Add an agent definition. */
38959
39335
  agent(name, options) {
38960
39336
  const def = {
@@ -38991,25 +39367,56 @@ var WorkflowBuilder = class {
38991
39367
  step(name, options) {
38992
39368
  const step = { name };
38993
39369
  if ("type" in options && options.type === "deterministic") {
39370
+ if (!options.command) {
39371
+ throw new Error("deterministic steps must have a command");
39372
+ }
39373
+ if ("agent" in options || "task" in options) {
39374
+ throw new Error("deterministic steps must not have agent or task");
39375
+ }
38994
39376
  step.type = "deterministic";
38995
39377
  step.command = options.command;
38996
- if (options.failOnError !== void 0)
38997
- step.failOnError = options.failOnError;
38998
39378
  if (options.captureOutput !== void 0)
38999
39379
  step.captureOutput = options.captureOutput;
39380
+ if (options.failOnError !== void 0)
39381
+ step.failOnError = options.failOnError;
39382
+ if (options.dependsOn !== void 0)
39383
+ step.dependsOn = options.dependsOn;
39384
+ if (options.verification !== void 0)
39385
+ step.verification = options.verification;
39386
+ if (options.timeoutMs !== void 0)
39387
+ step.timeoutMs = options.timeoutMs;
39388
+ } else if ("type" in options && options.type === "worktree") {
39389
+ if ("agent" in options || "task" in options) {
39390
+ throw new Error("worktree steps must not have agent or task");
39391
+ }
39392
+ step.type = "worktree";
39393
+ step.branch = options.branch;
39394
+ if (options.baseBranch !== void 0)
39395
+ step.baseBranch = options.baseBranch;
39396
+ if (options.path !== void 0)
39397
+ step.path = options.path;
39398
+ if (options.createBranch !== void 0)
39399
+ step.createBranch = options.createBranch;
39400
+ if (options.dependsOn !== void 0)
39401
+ step.dependsOn = options.dependsOn;
39402
+ if (options.timeoutMs !== void 0)
39403
+ step.timeoutMs = options.timeoutMs;
39000
39404
  } else {
39001
39405
  const agentOpts = options;
39406
+ if (!agentOpts.agent || !agentOpts.task) {
39407
+ throw new Error("Agent steps must have both agent and task");
39408
+ }
39002
39409
  step.agent = agentOpts.agent;
39003
39410
  step.task = agentOpts.task;
39411
+ if (agentOpts.dependsOn !== void 0)
39412
+ step.dependsOn = agentOpts.dependsOn;
39004
39413
  if (agentOpts.verification !== void 0)
39005
39414
  step.verification = agentOpts.verification;
39415
+ if (agentOpts.timeoutMs !== void 0)
39416
+ step.timeoutMs = agentOpts.timeoutMs;
39006
39417
  if (agentOpts.retries !== void 0)
39007
39418
  step.retries = agentOpts.retries;
39008
39419
  }
39009
- if (options.dependsOn !== void 0)
39010
- step.dependsOn = options.dependsOn;
39011
- if (options.timeoutMs !== void 0)
39012
- step.timeoutMs = options.timeoutMs;
39013
39420
  this._steps.push(step);
39014
39421
  return this;
39015
39422
  }
@@ -39058,6 +39465,12 @@ var WorkflowBuilder = class {
39058
39465
  config2.swarm.idleNudge = this._idleNudge;
39059
39466
  if (this._errorHandling !== void 0)
39060
39467
  config2.errorHandling = this._errorHandling;
39468
+ if (this._coordination !== void 0)
39469
+ config2.coordination = this._coordination;
39470
+ if (this._state !== void 0)
39471
+ config2.state = this._state;
39472
+ if (this._trajectories !== void 0)
39473
+ config2.trajectories = this._trajectories;
39061
39474
  return config2;
39062
39475
  }
39063
39476
  /** Serialize the config to a YAML string. */
@@ -39080,7 +39493,10 @@ var WorkflowBuilder = class {
39080
39493
  if (options.onEvent) {
39081
39494
  runner.on(options.onEvent);
39082
39495
  }
39083
- return runner.execute(config2, options.workflow, options.vars);
39496
+ const startFrom = this._startFrom ?? options.startFrom;
39497
+ const previousRunId = this._previousRunId ?? options.previousRunId;
39498
+ const executeOptions = startFrom ? { startFrom, previousRunId } : void 0;
39499
+ return runner.execute(config2, options.workflow, options.vars, executeOptions);
39084
39500
  }
39085
39501
  };
39086
39502
  function workflow(name) {
@@ -39088,7 +39504,7 @@ function workflow(name) {
39088
39504
  }
39089
39505
 
39090
39506
  // packages/sdk/dist/workflows/coordinator.js
39091
- var import_node_crypto5 = require("node:crypto");
39507
+ var import_node_crypto6 = require("node:crypto");
39092
39508
  var import_node_events3 = require("node:events");
39093
39509
  var PATTERN_HEURISTICS = [
39094
39510
  // ── Dependency-based patterns (highest priority) ──────────────────────
@@ -39443,7 +39859,7 @@ var SwarmCoordinator = class extends import_node_events3.EventEmitter {
39443
39859
  }
39444
39860
  // ── Lifecycle: create run ───────────────────────────────────────────────
39445
39861
  async createRun(workspaceId, config2) {
39446
- const id = `run_${Date.now()}_${(0, import_node_crypto5.randomBytes)(4).toString("hex")}`;
39862
+ const id = `run_${Date.now()}_${(0, import_node_crypto6.randomBytes)(4).toString("hex")}`;
39447
39863
  const pattern = this.selectPattern(config2);
39448
39864
  const now = (/* @__PURE__ */ new Date()).toISOString();
39449
39865
  const { rows } = await this.db.query(`INSERT INTO workflow_runs (id, workspace_id, workflow_name, pattern, status, config, started_at, created_at, updated_at)
@@ -39482,7 +39898,7 @@ var SwarmCoordinator = class extends import_node_events3.EventEmitter {
39482
39898
  const created = [];
39483
39899
  for (const wf of workflows) {
39484
39900
  for (const step of wf.steps) {
39485
- const id = `step_${Date.now()}_${(0, import_node_crypto5.randomBytes)(4).toString("hex")}`;
39901
+ const id = `step_${Date.now()}_${(0, import_node_crypto6.randomBytes)(4).toString("hex")}`;
39486
39902
  const now = (/* @__PURE__ */ new Date()).toISOString();
39487
39903
  const { rows } = await this.db.query(`INSERT INTO workflow_steps (id, run_id, step_name, agent_name, status, task, depends_on, created_at, updated_at)
39488
39904
  VALUES ($1, $2, $3, $4, 'pending', $5, $6, $7, $7)
@@ -39659,7 +40075,7 @@ var SwarmCoordinator = class extends import_node_events3.EventEmitter {
39659
40075
  };
39660
40076
 
39661
40077
  // packages/sdk/dist/workflows/barrier.js
39662
- var import_node_crypto6 = require("node:crypto");
40078
+ var import_node_crypto7 = require("node:crypto");
39663
40079
  var import_node_events4 = require("node:events");
39664
40080
  var BarrierManager = class extends import_node_events4.EventEmitter {
39665
40081
  db;
@@ -39675,7 +40091,7 @@ var BarrierManager = class extends import_node_events4.EventEmitter {
39675
40091
  * Create a barrier for a workflow run.
39676
40092
  */
39677
40093
  async createBarrier(runId, definition) {
39678
- const id = `bar_${Date.now()}_${(0, import_node_crypto6.randomBytes)(4).toString("hex")}`;
40094
+ const id = `bar_${Date.now()}_${(0, import_node_crypto7.randomBytes)(4).toString("hex")}`;
39679
40095
  const now = (/* @__PURE__ */ new Date()).toISOString();
39680
40096
  const mode = definition.mode ?? "all";
39681
40097
  const { rows } = await this.db.query(`INSERT INTO workflow_barriers (id, run_id, barrier_name, wait_for, resolved, is_satisfied, timeout_ms, created_at, updated_at)
@@ -39809,7 +40225,7 @@ var BarrierManager = class extends import_node_events4.EventEmitter {
39809
40225
  };
39810
40226
 
39811
40227
  // packages/sdk/dist/workflows/state.js
39812
- var import_node_crypto7 = require("node:crypto");
40228
+ var import_node_crypto8 = require("node:crypto");
39813
40229
  var import_node_events5 = require("node:events");
39814
40230
  var StateStore = class extends import_node_events5.EventEmitter {
39815
40231
  db;
@@ -39852,7 +40268,7 @@ var StateStore = class extends import_node_events5.EventEmitter {
39852
40268
  const namespace = options.namespace ?? this.defaultNamespace;
39853
40269
  const ttlMs = options.ttlMs ?? this.defaultTtlMs;
39854
40270
  const expiresAt = ttlMs ? new Date(Date.now() + ttlMs).toISOString() : null;
39855
- const id = `st_${Date.now()}_${(0, import_node_crypto7.randomBytes)(4).toString("hex")}`;
40271
+ const id = `st_${Date.now()}_${(0, import_node_crypto8.randomBytes)(4).toString("hex")}`;
39856
40272
  const now = (/* @__PURE__ */ new Date()).toISOString();
39857
40273
  const { rows } = await this.db.query(`INSERT INTO swarm_state (id, run_id, namespace, key, value, expires_at, created_at, updated_at)
39858
40274
  VALUES ($1, $2, $3, $4, $5, $6, $7, $7)
@@ -39940,7 +40356,7 @@ var StateStore = class extends import_node_events5.EventEmitter {
39940
40356
  };
39941
40357
 
39942
40358
  // packages/sdk/dist/workflows/templates.js
39943
- var import_node_fs6 = require("node:fs");
40359
+ var import_node_fs7 = require("node:fs");
39944
40360
  var import_node_path10 = __toESM(require("node:path"), 1);
39945
40361
  var import_node_url2 = require("node:url");
39946
40362
  var import_yaml4 = __toESM(require_dist(), 1);
@@ -40044,9 +40460,9 @@ var TemplateRegistry = class {
40044
40460
  throw new Error(`Invalid template name: "${templateName}" contains path separators or traversal sequences`);
40045
40461
  }
40046
40462
  this.validateRelayConfig(parsed, url2);
40047
- await import_node_fs6.promises.mkdir(this.customTemplatesDir, { recursive: true });
40463
+ await import_node_fs7.promises.mkdir(this.customTemplatesDir, { recursive: true });
40048
40464
  const targetPath = import_node_path10.default.join(this.customTemplatesDir, `${templateName}.yaml`);
40049
- await import_node_fs6.promises.writeFile(targetPath, (0, import_yaml4.stringify)(parsed), "utf-8");
40465
+ await import_node_fs7.promises.writeFile(targetPath, (0, import_yaml4.stringify)(parsed), "utf-8");
40050
40466
  return targetPath;
40051
40467
  }
40052
40468
  isTemplateShorthand(input) {
@@ -40075,7 +40491,7 @@ var TemplateRegistry = class {
40075
40491
  import_node_path10.default.resolve(currentDir, "../workflows/builtin-templates")
40076
40492
  ];
40077
40493
  for (const candidate of candidates) {
40078
- if ((0, import_node_fs6.existsSync)(candidate)) {
40494
+ if ((0, import_node_fs7.existsSync)(candidate)) {
40079
40495
  return candidate;
40080
40496
  }
40081
40497
  }
@@ -40097,7 +40513,7 @@ var TemplateRegistry = class {
40097
40513
  for (const ext of YAML_EXTENSIONS) {
40098
40514
  const candidate = import_node_path10.default.join(directory, `${templateName}${ext}`);
40099
40515
  try {
40100
- const stat2 = await import_node_fs6.promises.stat(candidate);
40516
+ const stat2 = await import_node_fs7.promises.stat(candidate);
40101
40517
  if (stat2.isFile()) {
40102
40518
  return candidate;
40103
40519
  }
@@ -40107,7 +40523,7 @@ var TemplateRegistry = class {
40107
40523
  return void 0;
40108
40524
  }
40109
40525
  async readTemplateFile(templatePath) {
40110
- const raw = await import_node_fs6.promises.readFile(templatePath, "utf-8");
40526
+ const raw = await import_node_fs7.promises.readFile(templatePath, "utf-8");
40111
40527
  const parsed = (0, import_yaml4.parse)(raw);
40112
40528
  if (!isRecord(parsed)) {
40113
40529
  throw new Error(`Template at ${templatePath} is not a YAML object`);
@@ -40300,7 +40716,7 @@ var TemplateRegistry = class {
40300
40716
  }
40301
40717
  async safeReadDir(directory) {
40302
40718
  try {
40303
- return await import_node_fs6.promises.readdir(directory);
40719
+ return await import_node_fs7.promises.readdir(directory);
40304
40720
  } catch {
40305
40721
  return [];
40306
40722
  }
@@ -40464,7 +40880,7 @@ function isValidAgentName(name) {
40464
40880
  }
40465
40881
 
40466
40882
  // packages/utils/dist/logger.js
40467
- var import_node_fs7 = __toESM(require("node:fs"), 1);
40883
+ var import_node_fs8 = __toESM(require("node:fs"), 1);
40468
40884
  var import_node_path11 = __toESM(require("node:path"), 1);
40469
40885
  function getLogFile() {
40470
40886
  return process.env.AGENT_RELAY_LOG_FILE;
@@ -40484,8 +40900,8 @@ var LEVEL_PRIORITY = {
40484
40900
  var createdLogDirs = /* @__PURE__ */ new Set();
40485
40901
  function ensureLogDir(logFile) {
40486
40902
  const logDir = import_node_path11.default.dirname(logFile);
40487
- if (!createdLogDirs.has(logDir) && !import_node_fs7.default.existsSync(logDir)) {
40488
- import_node_fs7.default.mkdirSync(logDir, { recursive: true });
40903
+ if (!createdLogDirs.has(logDir) && !import_node_fs8.default.existsSync(logDir)) {
40904
+ import_node_fs8.default.mkdirSync(logDir, { recursive: true });
40489
40905
  createdLogDirs.add(logDir);
40490
40906
  }
40491
40907
  }
@@ -40514,7 +40930,7 @@ function log(level, component, msg, extra) {
40514
40930
  const logFile = getLogFile();
40515
40931
  if (logFile) {
40516
40932
  ensureLogDir(logFile);
40517
- import_node_fs7.default.appendFileSync(logFile, formatted + "\n");
40933
+ import_node_fs8.default.appendFileSync(logFile, formatted + "\n");
40518
40934
  return;
40519
40935
  }
40520
40936
  if (level === "ERROR" || level === "WARN") {
@@ -40785,7 +41201,7 @@ function benchmarkPatterns(iterations = 1e4) {
40785
41201
 
40786
41202
  // packages/utils/dist/command-resolver.js
40787
41203
  var import_node_child_process4 = require("node:child_process");
40788
- var import_node_fs8 = __toESM(require("node:fs"), 1);
41204
+ var import_node_fs9 = __toESM(require("node:fs"), 1);
40789
41205
  function resolveCommand(command) {
40790
41206
  if (command.startsWith("/")) {
40791
41207
  return resolveSymlinks(command);
@@ -40811,7 +41227,7 @@ function resolveCommand(command) {
40811
41227
  }
40812
41228
  function resolveSymlinks(filePath) {
40813
41229
  try {
40814
- const resolved = import_node_fs8.default.realpathSync(filePath);
41230
+ const resolved = import_node_fs9.default.realpathSync(filePath);
40815
41231
  if (resolved !== filePath && process.env.DEBUG_SPAWN === "1") {
40816
41232
  console.log(`[command-resolver] Resolved symlink: ${filePath} -> ${resolved}`);
40817
41233
  }
@@ -40836,7 +41252,7 @@ function commandExists(command) {
40836
41252
  }
40837
41253
 
40838
41254
  // packages/utils/dist/git-remote.js
40839
- var fs5 = __toESM(require("node:fs"), 1);
41255
+ var fs6 = __toESM(require("node:fs"), 1);
40840
41256
  var path11 = __toESM(require("node:path"), 1);
40841
41257
  var import_node_child_process5 = require("node:child_process");
40842
41258
  function parseGitRemoteUrl(url2) {
@@ -40855,7 +41271,7 @@ function parseGitRemoteUrl(url2) {
40855
41271
  function getGitRemoteUrl(workingDirectory, remoteName = "origin") {
40856
41272
  try {
40857
41273
  const gitDir = path11.join(workingDirectory, ".git");
40858
- if (!fs5.existsSync(gitDir)) {
41274
+ if (!fs6.existsSync(gitDir)) {
40859
41275
  return null;
40860
41276
  }
40861
41277
  const result = (0, import_node_child_process5.execSync)(`git remote get-url ${remoteName}`, {
@@ -40868,10 +41284,10 @@ function getGitRemoteUrl(workingDirectory, remoteName = "origin") {
40868
41284
  } catch {
40869
41285
  try {
40870
41286
  const configPath = path11.join(workingDirectory, ".git", "config");
40871
- if (!fs5.existsSync(configPath)) {
41287
+ if (!fs6.existsSync(configPath)) {
40872
41288
  return null;
40873
41289
  }
40874
- const config2 = fs5.readFileSync(configPath, "utf-8");
41290
+ const config2 = fs6.readFileSync(configPath, "utf-8");
40875
41291
  const remoteSection = new RegExp(`\\[remote\\s+"${remoteName}"\\][^\\[]*url\\s*=\\s*([^\\n]+)`, "i");
40876
41292
  const match = config2.match(remoteSection);
40877
41293
  return match?.[1]?.trim() || null;
@@ -40891,7 +41307,7 @@ function findGitRoot(startPath) {
40891
41307
  let currentPath = path11.resolve(startPath);
40892
41308
  const root = path11.parse(currentPath).root;
40893
41309
  while (currentPath !== root) {
40894
- if (fs5.existsSync(path11.join(currentPath, ".git"))) {
41310
+ if (fs6.existsSync(path11.join(currentPath, ".git"))) {
40895
41311
  return currentPath;
40896
41312
  }
40897
41313
  currentPath = path11.dirname(currentPath);
@@ -40911,7 +41327,7 @@ function getRepoFullNameFromPath(workingDirectory) {
40911
41327
  }
40912
41328
 
40913
41329
  // packages/utils/dist/update-checker.js
40914
- var import_node_fs9 = __toESM(require("node:fs"), 1);
41330
+ var import_node_fs10 = __toESM(require("node:fs"), 1);
40915
41331
  var import_node_path12 = __toESM(require("node:path"), 1);
40916
41332
  var import_node_https = __toESM(require("node:https"), 1);
40917
41333
  var import_node_os4 = __toESM(require("node:os"), 1);
@@ -40926,9 +41342,9 @@ function getCachePath() {
40926
41342
  function readCache() {
40927
41343
  try {
40928
41344
  const cachePath = getCachePath();
40929
- if (!import_node_fs9.default.existsSync(cachePath))
41345
+ if (!import_node_fs10.default.existsSync(cachePath))
40930
41346
  return null;
40931
- const data = import_node_fs9.default.readFileSync(cachePath, "utf-8");
41347
+ const data = import_node_fs10.default.readFileSync(cachePath, "utf-8");
40932
41348
  return JSON.parse(data);
40933
41349
  } catch {
40934
41350
  return null;
@@ -40938,10 +41354,10 @@ function writeCache(cache) {
40938
41354
  try {
40939
41355
  const cachePath = getCachePath();
40940
41356
  const cacheDir = import_node_path12.default.dirname(cachePath);
40941
- if (!import_node_fs9.default.existsSync(cacheDir)) {
40942
- import_node_fs9.default.mkdirSync(cacheDir, { recursive: true });
41357
+ if (!import_node_fs10.default.existsSync(cacheDir)) {
41358
+ import_node_fs10.default.mkdirSync(cacheDir, { recursive: true });
40943
41359
  }
40944
- import_node_fs9.default.writeFileSync(cachePath, JSON.stringify(cache, null, 2));
41360
+ import_node_fs10.default.writeFileSync(cachePath, JSON.stringify(cache, null, 2));
40945
41361
  } catch {
40946
41362
  }
40947
41363
  }
@@ -41059,10 +41475,10 @@ function checkForUpdatesInBackground(currentVersion) {
41059
41475
  }
41060
41476
 
41061
41477
  // packages/utils/dist/error-tracking.js
41062
- var import_node_crypto8 = require("node:crypto");
41478
+ var import_node_crypto9 = require("node:crypto");
41063
41479
  function generateErrorId() {
41064
41480
  const timestamp = Math.floor(Date.now() / 1e3);
41065
- const random = (0, import_node_crypto8.randomBytes)(2).toString("hex");
41481
+ const random = (0, import_node_crypto9.randomBytes)(2).toString("hex");
41066
41482
  return `ERR-${timestamp}-${random}`;
41067
41483
  }
41068
41484
  function createTraceableError(message, context = {}, originalError) {
@@ -41220,7 +41636,7 @@ function validateModelForCli(cli, model) {
41220
41636
  }
41221
41637
 
41222
41638
  // packages/utils/dist/relay-pty-path.js
41223
- var import_node_fs10 = __toESM(require("node:fs"), 1);
41639
+ var import_node_fs11 = __toESM(require("node:fs"), 1);
41224
41640
  var import_node_os5 = __toESM(require("node:os"), 1);
41225
41641
  var import_node_path13 = __toESM(require("node:path"), 1);
41226
41642
  var SUPPORTED_PLATFORMS = {
@@ -41281,12 +41697,12 @@ function findRelayPtyBinary(callerDirname) {
41281
41697
  const home = process.env.HOME || process.env.USERPROFILE || "";
41282
41698
  if (home) {
41283
41699
  const npxCacheBase = import_node_path13.default.join(home, ".npm", "_npx");
41284
- if (import_node_fs10.default.existsSync(npxCacheBase)) {
41700
+ if (import_node_fs11.default.existsSync(npxCacheBase)) {
41285
41701
  try {
41286
- const entries = import_node_fs10.default.readdirSync(npxCacheBase);
41702
+ const entries = import_node_fs11.default.readdirSync(npxCacheBase);
41287
41703
  for (const entry of entries) {
41288
41704
  const npxPackage = import_node_path13.default.join(npxCacheBase, entry, "node_modules", "agent-relay");
41289
- if (import_node_fs10.default.existsSync(npxPackage)) {
41705
+ if (import_node_fs11.default.existsSync(npxPackage)) {
41290
41706
  packageRoots.push(npxPackage);
41291
41707
  }
41292
41708
  }
@@ -41344,7 +41760,7 @@ function findRelayPtyBinary(callerDirname) {
41344
41760
  }
41345
41761
  function isExecutable(filePath) {
41346
41762
  try {
41347
- import_node_fs10.default.accessSync(filePath, import_node_fs10.default.constants.X_OK);
41763
+ import_node_fs11.default.accessSync(filePath, import_node_fs11.default.constants.X_OK);
41348
41764
  return true;
41349
41765
  } catch {
41350
41766
  return false;
@@ -41353,9 +41769,9 @@ function isExecutable(filePath) {
41353
41769
  function isPlatformCompatibleBinary(filePath) {
41354
41770
  let fd;
41355
41771
  try {
41356
- fd = import_node_fs10.default.openSync(filePath, "r");
41772
+ fd = import_node_fs11.default.openSync(filePath, "r");
41357
41773
  const header = Buffer.alloc(4);
41358
- const bytesRead = import_node_fs10.default.readSync(fd, header, 0, 4, 0);
41774
+ const bytesRead = import_node_fs11.default.readSync(fd, header, 0, 4, 0);
41359
41775
  if (bytesRead < 4) {
41360
41776
  return false;
41361
41777
  }
@@ -41373,7 +41789,7 @@ function isPlatformCompatibleBinary(filePath) {
41373
41789
  } finally {
41374
41790
  if (fd !== void 0) {
41375
41791
  try {
41376
- import_node_fs10.default.closeSync(fd);
41792
+ import_node_fs11.default.closeSync(fd);
41377
41793
  } catch {
41378
41794
  }
41379
41795
  }
@@ -41404,7 +41820,7 @@ function clearBinaryCache() {
41404
41820
 
41405
41821
  // packages/utils/dist/client-helpers.js
41406
41822
  var import_node_net = require("node:net");
41407
- var import_node_crypto9 = require("node:crypto");
41823
+ var import_node_crypto10 = require("node:crypto");
41408
41824
 
41409
41825
  // packages/utils/dist/legacy-protocol.js
41410
41826
  var PROTOCOL_VERSION2 = 1;
@@ -41531,14 +41947,14 @@ function createRequestHandler(socketPath, envelope, options) {
41531
41947
  });
41532
41948
  }
41533
41949
  function generateRequestId(prefix = "") {
41534
- return `${prefix}${Date.now().toString(36)}-${(0, import_node_crypto9.randomUUID)().slice(0, 8)}`;
41950
+ return `${prefix}${Date.now().toString(36)}-${(0, import_node_crypto10.randomUUID)().slice(0, 8)}`;
41535
41951
  }
41536
41952
 
41537
41953
  // packages/hooks/dist/types.js
41538
41954
  var HOOK_ABI_VERSION = PROTOCOL_VERSION;
41539
41955
 
41540
41956
  // packages/hooks/dist/registry.js
41541
- var import_node_crypto11 = require("node:crypto");
41957
+ var import_node_crypto12 = require("node:crypto");
41542
41958
  var InMemoryHookMemory = class {
41543
41959
  store = /* @__PURE__ */ new Map();
41544
41960
  get(key) {
@@ -41587,8 +42003,8 @@ var HookRegistry = class {
41587
42003
  injectFn;
41588
42004
  sendFn;
41589
42005
  constructor(options = {}) {
41590
- this.sessionId = (0, import_node_crypto11.randomUUID)();
41591
- this.agentId = options.agentId ?? (0, import_node_crypto11.randomUUID)();
42006
+ this.sessionId = (0, import_node_crypto12.randomUUID)();
42007
+ this.agentId = options.agentId ?? (0, import_node_crypto12.randomUUID)();
41592
42008
  this.agentName = options.agentName ?? "agent";
41593
42009
  this.workingDir = options.workingDir ?? process.cwd();
41594
42010
  this.projectId = options.projectId ?? "default";
@@ -41992,9 +42408,9 @@ var HookRegistry = class {
41992
42408
  var import_node_child_process6 = require("node:child_process");
41993
42409
 
41994
42410
  // packages/config/dist/project-namespace.js
41995
- var import_node_crypto12 = __toESM(require("node:crypto"), 1);
42411
+ var import_node_crypto13 = __toESM(require("node:crypto"), 1);
41996
42412
  var import_node_path14 = __toESM(require("node:path"), 1);
41997
- var import_node_fs11 = __toESM(require("node:fs"), 1);
42413
+ var import_node_fs12 = __toESM(require("node:fs"), 1);
41998
42414
  var import_node_os6 = __toESM(require("node:os"), 1);
41999
42415
  function getGlobalBaseDir2() {
42000
42416
  if (process.env.AGENT_RELAY_DATA_DIR) {
@@ -42007,13 +42423,13 @@ function getGlobalBaseDir2() {
42007
42423
  return import_node_path14.default.join(import_node_os6.default.homedir(), ".agent-relay");
42008
42424
  }
42009
42425
  var GLOBAL_BASE_DIR2 = getGlobalBaseDir2();
42010
- var PROJECT_DATA_DIR = ".agent-relay";
42011
- function hashPath(projectPath) {
42426
+ var PROJECT_DATA_DIR2 = ".agent-relay";
42427
+ function hashPath2(projectPath) {
42012
42428
  const normalized = import_node_path14.default.resolve(projectPath);
42013
- const hash2 = import_node_crypto12.default.createHash("sha256").update(normalized).digest("hex");
42429
+ const hash2 = import_node_crypto13.default.createHash("sha256").update(normalized).digest("hex");
42014
42430
  return hash2.substring(0, 12);
42015
42431
  }
42016
- function findProjectRoot(startDir = process.cwd()) {
42432
+ function findProjectRoot2(startDir = process.cwd()) {
42017
42433
  if (process.env.AGENT_RELAY_PROJECT) {
42018
42434
  return import_node_path14.default.resolve(process.env.AGENT_RELAY_PROJECT);
42019
42435
  }
@@ -42022,7 +42438,7 @@ function findProjectRoot(startDir = process.cwd()) {
42022
42438
  const markers = [".git", "package.json", "Cargo.toml", "go.mod", "pyproject.toml", ".agent-relay"];
42023
42439
  while (current !== root) {
42024
42440
  for (const marker of markers) {
42025
- if (import_node_fs11.default.existsSync(import_node_path14.default.join(current, marker))) {
42441
+ if (import_node_fs12.default.existsSync(import_node_path14.default.join(current, marker))) {
42026
42442
  return current;
42027
42443
  }
42028
42444
  }
@@ -42031,9 +42447,9 @@ function findProjectRoot(startDir = process.cwd()) {
42031
42447
  return import_node_path14.default.resolve(startDir);
42032
42448
  }
42033
42449
  function getProjectPaths2(projectRoot) {
42034
- const root = projectRoot ?? findProjectRoot();
42035
- const projectId = hashPath(root);
42036
- const dataDir = import_node_path14.default.join(root, PROJECT_DATA_DIR);
42450
+ const root = projectRoot ?? findProjectRoot2();
42451
+ const projectId = hashPath2(root);
42452
+ const dataDir = import_node_path14.default.join(root, PROJECT_DATA_DIR2);
42037
42453
  return {
42038
42454
  dataDir,
42039
42455
  teamDir: import_node_path14.default.join(dataDir, "team"),
@@ -42045,10 +42461,10 @@ function getProjectPaths2(projectRoot) {
42045
42461
  }
42046
42462
 
42047
42463
  // packages/config/dist/trajectory-config.js
42048
- var import_node_fs12 = require("node:fs");
42464
+ var import_node_fs13 = require("node:fs");
42049
42465
  var import_node_path15 = require("node:path");
42050
42466
  var import_node_os7 = require("node:os");
42051
- var import_node_crypto13 = require("node:crypto");
42467
+ var import_node_crypto14 = require("node:crypto");
42052
42468
  function getAgentRelayConfigDir() {
42053
42469
  return process.env.AGENT_RELAY_CONFIG_DIR ?? (0, import_node_path15.join)((0, import_node_os7.homedir)(), ".config", "agent-relay");
42054
42470
  }
@@ -42060,7 +42476,7 @@ function readRelayConfig(projectRoot) {
42060
42476
  const configPath = getRelayConfigPath(projectRoot);
42061
42477
  if (configCache && configCache.path === configPath) {
42062
42478
  try {
42063
- const stat2 = (0, import_node_fs12.statSync)(configPath);
42479
+ const stat2 = (0, import_node_fs13.statSync)(configPath);
42064
42480
  if (stat2.mtimeMs === configCache.mtime) {
42065
42481
  return configCache.config;
42066
42482
  }
@@ -42068,13 +42484,13 @@ function readRelayConfig(projectRoot) {
42068
42484
  }
42069
42485
  }
42070
42486
  try {
42071
- if (!(0, import_node_fs12.existsSync)(configPath)) {
42487
+ if (!(0, import_node_fs13.existsSync)(configPath)) {
42072
42488
  return {};
42073
42489
  }
42074
- const content = (0, import_node_fs12.readFileSync)(configPath, "utf-8");
42490
+ const content = (0, import_node_fs13.readFileSync)(configPath, "utf-8");
42075
42491
  const config2 = JSON.parse(content);
42076
42492
  try {
42077
- const stat2 = (0, import_node_fs12.statSync)(configPath);
42493
+ const stat2 = (0, import_node_fs13.statSync)(configPath);
42078
42494
  configCache = { path: configPath, config: config2, mtime: stat2.mtimeMs };
42079
42495
  } catch {
42080
42496
  }
@@ -42090,7 +42506,7 @@ function shouldStoreInRepo(projectRoot) {
42090
42506
  }
42091
42507
  function getProjectHash(projectRoot) {
42092
42508
  const root = projectRoot ?? getProjectPaths2().projectRoot;
42093
- return (0, import_node_crypto13.createHash)("sha256").update(root).digest("hex").slice(0, 16);
42509
+ return (0, import_node_crypto14.createHash)("sha256").update(root).digest("hex").slice(0, 16);
42094
42510
  }
42095
42511
  function getUserTrajectoriesDir(projectRoot) {
42096
42512
  const projectHash = getProjectHash(projectRoot);
@@ -42739,7 +43155,7 @@ var HookEmitter = class {
42739
43155
  };
42740
43156
 
42741
43157
  // packages/hooks/dist/inbox-check/utils.js
42742
- var import_node_fs13 = require("node:fs");
43158
+ var import_node_fs14 = require("node:fs");
42743
43159
  var import_node_path16 = require("node:path");
42744
43160
  var DEFAULT_INBOX_DIR = "/tmp/agent-relay";
42745
43161
  function getAgentName() {
@@ -42753,13 +43169,13 @@ function getInboxPath(config2) {
42753
43169
  return (0, import_node_path16.join)(config2.inboxDir, agentName, "inbox.md");
42754
43170
  }
42755
43171
  function inboxExists(inboxPath) {
42756
- return (0, import_node_fs13.existsSync)(inboxPath);
43172
+ return (0, import_node_fs14.existsSync)(inboxPath);
42757
43173
  }
42758
43174
  function readInbox(inboxPath) {
42759
43175
  if (!inboxExists(inboxPath)) {
42760
43176
  return "";
42761
43177
  }
42762
- return (0, import_node_fs13.readFileSync)(inboxPath, "utf-8");
43178
+ return (0, import_node_fs14.readFileSync)(inboxPath, "utf-8");
42763
43179
  }
42764
43180
  function hasUnreadMessages(inboxPath) {
42765
43181
  const content = readInbox(inboxPath);
@@ -42846,6 +43262,7 @@ init_dist();
42846
43262
  HOOK_ABI_VERSION,
42847
43263
  HookEmitter,
42848
43264
  HookRegistry,
43265
+ HttpAgentRelayClient,
42849
43266
  InMemoryAdapter,
42850
43267
  InMemoryWorkflowDb,
42851
43268
  JsonFileWorkflowDb,