agent-relay 3.0.2 → 3.1.1

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 (266) hide show
  1. package/README.md +8 -0
  2. package/bin/agent-relay-broker-linux-x64 +0 -0
  3. package/dist/index.cjs +273 -56
  4. package/dist/src/cli/commands/core.d.ts +2 -0
  5. package/dist/src/cli/commands/core.d.ts.map +1 -1
  6. package/dist/src/cli/commands/core.js +9 -2
  7. package/dist/src/cli/commands/core.js.map +1 -1
  8. package/dist/src/cli/lib/broker-lifecycle.d.ts.map +1 -1
  9. package/dist/src/cli/lib/broker-lifecycle.js +87 -28
  10. package/dist/src/cli/lib/broker-lifecycle.js.map +1 -1
  11. package/package.json +9 -9
  12. package/packages/acp-bridge/README.md +50 -67
  13. package/packages/acp-bridge/package.json +2 -2
  14. package/packages/config/package.json +1 -1
  15. package/packages/hooks/package.json +4 -4
  16. package/packages/memory/package.json +2 -2
  17. package/packages/openclaw/README.md +78 -0
  18. package/packages/openclaw/bin/relay-openclaw.mjs +2 -0
  19. package/packages/openclaw/bridge/bridge.mjs +305 -0
  20. package/packages/openclaw/dist/__tests__/gateway-threads.test.d.ts +2 -0
  21. package/packages/openclaw/dist/__tests__/gateway-threads.test.d.ts.map +1 -0
  22. package/packages/openclaw/dist/__tests__/gateway-threads.test.js +320 -0
  23. package/packages/openclaw/dist/__tests__/gateway-threads.test.js.map +1 -0
  24. package/packages/openclaw/dist/__tests__/naming.test.d.ts +2 -0
  25. package/packages/openclaw/dist/__tests__/naming.test.d.ts.map +1 -0
  26. package/packages/openclaw/dist/__tests__/naming.test.js +21 -0
  27. package/packages/openclaw/dist/__tests__/naming.test.js.map +1 -0
  28. package/packages/openclaw/dist/__tests__/spawn-manager.test.d.ts +2 -0
  29. package/packages/openclaw/dist/__tests__/spawn-manager.test.d.ts.map +1 -0
  30. package/packages/openclaw/dist/__tests__/spawn-manager.test.js +126 -0
  31. package/packages/openclaw/dist/__tests__/spawn-manager.test.js.map +1 -0
  32. package/packages/openclaw/dist/auth/converter.d.ts +28 -0
  33. package/packages/openclaw/dist/auth/converter.d.ts.map +1 -0
  34. package/packages/openclaw/dist/auth/converter.js +64 -0
  35. package/packages/openclaw/dist/auth/converter.js.map +1 -0
  36. package/packages/openclaw/dist/cli.d.ts +2 -0
  37. package/packages/openclaw/dist/cli.d.ts.map +1 -0
  38. package/packages/openclaw/dist/cli.js +230 -0
  39. package/packages/openclaw/dist/cli.js.map +1 -0
  40. package/packages/openclaw/dist/config.d.ts +27 -0
  41. package/packages/openclaw/dist/config.d.ts.map +1 -0
  42. package/packages/openclaw/dist/config.js +97 -0
  43. package/packages/openclaw/dist/config.js.map +1 -0
  44. package/packages/openclaw/dist/control.d.ts +22 -0
  45. package/packages/openclaw/dist/control.d.ts.map +1 -0
  46. package/packages/openclaw/dist/control.js +58 -0
  47. package/packages/openclaw/dist/control.js.map +1 -0
  48. package/packages/openclaw/dist/gateway.d.ts +71 -0
  49. package/packages/openclaw/dist/gateway.d.ts.map +1 -0
  50. package/packages/openclaw/dist/gateway.js +785 -0
  51. package/packages/openclaw/dist/gateway.js.map +1 -0
  52. package/packages/openclaw/dist/identity/contract.d.ts +11 -0
  53. package/packages/openclaw/dist/identity/contract.d.ts.map +1 -0
  54. package/packages/openclaw/dist/identity/contract.js +40 -0
  55. package/packages/openclaw/dist/identity/contract.js.map +1 -0
  56. package/packages/openclaw/dist/identity/files.d.ts +33 -0
  57. package/packages/openclaw/dist/identity/files.d.ts.map +1 -0
  58. package/packages/openclaw/dist/identity/files.js +145 -0
  59. package/packages/openclaw/dist/identity/files.js.map +1 -0
  60. package/packages/openclaw/dist/identity/model.d.ts +11 -0
  61. package/packages/openclaw/dist/identity/model.d.ts.map +1 -0
  62. package/packages/openclaw/dist/identity/model.js +28 -0
  63. package/packages/openclaw/dist/identity/model.js.map +1 -0
  64. package/packages/openclaw/dist/identity/naming.d.ts +5 -0
  65. package/packages/openclaw/dist/identity/naming.d.ts.map +1 -0
  66. package/packages/openclaw/dist/identity/naming.js +7 -0
  67. package/packages/openclaw/dist/identity/naming.js.map +1 -0
  68. package/packages/openclaw/dist/index.d.ts +20 -0
  69. package/packages/openclaw/dist/index.d.ts.map +1 -0
  70. package/packages/openclaw/dist/index.js +27 -0
  71. package/packages/openclaw/dist/index.js.map +1 -0
  72. package/packages/openclaw/dist/inject.d.ts +14 -0
  73. package/packages/openclaw/dist/inject.d.ts.map +1 -0
  74. package/packages/openclaw/dist/inject.js +66 -0
  75. package/packages/openclaw/dist/inject.js.map +1 -0
  76. package/packages/openclaw/dist/mcp/server.d.ts +8 -0
  77. package/packages/openclaw/dist/mcp/server.d.ts.map +1 -0
  78. package/packages/openclaw/dist/mcp/server.js +105 -0
  79. package/packages/openclaw/dist/mcp/server.js.map +1 -0
  80. package/packages/openclaw/dist/mcp/tools.d.ts +17 -0
  81. package/packages/openclaw/dist/mcp/tools.d.ts.map +1 -0
  82. package/packages/openclaw/dist/mcp/tools.js +145 -0
  83. package/packages/openclaw/dist/mcp/tools.js.map +1 -0
  84. package/packages/openclaw/dist/runtime/openclaw-config.d.ts +20 -0
  85. package/packages/openclaw/dist/runtime/openclaw-config.d.ts.map +1 -0
  86. package/packages/openclaw/dist/runtime/openclaw-config.js +50 -0
  87. package/packages/openclaw/dist/runtime/openclaw-config.js.map +1 -0
  88. package/packages/openclaw/dist/runtime/patch.d.ts +24 -0
  89. package/packages/openclaw/dist/runtime/patch.d.ts.map +1 -0
  90. package/packages/openclaw/dist/runtime/patch.js +92 -0
  91. package/packages/openclaw/dist/runtime/patch.js.map +1 -0
  92. package/packages/openclaw/dist/runtime/setup.d.ts +26 -0
  93. package/packages/openclaw/dist/runtime/setup.d.ts.map +1 -0
  94. package/packages/openclaw/dist/runtime/setup.js +58 -0
  95. package/packages/openclaw/dist/runtime/setup.js.map +1 -0
  96. package/packages/openclaw/dist/setup.d.ts +29 -0
  97. package/packages/openclaw/dist/setup.d.ts.map +1 -0
  98. package/packages/openclaw/dist/setup.js +300 -0
  99. package/packages/openclaw/dist/setup.js.map +1 -0
  100. package/packages/openclaw/dist/spawn/docker.d.ts +58 -0
  101. package/packages/openclaw/dist/spawn/docker.d.ts.map +1 -0
  102. package/packages/openclaw/dist/spawn/docker.js +222 -0
  103. package/packages/openclaw/dist/spawn/docker.js.map +1 -0
  104. package/packages/openclaw/dist/spawn/manager.d.ts +45 -0
  105. package/packages/openclaw/dist/spawn/manager.d.ts.map +1 -0
  106. package/packages/openclaw/dist/spawn/manager.js +140 -0
  107. package/packages/openclaw/dist/spawn/manager.js.map +1 -0
  108. package/packages/openclaw/dist/spawn/process.d.ts +16 -0
  109. package/packages/openclaw/dist/spawn/process.d.ts.map +1 -0
  110. package/packages/openclaw/dist/spawn/process.js +241 -0
  111. package/packages/openclaw/dist/spawn/process.js.map +1 -0
  112. package/packages/openclaw/dist/spawn/types.d.ts +42 -0
  113. package/packages/openclaw/dist/spawn/types.d.ts.map +1 -0
  114. package/packages/openclaw/dist/spawn/types.js +2 -0
  115. package/packages/openclaw/dist/spawn/types.js.map +1 -0
  116. package/packages/openclaw/dist/types.d.ts +37 -0
  117. package/packages/openclaw/dist/types.d.ts.map +1 -0
  118. package/packages/openclaw/dist/types.js +2 -0
  119. package/packages/openclaw/dist/types.js.map +1 -0
  120. package/packages/openclaw/package.json +63 -0
  121. package/packages/openclaw/skill/SKILL.md +194 -0
  122. package/packages/openclaw/src/__tests__/gateway-threads.test.ts +384 -0
  123. package/packages/openclaw/src/__tests__/naming.test.ts +24 -0
  124. package/packages/openclaw/src/__tests__/spawn-manager.test.ts +152 -0
  125. package/packages/openclaw/src/auth/converter.ts +90 -0
  126. package/packages/openclaw/src/cli.ts +269 -0
  127. package/packages/openclaw/src/config.ts +124 -0
  128. package/packages/openclaw/src/control.ts +100 -0
  129. package/packages/openclaw/src/gateway.ts +941 -0
  130. package/packages/openclaw/src/identity/contract.ts +44 -0
  131. package/packages/openclaw/src/identity/files.ts +198 -0
  132. package/packages/openclaw/src/identity/model.ts +27 -0
  133. package/packages/openclaw/src/identity/naming.ts +6 -0
  134. package/packages/openclaw/src/index.ts +59 -0
  135. package/packages/openclaw/src/inject.ts +77 -0
  136. package/packages/openclaw/src/mcp/server.ts +121 -0
  137. package/packages/openclaw/src/mcp/tools.ts +174 -0
  138. package/packages/openclaw/src/runtime/openclaw-config.ts +64 -0
  139. package/packages/openclaw/src/runtime/patch.ts +103 -0
  140. package/packages/openclaw/src/runtime/setup.ts +89 -0
  141. package/packages/openclaw/src/setup.ts +336 -0
  142. package/packages/openclaw/src/spawn/docker.ts +261 -0
  143. package/packages/openclaw/src/spawn/manager.ts +181 -0
  144. package/packages/openclaw/src/spawn/process.ts +272 -0
  145. package/packages/openclaw/src/spawn/types.ts +43 -0
  146. package/packages/openclaw/src/types.ts +38 -0
  147. package/packages/openclaw/templates/SOUL.md.template +34 -0
  148. package/packages/openclaw/tsconfig.json +12 -0
  149. package/packages/policy/package.json +2 -2
  150. package/packages/sdk/README.md +169 -64
  151. package/packages/sdk/dist/__tests__/contract-fixtures.test.js +76 -9
  152. package/packages/sdk/dist/__tests__/contract-fixtures.test.js.map +1 -1
  153. package/packages/sdk/dist/__tests__/integration.test.js +5 -4
  154. package/packages/sdk/dist/__tests__/integration.test.js.map +1 -1
  155. package/packages/sdk/dist/client.d.ts +34 -3
  156. package/packages/sdk/dist/client.d.ts.map +1 -1
  157. package/packages/sdk/dist/client.js +120 -10
  158. package/packages/sdk/dist/client.js.map +1 -1
  159. package/packages/sdk/dist/protocol.d.ts +7 -1
  160. package/packages/sdk/dist/protocol.d.ts.map +1 -1
  161. package/packages/sdk/dist/relay.d.ts +47 -11
  162. package/packages/sdk/dist/relay.d.ts.map +1 -1
  163. package/packages/sdk/dist/relay.js +114 -23
  164. package/packages/sdk/dist/relay.js.map +1 -1
  165. package/packages/sdk/dist/workflows/runner.d.ts.map +1 -1
  166. package/packages/sdk/dist/workflows/runner.js +71 -36
  167. package/packages/sdk/dist/workflows/runner.js.map +1 -1
  168. package/packages/sdk/dist/workflows/types.d.ts +1 -1
  169. package/packages/sdk/dist/workflows/types.d.ts.map +1 -1
  170. package/packages/sdk/package.json +2 -2
  171. package/packages/sdk/src/__tests__/contract-fixtures.test.ts +88 -9
  172. package/packages/sdk/src/__tests__/error-scenarios.test.ts +1 -1
  173. package/packages/sdk/src/__tests__/idle-nudge.test.ts +205 -257
  174. package/packages/sdk/src/__tests__/integration.test.ts +5 -4
  175. package/packages/sdk/src/__tests__/orchestration-upgrades.test.ts +277 -13
  176. package/packages/sdk/src/__tests__/swarm-coordinator.test.ts +1 -0
  177. package/packages/sdk/src/__tests__/workflow-runner.test.ts +67 -7
  178. package/packages/sdk/src/__tests__/workflow-trajectory.test.ts +4 -5
  179. package/packages/sdk/src/client.ts +171 -14
  180. package/packages/sdk/src/examples/workflows/runner-idle-refactor.yaml +306 -0
  181. package/packages/sdk/src/protocol.ts +7 -2
  182. package/packages/sdk/src/relay.ts +196 -34
  183. package/packages/sdk/src/workflows/runner.ts +73 -42
  184. package/packages/sdk/src/workflows/schema.json +1 -1
  185. package/packages/sdk/src/workflows/types.ts +1 -1
  186. package/packages/sdk/vitest.config.ts +1 -0
  187. package/packages/sdk-py/README.md +89 -102
  188. package/packages/sdk-py/agent_relay/__init__.py +16 -19
  189. package/packages/sdk-py/pyproject.toml +5 -1
  190. package/packages/sdk-py/src/agent_relay/__init__.py +35 -1
  191. package/packages/sdk-py/src/agent_relay/client.py +776 -0
  192. package/packages/sdk-py/src/agent_relay/models.py +27 -0
  193. package/packages/sdk-py/src/agent_relay/protocol.py +114 -0
  194. package/packages/sdk-py/src/agent_relay/relay.py +860 -0
  195. package/packages/sdk-py/tests/test_relay_lifecycle_hooks.py +250 -0
  196. package/packages/telemetry/package.json +1 -1
  197. package/packages/trajectory/package.json +2 -2
  198. package/packages/user-directory/package.json +2 -2
  199. package/packages/utils/package.json +2 -2
  200. package/bin/agent-relay-broker-darwin-arm64 +0 -0
  201. package/bin/agent-relay-broker-darwin-x64 +0 -0
  202. package/bin/agent-relay-broker-linux-arm64 +0 -0
  203. package/packages/sdk/.trajectories/active/traj_1771875803391_84ca57b2.json +0 -50
  204. package/packages/sdk/.trajectories/active/traj_1771891934534_06504121.json +0 -50
  205. package/packages/sdk/.trajectories/active/traj_1771891957929_211afc4e.json +0 -50
  206. package/packages/sdk/.trajectories/active/traj_1771891982509_38c84638.json +0 -50
  207. package/packages/sdk/.trajectories/completed/traj_1771875803188_cd6d181c.json +0 -80
  208. package/packages/sdk/.trajectories/completed/traj_1771875803204_f2aeb8c8.json +0 -80
  209. package/packages/sdk/.trajectories/completed/traj_1771875803210_d65f3f1a.json +0 -80
  210. package/packages/sdk/.trajectories/completed/traj_1771875803218_e454a25d.json +0 -80
  211. package/packages/sdk/.trajectories/completed/traj_1771875803223_d7a64815.json +0 -80
  212. package/packages/sdk/.trajectories/completed/traj_1771875803227_7e56da5b.json +0 -80
  213. package/packages/sdk/.trajectories/completed/traj_1771875803235_4fbf93b4.json +0 -80
  214. package/packages/sdk/.trajectories/completed/traj_1771875803243_47931c71.json +0 -80
  215. package/packages/sdk/.trajectories/completed/traj_1771875803258_3816f3fe.json +0 -80
  216. package/packages/sdk/.trajectories/completed/traj_1771875803268_8061140e.json +0 -80
  217. package/packages/sdk/.trajectories/completed/traj_1771875803326_ae6f9c78.json +0 -80
  218. package/packages/sdk/.trajectories/completed/traj_1771875808396_cbde0a6c.json +0 -91
  219. package/packages/sdk/.trajectories/completed/traj_1771875812026_aa2442bb.json +0 -91
  220. package/packages/sdk/.trajectories/completed/traj_1771875815431_c2c656c5.json +0 -91
  221. package/packages/sdk/.trajectories/completed/traj_1771875818645_3a4dbf02.json +0 -91
  222. package/packages/sdk/.trajectories/completed/traj_1771891934403_24923c03.json +0 -80
  223. package/packages/sdk/.trajectories/completed/traj_1771891934421_dca16e24.json +0 -80
  224. package/packages/sdk/.trajectories/completed/traj_1771891934430_057706f7.json +0 -80
  225. package/packages/sdk/.trajectories/completed/traj_1771891934442_faf97382.json +0 -80
  226. package/packages/sdk/.trajectories/completed/traj_1771891934454_5542ecd5.json +0 -80
  227. package/packages/sdk/.trajectories/completed/traj_1771891934464_12202a08.json +0 -80
  228. package/packages/sdk/.trajectories/completed/traj_1771891934487_94378275.json +0 -80
  229. package/packages/sdk/.trajectories/completed/traj_1771891934503_ca728c13.json +0 -80
  230. package/packages/sdk/.trajectories/completed/traj_1771891934519_100af69a.json +0 -80
  231. package/packages/sdk/.trajectories/completed/traj_1771891934536_62ad39d9.json +0 -80
  232. package/packages/sdk/.trajectories/completed/traj_1771891934553_d6798a52.json +0 -80
  233. package/packages/sdk/.trajectories/completed/traj_1771891939537_541c8096.json +0 -91
  234. package/packages/sdk/.trajectories/completed/traj_1771891942985_36ab9a4d.json +0 -91
  235. package/packages/sdk/.trajectories/completed/traj_1771891946453_e8a6e05f.json +0 -91
  236. package/packages/sdk/.trajectories/completed/traj_1771891949838_5de0de84.json +0 -91
  237. package/packages/sdk/.trajectories/completed/traj_1771891957807_0ecfb4f4.json +0 -80
  238. package/packages/sdk/.trajectories/completed/traj_1771891957827_c4539239.json +0 -80
  239. package/packages/sdk/.trajectories/completed/traj_1771891957836_91168b48.json +0 -80
  240. package/packages/sdk/.trajectories/completed/traj_1771891957848_8c5cad0b.json +0 -80
  241. package/packages/sdk/.trajectories/completed/traj_1771891957857_0986b293.json +0 -80
  242. package/packages/sdk/.trajectories/completed/traj_1771891957872_8a3113af.json +0 -80
  243. package/packages/sdk/.trajectories/completed/traj_1771891957884_0bb85208.json +0 -80
  244. package/packages/sdk/.trajectories/completed/traj_1771891957892_86c75e2e.json +0 -80
  245. package/packages/sdk/.trajectories/completed/traj_1771891957907_98ca0e6f.json +0 -80
  246. package/packages/sdk/.trajectories/completed/traj_1771891957918_d9091231.json +0 -80
  247. package/packages/sdk/.trajectories/completed/traj_1771891957931_dcaf77ed.json +0 -80
  248. package/packages/sdk/.trajectories/completed/traj_1771891962931_eb1fdee2.json +0 -91
  249. package/packages/sdk/.trajectories/completed/traj_1771891966262_9061a93f.json +0 -91
  250. package/packages/sdk/.trajectories/completed/traj_1771891969915_1adaba19.json +0 -91
  251. package/packages/sdk/.trajectories/completed/traj_1771891973588_f08b79e9.json +0 -91
  252. package/packages/sdk/.trajectories/completed/traj_1771891982421_f1985bce.json +0 -80
  253. package/packages/sdk/.trajectories/completed/traj_1771891982432_e7a84163.json +0 -80
  254. package/packages/sdk/.trajectories/completed/traj_1771891982447_369b842a.json +0 -80
  255. package/packages/sdk/.trajectories/completed/traj_1771891982469_5fc45199.json +0 -80
  256. package/packages/sdk/.trajectories/completed/traj_1771891982495_454c7cb3.json +0 -80
  257. package/packages/sdk/.trajectories/completed/traj_1771891982514_08098e03.json +0 -80
  258. package/packages/sdk/.trajectories/completed/traj_1771891982526_b351d778.json +0 -80
  259. package/packages/sdk/.trajectories/completed/traj_1771891982533_fa542d83.json +0 -80
  260. package/packages/sdk/.trajectories/completed/traj_1771891982540_18ab24dc.json +0 -80
  261. package/packages/sdk/.trajectories/completed/traj_1771891982544_5b4fa163.json +0 -80
  262. package/packages/sdk/.trajectories/completed/traj_1771891982548_c13f089a.json +0 -80
  263. package/packages/sdk/.trajectories/completed/traj_1771891987510_23f6da1f.json +0 -91
  264. package/packages/sdk/.trajectories/completed/traj_1771891991466_912c2e04.json +0 -91
  265. package/packages/sdk/.trajectories/completed/traj_1771891994891_60604be2.json +0 -91
  266. package/packages/sdk/.trajectories/completed/traj_1771891998370_cfaf9b8b.json +0 -91
@@ -0,0 +1,300 @@
1
+ import { mkdir, writeFile, copyFile } from 'node:fs/promises';
2
+ import { join, dirname } from 'node:path';
3
+ import { existsSync } from 'node:fs';
4
+ import { hostname } from 'node:os';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { spawn as spawnProcess, execFileSync } from 'node:child_process';
7
+ import { detectOpenClaw, saveGatewayConfig } from './config.js';
8
+ /**
9
+ * Install the Relaycast bridge into an OpenClaw workspace.
10
+ *
11
+ * 1. Detect OpenClaw installation
12
+ * 2. Create/join workspace via Relaycast API (if no key provided)
13
+ * 3. Install SKILL.md
14
+ * 4. Write .env config
15
+ * 5. Configure MCP server in openclaw.json
16
+ * 6. Print success summary
17
+ */
18
+ export async function setup(options) {
19
+ const detection = await detectOpenClaw();
20
+ const clawName = options.clawName ?? hostname() ?? 'my-claw';
21
+ const baseUrl = options.baseUrl ?? 'https://api.relaycast.dev';
22
+ const channels = options.channels ?? ['general'];
23
+ if (!detection.installed) {
24
+ // Auto-create ~/.openclaw/ if OpenClaw binary is available but the config dir
25
+ // doesn't exist yet (common in Docker images before onboarding).
26
+ try {
27
+ await mkdir(detection.homeDir, { recursive: true });
28
+ await mkdir(join(detection.homeDir, 'workspace'), { recursive: true });
29
+ // Write a minimal openclaw.json so MCP servers can be registered
30
+ const configPath = join(detection.homeDir, 'openclaw.json');
31
+ if (!existsSync(configPath)) {
32
+ await writeFile(configPath, JSON.stringify({ mcpServers: {} }, null, 2) + '\n', 'utf-8');
33
+ }
34
+ // Re-detect after creating
35
+ const redetection = await detectOpenClaw();
36
+ Object.assign(detection, redetection);
37
+ }
38
+ catch {
39
+ return {
40
+ ok: false,
41
+ apiKey: '',
42
+ clawName,
43
+ skillDir: '',
44
+ message: 'OpenClaw not found. Please install OpenClaw first (expected ~/.openclaw/ directory).',
45
+ };
46
+ }
47
+ }
48
+ // Enable the OpenResponses HTTP API so the inbound gateway can inject
49
+ // messages via POST /v1/responses on the local OpenClaw gateway.
50
+ try {
51
+ execFileSync('openclaw', [
52
+ 'config', 'set',
53
+ 'gateway.http.endpoints.responses.enabled', 'true',
54
+ ], { stdio: 'pipe' });
55
+ }
56
+ catch {
57
+ console.warn('Could not enable OpenResponses API (non-fatal). Enable manually:');
58
+ console.warn(' openclaw config set gateway.http.endpoints.responses.enabled true');
59
+ }
60
+ // Resolve API key: use provided key or create a new workspace
61
+ let apiKey = options.apiKey;
62
+ if (!apiKey) {
63
+ try {
64
+ const res = await fetch(`${baseUrl}/v1/workspaces`, {
65
+ method: 'POST',
66
+ headers: { 'Content-Type': 'application/json' },
67
+ body: JSON.stringify({ name: `${clawName}-workspace` }),
68
+ });
69
+ if (res.status === 409) {
70
+ // Workspace already exists — look up its API key
71
+ const lookupRes = await fetch(`${baseUrl}/v1/workspaces/by-name/${encodeURIComponent(`${clawName}-workspace`)}`, {
72
+ headers: { 'Content-Type': 'application/json' },
73
+ });
74
+ if (lookupRes.ok) {
75
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
76
+ const lookupBody = (await lookupRes.json());
77
+ apiKey = lookupBody.apiKey ?? lookupBody.api_key ?? lookupBody.data?.apiKey ?? lookupBody.data?.api_key;
78
+ }
79
+ if (!apiKey) {
80
+ return {
81
+ ok: false,
82
+ apiKey: '',
83
+ clawName,
84
+ skillDir: '',
85
+ message: `Workspace "${clawName}-workspace" already exists. Pass the workspace key: @agent-relay/openclaw setup <key> --name ${clawName}`,
86
+ };
87
+ }
88
+ }
89
+ else if (!res.ok) {
90
+ const body = await res.text();
91
+ return {
92
+ ok: false,
93
+ apiKey: '',
94
+ clawName,
95
+ skillDir: '',
96
+ message: `Failed to create workspace: ${res.status} ${body}`,
97
+ };
98
+ }
99
+ else {
100
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
101
+ const successBody = (await res.json());
102
+ apiKey = successBody.apiKey ?? successBody.api_key ?? successBody.data?.apiKey ?? successBody.data?.api_key;
103
+ }
104
+ if (!apiKey) {
105
+ return {
106
+ ok: false,
107
+ apiKey: '',
108
+ clawName,
109
+ skillDir: '',
110
+ message: 'Workspace created but no API key returned.',
111
+ };
112
+ }
113
+ }
114
+ catch (err) {
115
+ return {
116
+ ok: false,
117
+ apiKey: '',
118
+ clawName,
119
+ skillDir: '',
120
+ message: `Failed to create workspace: ${err instanceof Error ? err.message : String(err)}`,
121
+ };
122
+ }
123
+ }
124
+ // Agent registration is done after mcporter is configured (see below),
125
+ // since the register tool is accessed via mcporter call relaycast.register.
126
+ // Install SKILL.md
127
+ const skillDir = join(detection.workspaceDir, 'relaycast');
128
+ await mkdir(skillDir, { recursive: true });
129
+ const skillSrc = resolveSkillPath();
130
+ if (existsSync(skillSrc)) {
131
+ await copyFile(skillSrc, join(skillDir, 'SKILL.md'));
132
+ }
133
+ else {
134
+ // Write a minimal SKILL.md inline if the bundled one isn't found
135
+ await writeFile(join(skillDir, 'SKILL.md'), FALLBACK_SKILL_MD, 'utf-8');
136
+ }
137
+ // Save gateway config (.env)
138
+ const gatewayConfig = {
139
+ apiKey,
140
+ clawName,
141
+ baseUrl,
142
+ channels,
143
+ };
144
+ await saveGatewayConfig(gatewayConfig);
145
+ // Register MCP servers via mcporter
146
+ let mcpConfigured = false;
147
+ {
148
+ const envArgs = [
149
+ '--env', `RELAY_API_KEY=${apiKey}`,
150
+ ...(baseUrl !== 'https://api.relaycast.dev'
151
+ ? ['--env', `RELAY_BASE_URL=${baseUrl}`]
152
+ : []),
153
+ ];
154
+ try {
155
+ // Register relaycast messaging MCP server
156
+ execFileSync('mcporter', [
157
+ 'config', 'add', 'relaycast',
158
+ '--command', 'npx',
159
+ '--arg', '@relaycast/mcp',
160
+ ...envArgs,
161
+ '--scope', 'home',
162
+ '--description', 'Relaycast messaging MCP server',
163
+ ], { stdio: 'pipe' });
164
+ // Register openclaw-spawner MCP server
165
+ execFileSync('mcporter', [
166
+ 'config', 'add', 'openclaw-spawner',
167
+ '--command', 'npx',
168
+ '--arg', '@agent-relay/openclaw',
169
+ '--arg', 'mcp-server',
170
+ ...envArgs,
171
+ '--scope', 'home',
172
+ '--description', 'OpenClaw spawner MCP server',
173
+ ], { stdio: 'pipe' });
174
+ mcpConfigured = true;
175
+ // Register this claw as an agent via mcporter and persist the agent token
176
+ try {
177
+ const registerOutput = execFileSync('mcporter', [
178
+ 'call', 'relaycast.register',
179
+ 'name=' + clawName,
180
+ 'type=agent',
181
+ ], { stdio: 'pipe', encoding: 'utf-8' });
182
+ // Parse the agent token from the register output
183
+ let agentToken;
184
+ try {
185
+ const parsed = JSON.parse(registerOutput);
186
+ agentToken = parsed.token ?? parsed.agentToken ?? parsed.agent_token;
187
+ }
188
+ catch {
189
+ // Try to find token in raw output
190
+ const tokenMatch = registerOutput.match(/"token"\s*:\s*"([^"]+)"/);
191
+ if (tokenMatch)
192
+ agentToken = tokenMatch[1];
193
+ }
194
+ if (agentToken) {
195
+ // Reconfigure mcporter with the agent token so subsequent calls are authenticated
196
+ try {
197
+ execFileSync('mcporter', ['config', 'remove', 'relaycast'], { stdio: 'pipe' });
198
+ }
199
+ catch { /* may not exist */ }
200
+ execFileSync('mcporter', [
201
+ 'config', 'add', 'relaycast',
202
+ '--command', 'npx',
203
+ '--arg', '@relaycast/mcp',
204
+ ...envArgs,
205
+ '--env', `RELAY_AGENT_TOKEN=${agentToken}`,
206
+ '--scope', 'home',
207
+ '--description', 'Relaycast messaging MCP server',
208
+ ], { stdio: 'pipe' });
209
+ console.log(`Agent "${clawName}" registered with token.`);
210
+ }
211
+ else {
212
+ console.warn('Agent registered but no token found in response.');
213
+ }
214
+ }
215
+ catch (regErr) {
216
+ console.warn(`Agent registration via mcporter failed (non-fatal): ${regErr instanceof Error ? regErr.message : String(regErr)}`);
217
+ }
218
+ }
219
+ catch (err) {
220
+ // mcporter not installed — non-fatal, print manual instructions
221
+ console.warn('mcporter not found. Install MCP servers manually:');
222
+ console.warn(` mcporter config add relaycast --command npx --arg @relaycast/mcp --env RELAY_API_KEY=${apiKey} --scope home`);
223
+ console.warn(` mcporter config add openclaw-spawner --command npx --arg @agent-relay/openclaw --arg mcp-server --env RELAY_API_KEY=${apiKey} --scope home`);
224
+ }
225
+ }
226
+ // Auto-start the inbound gateway in the background
227
+ let gatewayStarted = false;
228
+ try {
229
+ const child = spawnProcess('npx', ['@agent-relay/openclaw', 'gateway'], {
230
+ stdio: 'ignore',
231
+ detached: true,
232
+ env: { ...process.env, RELAY_API_KEY: apiKey, RELAY_CLAW_NAME: clawName, RELAY_BASE_URL: baseUrl },
233
+ });
234
+ child.unref();
235
+ gatewayStarted = true;
236
+ }
237
+ catch {
238
+ // Non-fatal — user can start manually
239
+ }
240
+ const parts = [
241
+ `Relaycast bridge installed at ${skillDir}`,
242
+ mcpConfigured ? 'MCP server configured in openclaw.json.' : '',
243
+ `Claw name: ${clawName}`,
244
+ `Channels: ${channels.join(', ')}`,
245
+ gatewayStarted
246
+ ? 'Inbound gateway started in background.'
247
+ : 'Start the inbound gateway manually:\n relay-openclaw gateway',
248
+ ].filter(Boolean);
249
+ return {
250
+ ok: true,
251
+ apiKey,
252
+ clawName,
253
+ skillDir,
254
+ message: parts.join('\n'),
255
+ };
256
+ }
257
+ /** Resolve the path to the bundled SKILL.md. */
258
+ function resolveSkillPath() {
259
+ try {
260
+ const thisDir = dirname(fileURLToPath(import.meta.url));
261
+ return join(thisDir, '..', 'skill', 'SKILL.md');
262
+ }
263
+ catch {
264
+ return join(process.cwd(), 'skill', 'SKILL.md');
265
+ }
266
+ }
267
+ const FALLBACK_SKILL_MD = `# Relaycast Bridge
268
+
269
+ Structured messaging for multi-claw communication. Provides channels, threads,
270
+ DMs, reactions, search, and persistent message history across OpenClaw instances.
271
+
272
+ ## Environment
273
+
274
+ - \`RELAY_API_KEY\` — Your Relaycast workspace key (required)
275
+ - \`RELAY_CLAW_NAME\` — This claw's agent name in Relaycast (required)
276
+ - \`RELAY_BASE_URL\` — API endpoint (default: https://api.relaycast.dev)
277
+
278
+ ## Setup
279
+
280
+ \`\`\`bash
281
+ relay-openclaw setup [YOUR_WORKSPACE_KEY]
282
+ \`\`\`
283
+
284
+ ## MCP Tools
285
+
286
+ Once installed, use the Relaycast MCP tools:
287
+ - \`post_message\` — Send to a channel
288
+ - \`send_dm\` — Direct message another agent
289
+ - \`reply_to_thread\` — Reply in a thread
290
+ - \`check_inbox\` — See unread messages
291
+
292
+ ## Commands
293
+
294
+ \`\`\`bash
295
+ relay-openclaw setup [key] # Install & configure
296
+ relay-openclaw gateway # Start inbound gateway
297
+ relay-openclaw status # Check connection
298
+ \`\`\`
299
+ `;
300
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import type { SpawnProvider, SpawnOptions, SpawnHandle } from './types.js';
2
+ export interface DockerSpawnProviderOptions {
3
+ /** Docker image to use. Default: 'openclaw:local'. */
4
+ image?: string;
5
+ /** Fallback image if primary not found. Default: 'clawrunner-sandbox:latest'. */
6
+ imageFallback?: string;
7
+ /** Docker network mode. Default: 'bridge'. */
8
+ networkMode?: string;
9
+ /** Docker socket path. Default: '/var/run/docker.sock'. */
10
+ socketPath?: string;
11
+ /** Path to host codex auth.json. Default: ~/.codex/auth.json. */
12
+ codexAuthFile?: string;
13
+ /** Path to host codex config.toml. Default: ~/.codex/config.toml. */
14
+ codexConfigFile?: string;
15
+ /** Container home dir. Default: '/home/node'. */
16
+ containerHome?: string;
17
+ /**
18
+ * Custom container command. If set, overrides the default entrypoint.
19
+ * Use this for ClawRunner-managed images that have /opt/clawrunner/start-claw.sh.
20
+ * Default: uses @agent-relay/openclaw runtime-setup + openclaw gateway + agent-relay broker-spawn.
21
+ */
22
+ containerCmd?: string[];
23
+ }
24
+ /**
25
+ * Spawn OpenClaw instances as Docker containers.
26
+ * Requires `dockerode` as an optional peer dependency — dynamically imported at runtime.
27
+ *
28
+ * By default, the container runs:
29
+ * 1. `npx @agent-relay/openclaw runtime-setup` — auth conversion, config, identity files, dist patching
30
+ * 2. `openclaw gateway` in background
31
+ * 3. `agent-relay broker-spawn --from-env` as PID 1
32
+ *
33
+ * For ClawRunner-managed images, set containerCmd to ['/opt/clawrunner/start-claw.sh'].
34
+ */
35
+ export declare class DockerSpawnProvider implements SpawnProvider {
36
+ private docker;
37
+ private readonly image;
38
+ private readonly imageFallback;
39
+ private readonly networkMode;
40
+ private readonly socketPath;
41
+ private readonly codexAuthFile;
42
+ private readonly codexConfigFile;
43
+ private readonly containerHome;
44
+ private readonly containerCmd;
45
+ private readonly handles;
46
+ constructor(options?: DockerSpawnProviderOptions);
47
+ private getDocker;
48
+ /**
49
+ * Build the default container entrypoint script.
50
+ * This script works with any vanilla OpenClaw image that has `openclaw` and `node` on PATH.
51
+ * It runs runtime-setup via the package CLI, starts the gateway, then hands off to broker-spawn.
52
+ */
53
+ private buildEntrypointScript;
54
+ spawn(options: SpawnOptions): Promise<SpawnHandle>;
55
+ destroy(id: string): Promise<void>;
56
+ list(): Promise<SpawnHandle[]>;
57
+ }
58
+ //# sourceMappingURL=docker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../src/spawn/docker.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA0B3E,MAAM,WAAW,0BAA0B;IACzC,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,mBAAoB,YAAW,aAAa;IAEvD,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkB;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;gBAE9C,OAAO,GAAE,0BAA+B;YActC,SAAS;IAevB;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAoCvB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAiGlD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYlC,IAAI,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;CAGrC"}
@@ -0,0 +1,222 @@
1
+ import { access } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ import { randomUUID } from 'node:crypto';
5
+ import { normalizeModelRef } from '../identity/model.js';
6
+ import { buildIdentityTask } from '../identity/contract.js';
7
+ import { buildAgentName } from '../identity/naming.js';
8
+ import { convertCodexAuth } from '../auth/converter.js';
9
+ async function pathExists(targetPath) {
10
+ try {
11
+ await access(targetPath);
12
+ return true;
13
+ }
14
+ catch {
15
+ return false;
16
+ }
17
+ }
18
+ function expandHomeDir(input) {
19
+ if (input === '~')
20
+ return homedir();
21
+ if (input.startsWith('~/'))
22
+ return join(homedir(), input.slice(2));
23
+ return input;
24
+ }
25
+ function sanitizeContainerSegment(value) {
26
+ const normalized = value.trim().toLowerCase().replace(/[^a-z0-9_.-]+/g, '-');
27
+ return normalized.replace(/^-+|-+$/g, '') || 'claw';
28
+ }
29
+ /**
30
+ * Spawn OpenClaw instances as Docker containers.
31
+ * Requires `dockerode` as an optional peer dependency — dynamically imported at runtime.
32
+ *
33
+ * By default, the container runs:
34
+ * 1. `npx @agent-relay/openclaw runtime-setup` — auth conversion, config, identity files, dist patching
35
+ * 2. `openclaw gateway` in background
36
+ * 3. `agent-relay broker-spawn --from-env` as PID 1
37
+ *
38
+ * For ClawRunner-managed images, set containerCmd to ['/opt/clawrunner/start-claw.sh'].
39
+ */
40
+ export class DockerSpawnProvider {
41
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
+ docker = null;
43
+ image;
44
+ imageFallback;
45
+ networkMode;
46
+ socketPath;
47
+ codexAuthFile;
48
+ codexConfigFile;
49
+ containerHome;
50
+ containerCmd;
51
+ handles = new Map();
52
+ constructor(options = {}) {
53
+ this.image = options.image ?? process.env.CLAW_IMAGE ?? 'openclaw:local';
54
+ this.imageFallback = options.imageFallback ?? process.env.CLAW_IMAGE_FALLBACK ?? 'clawrunner-sandbox:latest';
55
+ this.networkMode = options.networkMode ?? process.env.CLAW_NETWORK ?? 'bridge';
56
+ this.socketPath = options.socketPath ?? process.env.DOCKER_SOCKET ?? '/var/run/docker.sock';
57
+ this.codexAuthFile = expandHomeDir(options.codexAuthFile ?? process.env.CLAW_CODEX_AUTH_FILE ?? '~/.codex/auth.json');
58
+ this.codexConfigFile = expandHomeDir(options.codexConfigFile ?? process.env.CLAW_CODEX_CONFIG_FILE ?? '~/.codex/config.toml');
59
+ this.containerHome = options.containerHome ?? process.env.CLAW_CONTAINER_HOME ?? '/home/node';
60
+ this.containerCmd = options.containerCmd ?? (process.env.CLAW_CONTAINER_CMD
61
+ ? process.env.CLAW_CONTAINER_CMD.split(' ')
62
+ : null);
63
+ }
64
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
+ async getDocker() {
66
+ if (this.docker)
67
+ return this.docker;
68
+ try {
69
+ // @ts-expect-error dockerode is an optional dependency
70
+ const mod = await import('dockerode');
71
+ const Docker = mod.default ?? mod;
72
+ this.docker = new Docker({ socketPath: this.socketPath });
73
+ return this.docker;
74
+ }
75
+ catch {
76
+ throw new Error('dockerode is required for Docker spawning. Install it with: npm install dockerode');
77
+ }
78
+ }
79
+ /**
80
+ * Build the default container entrypoint script.
81
+ * This script works with any vanilla OpenClaw image that has `openclaw` and `node` on PATH.
82
+ * It runs runtime-setup via the package CLI, starts the gateway, then hands off to broker-spawn.
83
+ */
84
+ buildEntrypointScript(gatewayPort) {
85
+ // Shell script that runs setup, starts gateway, waits for health, then execs broker-spawn.
86
+ // Uses sh -c so it works in minimal alpine images.
87
+ // Runtime setup via package CLI, then gateway, then SDK's spawnFromEnv()
88
+ // which handles broker + agent lifecycle without needing the agent-relay CLI.
89
+ const script = [
90
+ 'set -e',
91
+ // Runtime setup: auth conversion, openclaw.json, identity files, dist patching
92
+ 'npx @agent-relay/openclaw runtime-setup',
93
+ // Resolve bridge.mjs from the installed package and symlink to the known AGENT_ARGS path.
94
+ // This handles any npm install location (global, local, npx cache).
95
+ 'node -e "' +
96
+ "const p = require('path');" +
97
+ "const m = require('module');" +
98
+ "const r = m.createRequire(require.resolve('@agent-relay/openclaw/package.json'));" +
99
+ "const bp = p.join(p.dirname(require.resolve('@agent-relay/openclaw/package.json')), 'bridge', 'bridge.mjs');" +
100
+ "require('fs').symlinkSync(bp, '/tmp/openclaw-bridge.mjs');" +
101
+ "console.log('[entrypoint] Bridge resolved: ' + bp);" +
102
+ '"',
103
+ // Start gateway in background
104
+ `openclaw gateway --port ${gatewayPort} --bind loopback --allow-unconfigured --auth token &`,
105
+ // Wait for gateway health
106
+ `for i in $(seq 1 30); do`,
107
+ ` if openclaw health --port ${gatewayPort} 2>/dev/null; then break; fi`,
108
+ ` if [ "$i" -eq 30 ]; then echo "Gateway failed to start" >&2; exit 1; fi`,
109
+ ` sleep 1`,
110
+ `done`,
111
+ // Use SDK's spawnFromEnv() instead of shelling out to agent-relay CLI.
112
+ // This reads AGENT_NAME, AGENT_CLI, RELAY_API_KEY etc. from env,
113
+ // creates a broker internally, spawns the agent via PTY, and waits for exit.
114
+ `node -e "import('@agent-relay/sdk').then(m => m.spawnFromEnv())"`,
115
+ ].join('\n');
116
+ return ['sh', '-c', script];
117
+ }
118
+ async spawn(options) {
119
+ const docker = await this.getDocker();
120
+ const { preferredProvider } = await convertCodexAuth();
121
+ const modelRef = normalizeModelRef(options.model, preferredProvider);
122
+ const workspaceId = options.workspaceId ?? `local-${Date.now().toString(36)}`;
123
+ const agentName = buildAgentName(workspaceId, options.name);
124
+ const gatewayPort = 18789; // Internal to container — each container is isolated
125
+ const identityTask = buildIdentityTask(agentName, workspaceId, modelRef);
126
+ const channels = options.channels?.length ? options.channels : ['general'];
127
+ const gatewayToken = randomUUID().replace(/-/g, '').slice(0, 32);
128
+ const suffix = `${Date.now().toString(36)}-${randomUUID().slice(0, 8)}`;
129
+ const containerName = `openclaw-${sanitizeContainerSegment(agentName)}-${suffix}`.slice(0, 63);
130
+ const binds = [];
131
+ if (options.workspacePath) {
132
+ binds.push(`${options.workspacePath}:/workspace:rw`);
133
+ }
134
+ if (await pathExists(this.codexAuthFile)) {
135
+ binds.push(`${this.codexAuthFile}:${this.containerHome}/.codex/auth.json:rw`);
136
+ }
137
+ if (await pathExists(this.codexConfigFile)) {
138
+ binds.push(`${this.codexConfigFile}:${this.containerHome}/.codex/config.toml:ro`);
139
+ }
140
+ const envVars = {
141
+ AGENT_NAME: agentName,
142
+ AGENT_CLI: 'node',
143
+ // Bridge path: resolved dynamically inside the container via the entrypoint script.
144
+ // The entrypoint writes the resolved path to /tmp/bridge-path.txt after runtime-setup.
145
+ AGENT_ARGS: '/tmp/openclaw-bridge.mjs',
146
+ RELAY_API_KEY: options.relayApiKey,
147
+ RELAY_BASE_URL: options.relayBaseUrl ?? '',
148
+ AGENT_TASK: options.systemPrompt
149
+ ? `${options.systemPrompt}\n\n${identityTask}`
150
+ : identityTask,
151
+ AGENT_CWD: '/workspace',
152
+ AGENT_CHANNELS: channels.join(','),
153
+ GATEWAY_PORT: String(gatewayPort),
154
+ OPENCLAW_GATEWAY_TOKEN: gatewayToken,
155
+ OPENCLAW_WORKSPACE_ID: workspaceId,
156
+ OPENCLAW_NAME: options.name,
157
+ OPENCLAW_ROLE: options.role ?? 'general',
158
+ OPENCLAW_MODEL: modelRef,
159
+ BROKER_NO_REMOTE_SPAWN: '1',
160
+ };
161
+ // Try to remove stale container with same name
162
+ try {
163
+ const stale = docker.getContainer(containerName);
164
+ await stale.stop({ t: 5 }).catch(() => { });
165
+ await stale.remove({ force: true }).catch(() => { });
166
+ }
167
+ catch {
168
+ // No stale container
169
+ }
170
+ let imageToUse = this.image;
171
+ try {
172
+ await docker.getImage(this.image).inspect();
173
+ }
174
+ catch {
175
+ imageToUse = this.imageFallback;
176
+ }
177
+ // Use custom cmd if provided, otherwise generate a vanilla-compatible entrypoint
178
+ const cmd = this.containerCmd ?? this.buildEntrypointScript(gatewayPort);
179
+ const container = await docker.createContainer({
180
+ Image: imageToUse,
181
+ name: containerName,
182
+ Env: Object.entries(envVars).map(([k, v]) => `${k}=${v}`),
183
+ Cmd: cmd,
184
+ WorkingDir: '/workspace',
185
+ Labels: {
186
+ '@agent-relay/openclaw.spawn': 'true',
187
+ '@agent-relay/openclaw.agent': agentName,
188
+ },
189
+ HostConfig: {
190
+ NetworkMode: this.networkMode,
191
+ Binds: binds,
192
+ AutoRemove: false,
193
+ },
194
+ });
195
+ await container.start();
196
+ const handle = {
197
+ id: container.id,
198
+ displayName: options.name,
199
+ agentName,
200
+ gatewayPort,
201
+ destroy: () => this.destroy(container.id),
202
+ };
203
+ this.handles.set(container.id, handle);
204
+ return handle;
205
+ }
206
+ async destroy(id) {
207
+ this.handles.delete(id);
208
+ try {
209
+ const docker = await this.getDocker();
210
+ const container = docker.getContainer(id);
211
+ await container.stop({ t: 5 }).catch(() => { });
212
+ await container.remove({ force: true }).catch(() => { });
213
+ }
214
+ catch {
215
+ // Already gone
216
+ }
217
+ }
218
+ async list() {
219
+ return Array.from(this.handles.values());
220
+ }
221
+ }
222
+ //# sourceMappingURL=docker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker.js","sourceRoot":"","sources":["../../src/spawn/docker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { SpawnOptions, SpawnHandle } from './types.js';
2
+ export type SpawnMode = 'process' | 'docker';
3
+ interface PersistedSpawn {
4
+ id: string;
5
+ displayName: string;
6
+ agentName: string;
7
+ gatewayPort: number;
8
+ spawnedAt: string;
9
+ }
10
+ /**
11
+ * SpawnManager — tracks active spawns and provides a unified interface
12
+ * for spawning, listing, and releasing OpenClaw instances.
13
+ *
14
+ * Security controls:
15
+ * - maxSpawns: Maximum concurrent spawns (default: 10)
16
+ * - maxDepth: Maximum spawn depth to prevent recursive chains (default: 3)
17
+ * - Persistent state in spawns.json for recovery on restart
18
+ */
19
+ export declare class SpawnManager {
20
+ private readonly provider;
21
+ private readonly handles;
22
+ private readonly maxSpawns;
23
+ private readonly maxDepth;
24
+ private readonly stateFile;
25
+ private currentDepth;
26
+ constructor(options?: {
27
+ mode?: SpawnMode;
28
+ maxSpawns?: number;
29
+ maxDepth?: number;
30
+ spawnDepth?: number;
31
+ });
32
+ spawn(options: SpawnOptions): Promise<SpawnHandle>;
33
+ release(id: string): Promise<boolean>;
34
+ releaseByName(name: string): Promise<boolean>;
35
+ releaseAll(): Promise<void>;
36
+ list(): SpawnHandle[];
37
+ get(id: string): SpawnHandle | undefined;
38
+ get size(): number;
39
+ /** Persist spawn state to disk for recovery. */
40
+ private persistState;
41
+ /** Load persisted state (for display/diagnostics only — processes can't be recovered). */
42
+ loadPersistedState(): Promise<PersistedSpawn[]>;
43
+ }
44
+ export {};
45
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/spawn/manager.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAiB,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI3E,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAQ7C,UAAU,cAAc;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAeD;;;;;;;;GAQG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,YAAY,CAAS;gBAEjB,OAAO,CAAC,EAAE;QACpB,IAAI,CAAC,EAAE,SAAS,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB;IAkBK,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IA8BlD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IASrC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAa7C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAKjC,IAAI,IAAI,WAAW,EAAE;IAIrB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAIxC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,gDAAgD;YAClC,YAAY;IAqB1B,0FAA0F;IACpF,kBAAkB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;CAUtD"}