shadow-claw 1.34.5 → 1.35.0

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 (193) hide show
  1. package/.well-known/mcp/server-card.json +1 -1
  2. package/.well-known/mcp.json +1 -1
  3. package/README.md +5 -1
  4. package/dist/cli/chunk-BCLxzLO92.js +5 -0
  5. package/dist/cli/chunk-BHNCi3ui2.js +1 -0
  6. package/dist/cli/chunk-BMPhLSn8.js +1 -0
  7. package/dist/cli/chunk-BMW6QB5-2.js +27 -0
  8. package/dist/cli/chunk-BQCWtrzh.js +1 -0
  9. package/dist/cli/chunk-BQCWtrzh2.js +1 -0
  10. package/dist/cli/chunk-BdJUjMuz.js +1 -0
  11. package/dist/cli/chunk-C47WdxKx2.js +1 -0
  12. package/dist/cli/{chunk-D9dku_3t.js → chunk-CAqvQuGr.js} +1 -1
  13. package/dist/cli/{chunk-DoVxObGa2.js → chunk-CHzhUS1N2.js} +1 -1
  14. package/dist/cli/chunk-CUMlq7Jw2.js +263 -0
  15. package/dist/cli/chunk-CXi9LU9e2.js +110 -0
  16. package/dist/cli/chunk-ChefnX-r.js +110 -0
  17. package/dist/cli/{chunk-zvi71-77.js → chunk-D3JxbzjI2.js} +15 -15
  18. package/dist/cli/chunk-D7VYMl092.js +1 -0
  19. package/dist/cli/chunk-DNIduiJ82.js +91 -0
  20. package/dist/cli/{chunk-C4UfzPK4.js → chunk-DTbrldk_.js} +1 -1
  21. package/dist/cli/chunk-DZ8YBXax.js +969 -0
  22. package/dist/cli/chunk-DduRvw8B2.js +1 -0
  23. package/dist/cli/chunk-DnYxGjdu2.js +1 -0
  24. package/dist/cli/chunk-Ea7nXmgb2.js +1 -0
  25. package/dist/cli/{chunk-BRiGkTIi.js → chunk-EohNY8vW.js} +1 -1
  26. package/dist/cli/chunk-LIIpZlwP2.js +1 -0
  27. package/dist/cli/chunk-LIJZHJml2.js +1 -0
  28. package/dist/cli/chunk-MHBh2BgF2.js +91 -0
  29. package/dist/cli/{chunk-BQ7lHA7c.js → chunk-SKgLGyTY.js} +1 -1
  30. package/dist/cli/chunk-kcJSXcbq2.js +1 -0
  31. package/dist/cli/cli.js +12 -11
  32. package/dist/headless-agent.js +191 -187
  33. package/dist/lib/components/index.js +21 -21
  34. package/dist/lib/components/settings/shadow-claw-channel-config.js +1 -1
  35. package/dist/lib/components/settings/shadow-claw-control-plane.js +1 -1
  36. package/dist/lib/components/settings/shadow-claw-git.js +1 -1
  37. package/dist/lib/components/settings/shadow-claw-llm.js +1 -1
  38. package/dist/lib/components/settings/shadow-claw-networking.js +1 -1
  39. package/dist/lib/components/settings/shadow-claw-notifications.js +1 -1
  40. package/dist/lib/components/settings/shadow-claw-peerjs.js +1 -1
  41. package/dist/lib/components/settings/shadow-claw-storage.js +1 -1
  42. package/dist/lib/components/settings/shadow-claw-task-server.js +1 -1
  43. package/dist/lib/components/settings/shadow-claw-webvm.js +1 -1
  44. package/dist/lib/components/shadow-claw-channel-config.js +1 -1
  45. package/dist/lib/components/shadow-claw-channels.js +1 -1
  46. package/dist/lib/components/shadow-claw-chat.js +1 -1
  47. package/dist/lib/components/shadow-claw-control-plane.js +1 -1
  48. package/dist/lib/components/shadow-claw-conversations.js +1 -1
  49. package/dist/lib/components/shadow-claw-file-viewer.js +1 -1
  50. package/dist/lib/components/shadow-claw-files.js +1 -1
  51. package/dist/lib/components/shadow-claw-git.js +1 -1
  52. package/dist/lib/components/shadow-claw-llm.js +1 -1
  53. package/dist/lib/components/shadow-claw-networking.js +1 -1
  54. package/dist/lib/components/shadow-claw-notifications.js +1 -1
  55. package/dist/lib/components/shadow-claw-pages.js +1 -1
  56. package/dist/lib/components/shadow-claw-peerjs.js +1 -1
  57. package/dist/lib/components/shadow-claw-settings.js +1 -1
  58. package/dist/lib/components/shadow-claw-storage.js +1 -1
  59. package/dist/lib/components/shadow-claw-task-server.js +1 -1
  60. package/dist/lib/components/shadow-claw-tasks.js +1 -1
  61. package/dist/lib/components/shadow-claw-terminal.js +1 -1
  62. package/dist/lib/components/shadow-claw-tools.js +1 -1
  63. package/dist/lib/components/shadow-claw-webvm.js +1 -1
  64. package/dist/lib/components/shadow-claw.js +1 -1
  65. package/dist/lib/{configurePeerJs-DSRcNp3v.js → configurePeerJs-CdPzmpyI.js} +2 -2
  66. package/dist/lib/{configurePeerJs-DSRcNp3v.js.map → configurePeerJs-CdPzmpyI.js.map} +1 -1
  67. package/dist/lib/index.js +21 -21
  68. package/dist/lib/{initControlPlane-CWfE_Oan.js → initControlPlane-BLymRW34.js} +7 -7
  69. package/dist/lib/{initControlPlane-CWfE_Oan.js.map → initControlPlane-BLymRW34.js.map} +1 -1
  70. package/dist/lib/{orchestrator-BEUug1TW.js → orchestrator-DZkhJj7f.js} +13 -2
  71. package/dist/lib/{orchestrator-BEUug1TW.js.map → orchestrator-DZkhJj7f.js.map} +1 -1
  72. package/dist/lib/{orchestrator-CGUzfGbE.js → orchestrator-ZsQTRknI.js} +5 -5
  73. package/dist/lib/{orchestrator-CGUzfGbE.js.map → orchestrator-ZsQTRknI.js.map} +1 -1
  74. package/dist/lib/{peerjs-BSD88rT3.js → peerjs-CJYfnR5V.js} +3 -3
  75. package/dist/lib/{peerjs-BSD88rT3.js.map → peerjs-CJYfnR5V.js.map} +1 -1
  76. package/dist/lib/{push-client-CC3qifgc.js → push-client-C9hIPqLZ.js} +2 -2
  77. package/dist/lib/{push-client-CC3qifgc.js.map → push-client-C9hIPqLZ.js.map} +1 -1
  78. package/dist/lib/{shadow-claw-BWS-UVnE.js → shadow-claw-8qL2-QoK.js} +4 -4
  79. package/dist/lib/{shadow-claw-BWS-UVnE.js.map → shadow-claw-8qL2-QoK.js.map} +1 -1
  80. package/dist/lib/{shadow-claw-channel-config-DwMn3nFJ.js → shadow-claw-channel-config-CvnbqGBy.js} +3 -3
  81. package/dist/lib/{shadow-claw-channel-config-DwMn3nFJ.js.map → shadow-claw-channel-config-CvnbqGBy.js.map} +1 -1
  82. package/dist/lib/{shadow-claw-channels-BdE4cUlx.js → shadow-claw-channels-CkCvjWn1.js} +2 -2
  83. package/dist/lib/{shadow-claw-channels-BdE4cUlx.js.map → shadow-claw-channels-CkCvjWn1.js.map} +1 -1
  84. package/dist/lib/{shadow-claw-chat-DqaMoE9C.js → shadow-claw-chat-B1YEHKN3.js} +3 -3
  85. package/dist/lib/{shadow-claw-chat-DqaMoE9C.js.map → shadow-claw-chat-B1YEHKN3.js.map} +1 -1
  86. package/dist/lib/{shadow-claw-control-plane-D3DUDO29.js → shadow-claw-control-plane-jjo789IE.js} +6 -6
  87. package/dist/lib/{shadow-claw-control-plane-D3DUDO29.js.map → shadow-claw-control-plane-jjo789IE.js.map} +1 -1
  88. package/dist/lib/{shadow-claw-conversations-XT-OXogj.js → shadow-claw-conversations-MMT7wYH3.js} +2 -2
  89. package/dist/lib/{shadow-claw-conversations-XT-OXogj.js.map → shadow-claw-conversations-MMT7wYH3.js.map} +1 -1
  90. package/dist/lib/{shadow-claw-file-viewer-DJqxyd97.js → shadow-claw-file-viewer-qSkD1RQK.js} +2 -2
  91. package/dist/lib/{shadow-claw-file-viewer-DJqxyd97.js.map → shadow-claw-file-viewer-qSkD1RQK.js.map} +1 -1
  92. package/dist/lib/{shadow-claw-files-CUEJlA1o.js → shadow-claw-files-Cg8ycQ_N.js} +2 -2
  93. package/dist/lib/{shadow-claw-files-CUEJlA1o.js.map → shadow-claw-files-Cg8ycQ_N.js.map} +1 -1
  94. package/dist/lib/{shadow-claw-git-D_iVcb86.js → shadow-claw-git-gaClz-ZC.js} +3 -3
  95. package/dist/lib/{shadow-claw-git-D_iVcb86.js.map → shadow-claw-git-gaClz-ZC.js.map} +1 -1
  96. package/dist/lib/{shadow-claw-llm-C2msAsyU.js → shadow-claw-llm-DyOz0qzT.js} +2 -2
  97. package/dist/lib/{shadow-claw-llm-C2msAsyU.js.map → shadow-claw-llm-DyOz0qzT.js.map} +1 -1
  98. package/dist/lib/{shadow-claw-networking-D2NvodC-.js → shadow-claw-networking-B2xx0UUR.js} +2 -2
  99. package/dist/lib/{shadow-claw-networking-D2NvodC-.js.map → shadow-claw-networking-B2xx0UUR.js.map} +1 -1
  100. package/dist/lib/{shadow-claw-notifications-BcvVn_vu.js → shadow-claw-notifications-BjKfZy0k.js} +2 -2
  101. package/dist/lib/{shadow-claw-notifications-BcvVn_vu.js.map → shadow-claw-notifications-BjKfZy0k.js.map} +1 -1
  102. package/dist/lib/{shadow-claw-pages-CTMXRhEX.js → shadow-claw-pages-CJ2tsMtL.js} +2 -2
  103. package/dist/lib/{shadow-claw-pages-CTMXRhEX.js.map → shadow-claw-pages-CJ2tsMtL.js.map} +1 -1
  104. package/dist/lib/{shadow-claw-peerjs-C2YvypqM.js → shadow-claw-peerjs-CazCkXQ1.js} +3 -3
  105. package/dist/lib/{shadow-claw-peerjs-C2YvypqM.js.map → shadow-claw-peerjs-CazCkXQ1.js.map} +1 -1
  106. package/dist/lib/{shadow-claw-settings-B0hiDwEt.js → shadow-claw-settings-qro6pO9I.js} +2 -2
  107. package/dist/lib/{shadow-claw-settings-B0hiDwEt.js.map → shadow-claw-settings-qro6pO9I.js.map} +1 -1
  108. package/dist/lib/{shadow-claw-storage-Dt4yg4Q4.js → shadow-claw-storage-ewDdvCGa.js} +2 -2
  109. package/dist/lib/{shadow-claw-storage-Dt4yg4Q4.js.map → shadow-claw-storage-ewDdvCGa.js.map} +1 -1
  110. package/dist/lib/{shadow-claw-task-server-B2gbZaz4.js → shadow-claw-task-server-DpqQcNIs.js} +2 -2
  111. package/dist/lib/{shadow-claw-task-server-B2gbZaz4.js.map → shadow-claw-task-server-DpqQcNIs.js.map} +1 -1
  112. package/dist/lib/{shadow-claw-tasks-Bxq-niuM.js → shadow-claw-tasks-B2fMF4qE.js} +2 -2
  113. package/dist/lib/{shadow-claw-tasks-Bxq-niuM.js.map → shadow-claw-tasks-B2fMF4qE.js.map} +1 -1
  114. package/dist/lib/{shadow-claw-terminal-BfbW3xtg.js → shadow-claw-terminal-B25kQJC3.js} +2 -2
  115. package/dist/lib/{shadow-claw-terminal-BfbW3xtg.js.map → shadow-claw-terminal-B25kQJC3.js.map} +1 -1
  116. package/dist/lib/{shadow-claw-tools-BNSAaK0Y.js → shadow-claw-tools-B0y8JzoA.js} +10 -3
  117. package/dist/lib/{shadow-claw-tools-BNSAaK0Y.js.map → shadow-claw-tools-B0y8JzoA.js.map} +1 -1
  118. package/dist/lib/{shadow-claw-webvm-Dc2KmEXq.js → shadow-claw-webvm-CoCedIza.js} +2 -2
  119. package/dist/lib/{shadow-claw-webvm-Dc2KmEXq.js.map → shadow-claw-webvm-CoCedIza.js.map} +1 -1
  120. package/dist/lib/{syncWebMcpRegistration-BIL83P0Q.js → syncWebMcpRegistration-JKLALq4e.js} +2 -2
  121. package/dist/lib/{syncWebMcpRegistration-BIL83P0Q.js.map → syncWebMcpRegistration-JKLALq4e.js.map} +1 -1
  122. package/dist/lib/worker/utils/sandboxedEval.d.ts +8 -0
  123. package/dist/public/.well-known/mcp/server-card.json +1 -1
  124. package/dist/public/.well-known/mcp.json +1 -1
  125. package/dist/public/AGENTS.md +1 -1
  126. package/dist/public/README.md +5 -1
  127. package/dist/public/agent.worker.js +1 -1
  128. package/dist/public/components/shadow-claw-tools/shadow-claw-tools.html +1 -1
  129. package/dist/public/{configurePeerJs-B925t9C7.js → configurePeerJs-BrHeJGw1.js} +1 -1
  130. package/dist/public/docs/decisions/headless-cli-agent-participant.md +1 -1
  131. package/dist/public/docs/example/article/index.html +1 -1
  132. package/dist/public/docs/publishing/index.html +1 -1
  133. package/dist/public/docs/skill-creator/index.html +1 -1
  134. package/dist/public/docs/subsystems/cli.md +33 -23
  135. package/dist/public/docs/subsystems/skills.md +17 -0
  136. package/dist/public/docs/subsystems/tools.md +1 -1
  137. package/dist/public/e2e/README.md +2 -2
  138. package/dist/public/{e2e-bridge-CE1xleGn.js → e2e-bridge-D_lyH__p.js} +1 -1
  139. package/dist/public/{executeTool-DtTrsZHV.js → executeTool-b6DnRhcv.js} +2 -1
  140. package/dist/public/{file-viewer-LEEStSq-.js → file-viewer-CKrQoxZi.js} +1 -1
  141. package/dist/public/index.html +1 -1
  142. package/dist/public/index.js +1 -1
  143. package/dist/public/{initControlPlane-e2JgxXEb.js → initControlPlane-Dn-XFuxg.js} +1 -1
  144. package/dist/public/llms.txt +2 -0
  145. package/dist/public/main/index.html +1 -1
  146. package/dist/public/main/memory/index.html +1 -1
  147. package/dist/public/{orchestrator-Baif6kmu.js → orchestrator-0BnBtxHO.js} +3 -2
  148. package/dist/public/{orchestrator-TndREZPL.js → orchestrator-C3GKZriH.js} +1 -1
  149. package/dist/public/{peerjs-DE6WF3h2.js → peerjs-CgfLEp2N.js} +1 -1
  150. package/dist/public/{push-client-B_IkTpNm.js → push-client-D6DLiY1s.js} +1 -1
  151. package/dist/public/service-worker.js +1 -1
  152. package/dist/public/{shadow-claw-channels-BCGz36Zl.js → shadow-claw-channels-DSijinZ9.js} +1 -1
  153. package/dist/public/{shadow-claw-chat-H9U9jbqD.js → shadow-claw-chat-BeHlAjnA.js} +1 -1
  154. package/dist/public/{shadow-claw-control-plane-CeKh64s2.js → shadow-claw-control-plane-BfF_AZSg.js} +2 -2
  155. package/dist/public/{shadow-claw-conversations-C26t1HXN.js → shadow-claw-conversations-Bb_2bVLJ.js} +1 -1
  156. package/dist/public/{shadow-claw-DBeXILmk.js → shadow-claw-f71DlRdV.js} +2 -2
  157. package/dist/public/{shadow-claw-file-viewer-DWUoTjkr.js → shadow-claw-file-viewer-B67000Mm.js} +1 -1
  158. package/dist/public/{shadow-claw-files-BQ8DSX-z.js → shadow-claw-files-DeZZYt01.js} +1 -1
  159. package/dist/public/{shadow-claw-git-CIXyISw-.js → shadow-claw-git-Ccy25LuW.js} +2 -2
  160. package/dist/public/{shadow-claw-llm-D_GpOSZE.js → shadow-claw-llm-XjYcTlXT.js} +1 -1
  161. package/dist/public/{shadow-claw-networking-BYp5K3B7.js → shadow-claw-networking-efXQtydQ.js} +1 -1
  162. package/dist/public/{shadow-claw-notifications-ZiXmPweY.js → shadow-claw-notifications-Cq2ZSeJa.js} +1 -1
  163. package/dist/public/{shadow-claw-pages-BHXwf3BD.js → shadow-claw-pages-BVFNSSb1.js} +1 -1
  164. package/dist/public/{shadow-claw-settings-BfvDvt9c.js → shadow-claw-settings-B3sHxPh9.js} +2 -2
  165. package/dist/public/{shadow-claw-storage-Bvn85DII.js → shadow-claw-storage-DNdlzCgC.js} +1 -1
  166. package/dist/public/{shadow-claw-task-server-DZL_d8FC.js → shadow-claw-task-server-BJq0rpju.js} +1 -1
  167. package/dist/public/{shadow-claw-tasks-Cy8jzd8q.js → shadow-claw-tasks-CkF1uMeZ.js} +1 -1
  168. package/dist/public/{shadow-claw-terminal-BgEXr82T.js → shadow-claw-terminal-CnHhcpA-.js} +1 -1
  169. package/dist/public/{shadow-claw-tools-BjnssRSi.js → shadow-claw-tools-iw0fljud.js} +8 -1
  170. package/dist/public/{shadow-claw-webvm-tZ1VDoVA.js → shadow-claw-webvm-Bliu4V__.js} +1 -1
  171. package/dist/public/{syncWebMcpRegistration-CLMvJ4kV.js → syncWebMcpRegistration-D91usEMu.js} +1 -1
  172. package/package.json +1 -1
  173. package/src/cli/cli.ts +26 -2
  174. package/src/cli/commands/agent.test.ts +421 -0
  175. package/src/cli/commands/agent.ts +270 -20
  176. package/src/components/shadow-claw-tools/shadow-claw-tools.html +7 -0
  177. package/src/worker/headless-agent.ts +14 -0
  178. package/src/worker/headless-types.ts +39 -0
  179. package/src/worker/utils/native-eval-executor.test.ts +36 -0
  180. package/src/worker/utils/native-eval-executor.ts +58 -0
  181. package/src/worker/utils/sandboxedEval.ts +36 -0
  182. package/dist/cli/chunk-1BmpU7jO2.js +0 -1
  183. package/dist/cli/chunk-54Euq8Ji2.js +0 -1
  184. package/dist/cli/chunk-BTitwCgT2.js +0 -88
  185. package/dist/cli/chunk-Bjh76Dai.js +0 -1081
  186. package/dist/cli/chunk-C2HeZQ6K.js +0 -1
  187. package/dist/cli/chunk-CxdpafWg.js +0 -1
  188. package/dist/cli/chunk-DEy72ZNV2.js +0 -88
  189. package/dist/cli/chunk-Da1BZyqf.js +0 -1
  190. package/dist/cli/chunk-FHsJD-Sf2.js +0 -27
  191. package/dist/cli/chunk-aWgoVB7x2.js +0 -1
  192. package/dist/cli/chunk-hOceZVB92.js +0 -371
  193. package/dist/cli/chunk-pwNc6VtC2.js +0 -1
@@ -21,6 +21,8 @@ import type {
21
21
  AgentRunResult,
22
22
  AgentModelOptions,
23
23
  AgentModelResult,
24
+ AgentImportOptions,
25
+ AgentImportResult,
24
26
  } from "../../worker/headless-types.js";
25
27
 
26
28
  import { bootstrapHeadlessAgent } from "./agent-bootstrap.js";
@@ -254,6 +256,8 @@ export async function runAgentTools(
254
256
  options: AgentToolsOptions & Record<string, any> = {},
255
257
  ): Promise<any> {
256
258
  const { db, core } = await bootstrapHeadlessAgent(options);
259
+ const groupId =
260
+ options.group || core.DEFAULT_SERVER_GROUP_ID || DEFAULT_SERVER_GROUP_ID;
257
261
 
258
262
  let profileToolNames: Set<string> | null = null;
259
263
  if (options.toolsProfile || options.profile) {
@@ -283,7 +287,21 @@ export async function runAgentTools(
283
287
  }
284
288
  }
285
289
 
286
- const tools = (core.TOOL_DEFINITIONS || []).map((def) => ({
290
+ const allTools = [...(core.TOOL_DEFINITIONS || [])];
291
+ if (typeof core.loadDeclarativeTools === "function") {
292
+ try {
293
+ const decl = await core.loadDeclarativeTools(db, groupId);
294
+ if (decl && Array.isArray(decl.tools)) {
295
+ for (const dt of decl.tools) {
296
+ if (!allTools.some((t) => t.name === dt.name)) {
297
+ allTools.push(dt);
298
+ }
299
+ }
300
+ }
301
+ } catch {}
302
+ }
303
+
304
+ const tools = allTools.map((def) => ({
287
305
  name: def.name,
288
306
  description: def.description,
289
307
  headlessSafe: !BROWSER_ONLY_TOOLS.has(def.name),
@@ -310,11 +328,14 @@ export async function runAgentTool(
310
328
  options.group || core.DEFAULT_SERVER_GROUP_ID || DEFAULT_SERVER_GROUP_ID;
311
329
 
312
330
  // Find tool in built-in TOOL_DEFINITIONS or declarative tools
313
- let toolDef = (core.TOOL_DEFINITIONS || []).find((t) => t.name === toolName);
331
+ let toolDef = (core.TOOL_DEFINITIONS || []).find(
332
+ (t: any) => t.name === toolName,
333
+ );
334
+
314
335
  if (!toolDef && typeof core.loadDeclarativeTools === "function") {
315
336
  try {
316
337
  const decl = await core.loadDeclarativeTools(db, groupId);
317
- toolDef = decl.tools.find((t) => t.name === toolName);
338
+ toolDef = decl.tools.find((t: any) => t.name === toolName);
318
339
  } catch {}
319
340
  }
320
341
 
@@ -370,12 +391,10 @@ export async function runAgentTool(
370
391
 
371
392
  let invokeContext: any = undefined;
372
393
  try {
373
- const resolved = await resolveAgentProvider(
374
- db,
375
- core,
376
- workspaceDir,
377
- options,
378
- );
394
+ const resolved = await resolveAgentProvider(db, core, workspaceDir, {
395
+ ...options,
396
+ interactive: false,
397
+ });
379
398
  invokeContext = {
380
399
  db,
381
400
  provider: resolved.providerId,
@@ -471,7 +490,7 @@ export async function runAgentSkill(
471
490
  skill.execution?.type === "tools" &&
472
491
  Array.isArray(skill.execution.tools)
473
492
  ) {
474
- const normalizedTools = skill.execution.tools.map((t) => ({
493
+ const normalizedTools = skill.execution.tools.map((t: any) => ({
475
494
  name: t.name || t.tool,
476
495
  input: t.input || t.arguments || {},
477
496
  suppressOutput: t.suppressOutput,
@@ -565,7 +584,8 @@ export async function resolveAgentProvider(
565
584
  process.env.CI &&
566
585
  !["0", "false"].includes(process.env.CI.toLowerCase()),
567
586
  );
568
- const isInteractive = isTTY && !isCI && !options.quiet;
587
+ const isInteractive =
588
+ isTTY && !isCI && !options.quiet && options.interactive !== false;
569
589
 
570
590
  if (!providerId) {
571
591
  if (isInteractive) {
@@ -726,7 +746,7 @@ export async function resolveAgentProvider(
726
746
  const processSigintListener = () => handleSigint();
727
747
  process.on("SIGINT", processSigintListener);
728
748
 
729
- const dataListener = (chunk) => {
749
+ const dataListener = (chunk: any) => {
730
750
  const str =
731
751
  typeof chunk === "string" ? chunk : chunk.toString("binary");
732
752
  if (str.includes("\x03") || str.includes("\x04")) {
@@ -883,11 +903,13 @@ async function resolveToolsAndProfile(
883
903
  ? options.tools
884
904
  : String(options.tools).split(",")
885
905
  )
886
- .map((t) => String(t).trim())
906
+ .map((t: unknown) => String(t).trim())
887
907
  .filter(Boolean);
888
908
 
889
909
  enabledTools = requestedNames
890
- .map((name) => allAvailableTools.find((t) => t.name === name))
910
+ .map((name: unknown) =>
911
+ allAvailableTools.find((t) => t.name === String(name)),
912
+ )
891
913
  .filter(Boolean);
892
914
  return { enabledTools, profileSystemPromptOverride };
893
915
  }
@@ -1098,7 +1120,7 @@ export async function runAgentRun(
1098
1120
  let hasStreamedChunks = false;
1099
1121
  const pendingWrites: Promise<void>[] = [];
1100
1122
 
1101
- core.setPostHandler(async (message) => {
1123
+ core.setPostHandler(async (message: any) => {
1102
1124
  switch (message.type) {
1103
1125
  case "streaming-start":
1104
1126
  hasStreamedChunks = true;
@@ -1197,15 +1219,15 @@ export async function runAgentRun(
1197
1219
  groupId: taskGroupId,
1198
1220
  db,
1199
1221
  })
1200
- .then((res) => {
1201
- const resolvers = globalThis.pendingNativeAiResolvers;
1222
+ .then((res: unknown) => {
1223
+ const resolvers = (globalThis as any).pendingNativeAiResolvers;
1202
1224
  if (resolvers && resolvers[id]) {
1203
1225
  resolvers[id].resolve(res);
1204
1226
  delete resolvers[id];
1205
1227
  }
1206
1228
  })
1207
- .catch((err) => {
1208
- const resolvers = globalThis.pendingNativeAiResolvers;
1229
+ .catch((err: unknown) => {
1230
+ const resolvers = (globalThis as any).pendingNativeAiResolvers;
1209
1231
  if (resolvers && resolvers[id]) {
1210
1232
  resolvers[id].reject(err);
1211
1233
  delete resolvers[id];
@@ -1601,6 +1623,218 @@ export async function runAgentModel(
1601
1623
  return { success: false, error: errorMsg };
1602
1624
  }
1603
1625
 
1626
+ /**
1627
+ * Import tools, skills, and companion scripts from a remote discovery manifest or site URL.
1628
+ * @param {string} urlOrSite
1629
+ * @param {import("../../src/worker/headless-types.js").AgentImportOptions} [options]
1630
+ * @returns {Promise<import("../../src/worker/headless-types.js").AgentImportResult>}
1631
+ */
1632
+ export async function runAgentImport(
1633
+ urlOrSite: string,
1634
+ options: AgentImportOptions & Record<string, any> = {},
1635
+ ): Promise<AgentImportResult> {
1636
+ const trimmedUrl = (urlOrSite || "").trim();
1637
+ if (!trimmedUrl) {
1638
+ const errorMsg =
1639
+ "Error: Discovery URL or site URL required. Usage: shadow-claw agent import <url> [options]";
1640
+ if (!options.quiet) {
1641
+ console.error(errorMsg);
1642
+ }
1643
+ process.exitCode = 1;
1644
+ return { success: false, error: errorMsg };
1645
+ }
1646
+
1647
+ const { db, core } = await bootstrapHeadlessAgent(options);
1648
+ const groupId =
1649
+ options.group || core.DEFAULT_SERVER_GROUP_ID || DEFAULT_SERVER_GROUP_ID;
1650
+
1651
+ const fetchDiscoveryManifest =
1652
+ core.fetchDiscoveryManifest ||
1653
+ (await import("../../subsystems/tools/remote/discovery.js"))
1654
+ .fetchDiscoveryManifest;
1655
+ const importRemoteArtifacts =
1656
+ core.importRemoteArtifacts ||
1657
+ (await import("../../subsystems/tools/remote/importArtifacts.js"))
1658
+ .importRemoteArtifacts;
1659
+
1660
+ const fetchFn = options.fetchFn || globalThis.fetch;
1661
+
1662
+ if (!options.quiet) {
1663
+ console.log(`Fetching discovery manifest from ${trimmedUrl}...`);
1664
+ }
1665
+
1666
+ let resolvedManifest: any;
1667
+ try {
1668
+ resolvedManifest = await fetchDiscoveryManifest(trimmedUrl, fetchFn);
1669
+ } catch (err: any) {
1670
+ const errorMsg = `Failed to fetch discovery manifest: ${err instanceof Error ? err.message : String(err)}`;
1671
+ if (!options.quiet) {
1672
+ console.error(`Error: ${errorMsg}`);
1673
+ }
1674
+ process.exitCode = 1;
1675
+ return { success: false, error: errorMsg };
1676
+ }
1677
+
1678
+ const { manifest, siteUrl, manifestUrl } = resolvedManifest;
1679
+
1680
+ const manifestTools = manifest.tools || [];
1681
+ const manifestSkills = manifest.skills || [];
1682
+ const manifestScripts = manifest.scripts || [];
1683
+
1684
+ if (!options.quiet) {
1685
+ console.log(
1686
+ `Discovered: ${manifest.name || "Remote Site"} (${manifestSkills.length} skill${manifestSkills.length === 1 ? "" : "s"}, ${manifestTools.length} tool${manifestTools.length === 1 ? "" : "s"}, ${manifestScripts.length} script${manifestScripts.length === 1 ? "" : "s"})`,
1687
+ );
1688
+ }
1689
+
1690
+ const allToolNames = manifestTools.map((t: any) => t.name);
1691
+ const allSkillNames = manifestSkills.map((s: any) => s.name);
1692
+ const allScriptNames = manifestScripts.map((s: any) => s.name);
1693
+
1694
+ let toolNames: string[];
1695
+ let skillNames: string[];
1696
+ let scriptNames: string[];
1697
+
1698
+ const hasExplicitFilter = Boolean(
1699
+ options.tools || options.skills || options.scripts,
1700
+ );
1701
+
1702
+ if (hasExplicitFilter && !options.all) {
1703
+ const parseList = (val: any) => {
1704
+ if (!val) return [];
1705
+ if (Array.isArray(val))
1706
+ return val.map((v) => String(v).trim()).filter(Boolean);
1707
+ return String(val)
1708
+ .split(",")
1709
+ .map((v) => v.trim())
1710
+ .filter(Boolean);
1711
+ };
1712
+ toolNames = parseList(options.tools);
1713
+ skillNames = parseList(options.skills);
1714
+ scriptNames = parseList(options.scripts);
1715
+ } else {
1716
+ toolNames = allToolNames;
1717
+ skillNames = allSkillNames;
1718
+ scriptNames = allScriptNames;
1719
+ }
1720
+
1721
+ const autoEnable = options.autoEnable !== false;
1722
+ const overwrite = Boolean(options.overwrite);
1723
+
1724
+ let importResult: any;
1725
+ try {
1726
+ importResult = await importRemoteArtifacts(
1727
+ db,
1728
+ groupId,
1729
+ manifest,
1730
+ { toolNames, skillNames, scriptNames },
1731
+ {
1732
+ autoEnable,
1733
+ overwrite,
1734
+ fetchFn,
1735
+ siteSlug: options.siteSlug,
1736
+ targetSubdir: options.targetSubdir,
1737
+ },
1738
+ );
1739
+ } catch (err: any) {
1740
+ const errorMsg = `Import failed: ${err instanceof Error ? err.message : String(err)}`;
1741
+ if (!options.quiet) {
1742
+ console.error(`Error: ${errorMsg}`);
1743
+ }
1744
+ process.exitCode = 1;
1745
+ return { success: false, error: errorMsg };
1746
+ }
1747
+
1748
+ const importedTools = importResult.tools.filter(
1749
+ (t: any) => t.status === "imported",
1750
+ );
1751
+ const importedSkills = importResult.skills.filter(
1752
+ (s: any) => s.status === "imported",
1753
+ );
1754
+ const importedScripts = importResult.scripts.filter(
1755
+ (sc: any) => sc.status === "imported",
1756
+ );
1757
+
1758
+ const skippedTools = importResult.tools.filter(
1759
+ (t: any) => t.status === "skipped",
1760
+ );
1761
+ const skippedSkills = importResult.skills.filter(
1762
+ (s: any) => s.status === "skipped",
1763
+ );
1764
+ const skippedScripts = importResult.scripts.filter(
1765
+ (sc: any) => sc.status === "skipped",
1766
+ );
1767
+
1768
+ const failedTools = importResult.tools.filter(
1769
+ (t: any) => t.status === "failed",
1770
+ );
1771
+ const failedSkills = importResult.skills.filter(
1772
+ (s: any) => s.status === "failed",
1773
+ );
1774
+ const failedScripts = importResult.scripts.filter(
1775
+ (sc: any) => sc.status === "failed",
1776
+ );
1777
+
1778
+ const importedCount =
1779
+ importedTools.length + importedSkills.length + importedScripts.length;
1780
+ const skippedCount =
1781
+ skippedTools.length + skippedSkills.length + skippedScripts.length;
1782
+ const failedCount =
1783
+ failedTools.length + failedSkills.length + failedScripts.length;
1784
+
1785
+ if (!options.quiet) {
1786
+ console.log("\nImporting artifacts:");
1787
+ for (const item of [
1788
+ ...importResult.tools,
1789
+ ...importResult.skills,
1790
+ ...importResult.scripts,
1791
+ ]) {
1792
+ const type = importResult.tools.includes(item)
1793
+ ? "tool"
1794
+ : importResult.skills.includes(item)
1795
+ ? "skill"
1796
+ : "script";
1797
+ if (item.status === "imported") {
1798
+ console.log(` [${type}] ${item.name} -> ${item.path} (imported)`);
1799
+ } else if (item.status === "skipped") {
1800
+ console.log(
1801
+ ` [${type}] ${item.name} -> ${item.path} (skipped, already exists - use --overwrite to replace)`,
1802
+ );
1803
+ } else {
1804
+ console.log(
1805
+ ` [${type}] ${item.name} (failed: ${item.error || "unknown error"})`,
1806
+ );
1807
+ }
1808
+ }
1809
+
1810
+ if (failedCount > 0) {
1811
+ console.log(
1812
+ `\nCompleted with ${failedCount} error${failedCount === 1 ? "" : "s"}. Successfully imported ${importedCount} items, ${skippedCount} skipped.`,
1813
+ );
1814
+ } else {
1815
+ console.log(
1816
+ `\nSuccessfully imported ${importedCount} item${importedCount === 1 ? "" : "s"} (${importedTools.length} tool${importedTools.length === 1 ? "" : "s"}, ${importedSkills.length} skill${importedSkills.length === 1 ? "" : "s"}, ${importedScripts.length} script${importedScripts.length === 1 ? "" : "s"}).`,
1817
+ );
1818
+ }
1819
+ }
1820
+
1821
+ const success = failedCount === 0 || importedCount > 0;
1822
+ if (!success) {
1823
+ process.exitCode = 1;
1824
+ }
1825
+
1826
+ return {
1827
+ success,
1828
+ manifest,
1829
+ siteUrl,
1830
+ manifestUrl,
1831
+ result: importResult,
1832
+ importedCount,
1833
+ skippedCount,
1834
+ failedCount,
1835
+ };
1836
+ }
1837
+
1604
1838
  /**
1605
1839
  * Main dispatcher for the `agent` command group.
1606
1840
  */
@@ -1714,9 +1948,25 @@ export async function runAgentCommand(
1714
1948
  return await runAgentModel(subaction, modelId, actualOptions);
1715
1949
  }
1716
1950
 
1951
+ case "import": {
1952
+ const url = actualArgs[0];
1953
+ if (!url) {
1954
+ console.error(
1955
+ "Error: Discovery URL or site URL required. Usage: shadow-claw agent import <url> [options]",
1956
+ );
1957
+ process.exitCode = 1;
1958
+ return {
1959
+ success: false,
1960
+ error:
1961
+ "Discovery URL or site URL required. Usage: shadow-claw agent import <url> [options]",
1962
+ };
1963
+ }
1964
+ return await runAgentImport(url, actualOptions);
1965
+ }
1966
+
1717
1967
  default: {
1718
1968
  console.log(
1719
- "Usage: shadow-claw agent <init|model|skills|tools|tool|skill|run> [args...]",
1969
+ "Usage: shadow-claw agent <init|model|skills|tools|tool|skill|import|run> [args...]",
1720
1970
  );
1721
1971
  }
1722
1972
  }
@@ -544,6 +544,13 @@
544
544
  >
545
545
  🌱 Block Garden Knowledge Hub
546
546
  </button>
547
+ <button
548
+ class="tools__preset-btn"
549
+ data-url="https://xt-ml.github.io/shadow-claw-agent-cli-weather"
550
+ type="button"
551
+ >
552
+ 🌦️ Weather Agent (Open-Meteo)
553
+ </button>
547
554
  </div>
548
555
  </div>
549
556
 
@@ -12,11 +12,14 @@ import {
12
12
  } from "./utils/handleInvoke.js";
13
13
  import { executeNodeTransformersCompletion } from "./tools/node-transformers-executor.js";
14
14
  import { executeNodeLlamafileCompletion } from "./tools/node-llamafile-executor.js";
15
+ import { setHeadlessEvalExecutor } from "./utils/sandboxedEval.js";
16
+ import { nativeEvalExecutor } from "./utils/native-eval-executor.js";
15
17
 
16
18
  // Automatically wire native OS process execution for headless CLI agent
17
19
  setHeadlessBashExecutor(nativeBashExecutor);
18
20
  setNodeTransformersCompletionExecutor(executeNodeTransformersCompletion);
19
21
  setNodeLlamafileCompletionExecutor(executeNodeLlamafileCompletion);
22
+ setHeadlessEvalExecutor(nativeEvalExecutor);
20
23
 
21
24
  export { executeTool } from "./utils/executeTool.js";
22
25
  export { executeToolChain } from "./utils/toolChain.js";
@@ -52,6 +55,16 @@ export {
52
55
  export { TOOL_DEFINITIONS } from "../subsystems/tools/index.js";
53
56
  export { DEFAULT_BUILTIN_PROFILE } from "../subsystems/tools/builtin-profiles.js";
54
57
  export { loadDeclarativeTools } from "../subsystems/tools/declarative.js";
58
+ export {
59
+ resolveDiscoveryUrl,
60
+ fetchDiscoveryManifest,
61
+ } from "../subsystems/tools/remote/discovery.js";
62
+ export {
63
+ importRemoteArtifacts,
64
+ importRemoteTool,
65
+ importRemoteSkill,
66
+ importRemoteScript,
67
+ } from "../subsystems/tools/remote/importArtifacts.js";
55
68
  export {
56
69
  getProvider,
57
70
  getDefaultProvider,
@@ -81,4 +94,5 @@ export { executeNodeTransformersCompletion } from "./tools/node-transformers-exe
81
94
  export { createTransformersRuntimeService } from "../server/services/transformers-runtime.js";
82
95
  export { cleanupAllLlamafileProcesses } from "../server/services/llamafile-manager.js";
83
96
  export { nativeBashExecutor, setHeadlessBashExecutor };
97
+ export { nativeEvalExecutor, setHeadlessEvalExecutor };
84
98
  export type * from "./headless-types.js";
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import type { ShadowClawDatabase } from "../db/types.js";
7
+ import type { ImportResult } from "../subsystems/tools/remote/types.js";
7
8
 
8
9
  /**
9
10
  * Dedicated agent configuration section in shadow-claw.config.json.
@@ -235,3 +236,41 @@ export interface AgentModelResult {
235
236
  error?: string;
236
237
  [key: string]: unknown;
237
238
  }
239
+
240
+ /**
241
+ * Options for runAgentImport.
242
+ */
243
+ export interface AgentImportOptions {
244
+ workspace?: string;
245
+ group?: string;
246
+ databaseDir?: string;
247
+ cacheDir?: string;
248
+ tools?: string | string[];
249
+ skills?: string | string[];
250
+ scripts?: string | string[];
251
+ all?: boolean;
252
+ overwrite?: boolean;
253
+ autoEnable?: boolean;
254
+ targetSubdir?: string;
255
+ siteSlug?: string;
256
+ quiet?: boolean;
257
+ verbose?: boolean;
258
+ fetchFn?: typeof fetch;
259
+ [key: string]: unknown;
260
+ }
261
+
262
+ /**
263
+ * Result returned by runAgentImport.
264
+ */
265
+ export interface AgentImportResult {
266
+ success: boolean;
267
+ manifest?: unknown;
268
+ siteUrl?: string;
269
+ manifestUrl?: string;
270
+ result?: ImportResult;
271
+ importedCount?: number;
272
+ skippedCount?: number;
273
+ failedCount?: number;
274
+ error?: string;
275
+ [key: string]: unknown;
276
+ }
@@ -0,0 +1,36 @@
1
+ import { nativeEvalExecutor } from "./native-eval-executor.js";
2
+ import { sandboxedEval, setHeadlessEvalExecutor } from "./sandboxedEval.js";
3
+
4
+ describe("nativeEvalExecutor", () => {
5
+ it("evaluates javascript expressions in node:vm", async () => {
6
+ const res = await nativeEvalExecutor("return 2 + 2;", 5000, false);
7
+ expect(res).toEqual({ ok: true, value: 4 });
8
+ });
9
+
10
+ it("handles injected $PIPE_DATA and data parameter", async () => {
11
+ const res = await nativeEvalExecutor(
12
+ "const d = JSON.parse(data); return d.val * 3;",
13
+ 5000,
14
+ false,
15
+ JSON.stringify({ val: 10 }),
16
+ );
17
+ expect(res).toEqual({ ok: true, value: 30 });
18
+ });
19
+
20
+ it("integrates with sandboxedEval when Worker is undefined", async () => {
21
+ setHeadlessEvalExecutor(nativeEvalExecutor);
22
+ const origWorker = (globalThis as any).Worker;
23
+ try {
24
+ delete (globalThis as any).Worker;
25
+ const res = await sandboxedEval("return 100 * 2;");
26
+ expect(res).toEqual({ ok: true, value: 200 });
27
+ } finally {
28
+ (globalThis as any).Worker = origWorker;
29
+ }
30
+ });
31
+
32
+ it("handles evaluation timeout gracefully", async () => {
33
+ const res = await nativeEvalExecutor("while(true) {}", 50, false);
34
+ expect(res.ok).toBe(false);
35
+ });
36
+ });
@@ -0,0 +1,58 @@
1
+ import { runInNewContext } from "node:vm";
2
+ import type { HeadlessEvalExecutor } from "./sandboxedEval.js";
3
+ import { setHeadlessEvalExecutor } from "./sandboxedEval.js";
4
+
5
+ /**
6
+ * Native Node.js node:vm executor for headless CLI / server mode.
7
+ */
8
+ export const nativeEvalExecutor: HeadlessEvalExecutor = async (
9
+ code,
10
+ timeoutMs,
11
+ allowFullInternetAccess = false,
12
+ data,
13
+ ) => {
14
+ try {
15
+ const sandbox: any = {
16
+ console,
17
+ URL,
18
+ TextEncoder,
19
+ TextDecoder,
20
+ JSON,
21
+ Math,
22
+ Date,
23
+ parseInt,
24
+ parseFloat,
25
+ encodeURIComponent,
26
+ decodeURIComponent,
27
+ setTimeout,
28
+ clearTimeout,
29
+ data: data ?? "",
30
+ $PIPE_DATA: data ?? "",
31
+ fetch: allowFullInternetAccess ? globalThis.fetch : undefined,
32
+ };
33
+ const wrappedCode = `(async () => {
34
+ "use strict";
35
+ ${code}
36
+ })()`;
37
+ const result = await Promise.race([
38
+ runInNewContext(wrappedCode, sandbox, { timeout: timeoutMs }),
39
+ new Promise((_, reject) =>
40
+ setTimeout(
41
+ () =>
42
+ reject(new Error(`Execution timed out after ${timeoutMs / 1000}s`)),
43
+ timeoutMs,
44
+ ),
45
+ ),
46
+ ]);
47
+ return { ok: true, value: result };
48
+ } catch (err: any) {
49
+ return {
50
+ ok: false,
51
+ error: err && err.message ? err.message : String(err),
52
+ };
53
+ }
54
+ };
55
+
56
+ // Register with sandboxedEval when loaded
57
+ setHeadlessEvalExecutor(nativeEvalExecutor);
58
+ (globalThis as any).__headlessEvalExecutor = nativeEvalExecutor;
@@ -87,6 +87,21 @@ function getBlockedGlobals(allowFullInternetAccess: boolean): string[] {
87
87
  return [...BASE_BLOCKED_GLOBALS, "fetch"];
88
88
  }
89
89
 
90
+ export type HeadlessEvalExecutor = (
91
+ code: string,
92
+ timeoutMs: number,
93
+ allowFullInternetAccess: boolean,
94
+ data?: string,
95
+ ) => Promise<{ ok: true; value: unknown } | { ok: false; error: string }>;
96
+
97
+ let _headlessEvalExecutor: HeadlessEvalExecutor | null = null;
98
+
99
+ export function setHeadlessEvalExecutor(
100
+ executor: HeadlessEvalExecutor | null,
101
+ ): void {
102
+ _headlessEvalExecutor = executor;
103
+ }
104
+
90
105
  /**
91
106
  * Execute user-supplied JavaScript in a sandboxed, timeout-enforced context.
92
107
  */
@@ -96,6 +111,26 @@ export async function sandboxedEval(
96
111
  allowFullInternetAccess: boolean = false,
97
112
  data?: string,
98
113
  ): Promise<{ ok: true; value: unknown } | { ok: false; error: string }> {
114
+ if (typeof Worker === "undefined") {
115
+ if (_headlessEvalExecutor) {
116
+ return _headlessEvalExecutor(
117
+ code,
118
+ timeoutMs,
119
+ allowFullInternetAccess,
120
+ data,
121
+ );
122
+ }
123
+ const globalExecutor = (globalThis as any).__headlessEvalExecutor;
124
+ if (typeof globalExecutor === "function") {
125
+ return globalExecutor(code, timeoutMs, allowFullInternetAccess, data);
126
+ }
127
+
128
+ return {
129
+ ok: false,
130
+ error: "Web Workers are not supported in this environment.",
131
+ };
132
+ }
133
+
99
134
  // Build the worker source inline via a Blob URL
100
135
  const workerSource = buildWorkerSource(code, allowFullInternetAccess, data);
101
136
  const blob = new Blob([workerSource], { type: "application/javascript" });
@@ -266,6 +301,7 @@ const restoreGlobals = applyGlobalShadows();
266
301
  const Function = undefined;
267
302
  ${allowFullInternetAccess ? "" : "const fetch = undefined;"}
268
303
  const $PIPE_DATA = ${JSON.stringify(data ?? "")};
304
+ const data = $PIPE_DATA;
269
305
 
270
306
  ${code}
271
307
  })();
@@ -1 +0,0 @@
1
- import{r as e}from"./chunk-hOceZVB92.js";export{e as orchestratorStore};
@@ -1 +0,0 @@
1
- import{n as e}from"./chunk-zvi71-77.js";export{e as executeNativeAiTask};