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
package/dist/cli/cli.js CHANGED
@@ -1,21 +1,21 @@
1
- import{a as e}from"./chunk-8V8biNmG.js";import{t}from"./chunk-uAI_Zi6n.js";import{t as n}from"./chunk-DoHbMaWn.js";import{t as r}from"./chunk-DxIsgrAF.js";import{r as i}from"./chunk-JBAAPRpe.js";import{a}from"./chunk-CS2NqF-O.js";import{t as o}from"./chunk-BRiGkTIi.js";import s,{constants as c}from"node:fs";import l from"node:path";import{fileURLToPath as u}from"node:url";import d from"node:process";import{exec as f}from"node:child_process";import{access as p,mkdir as m,readFile as h,stat as g,writeFile as _}from"node:fs/promises";import{Command as v}from"commander";import y from"process";import{Buffer as b}from"buffer";import x from"node:http";import S from"node:https";import{tmpdir as C}from"node:os";import w from"node:readline";function T(){let e=d.emitWarning;if(!e||e.__suppressed)return;let t=function(t,...n){if(!(typeof t==`string`&&(n[0]===`ExperimentalWarning`||t.includes(`ExperimentalWarning`)||t.includes(`SQLite`)))&&!(t&&typeof t==`object`&&(t.name===`ExperimentalWarning`||typeof t.message==`string`&&t.message.includes(`SQLite`))))return e.call(d,t,...n)};t.__suppressed=!0,d.emitWarning=t}T();function E(e){let t=e||(y.env.SHADOWCLAW_CACHE_DIR||``).trim()||l.join(y.cwd(),`.cache`);return l.join(t,`webrtc-ipc.sock`)}function D(e){try{s.unlinkSync(E(e))}catch{}}async function O(e){let t=E(e);try{return s.existsSync(t)?(await new Promise((e,n)=>{let r=x.request({socketPath:t,path:`/ping`,method:`GET`},t=>{t.resume(),t.statusCode===200?e():n(Error(`status ${t.statusCode}`))});r.setTimeout(1e3,()=>{r.destroy(),n(Error(`timeout`))}),r.on(`error`,n),r.end()}),{socketPath:t}):null}catch{return null}}function k(e,t,n,r,i){let a=e.socketPath||e.port;return new Promise((e,o)=>{let s=JSON.stringify({targetPeerId:t,action:n,args:r,timeoutMs:i}),c=x.request({socketPath:a,path:`/command`,method:`POST`,headers:{"Content-Type":`application/json`,"Content-Length":b.byteLength(s)}},t=>{let n=``;t.on(`data`,e=>n+=e),t.on(`end`,()=>{try{let r=JSON.parse(n);t.statusCode&&t.statusCode>=200&&t.statusCode<300?e(r):o(Error(r?.error||`IPC error ${t.statusCode}`))}catch{o(Error(`Bad IPC response: ${n}`))}})});c.setTimeout(i+2e3,()=>{c.destroy(),o(Error(`IPC request timed out`))}),c.on(`error`,e=>o(Error(`IPC connection failed: ${e.message}`))),c.write(s),c.end()})}function A(e){let t=e||(y.env.SHADOWCLAW_CACHE_DIR||``).trim()||l.join(y.cwd(),`.cache`);return l.join(t,`cli-peer-id`)}function j(e){if(y.env.SHADOWCLAW_CLI_PEER_ID)return y.env.SHADOWCLAW_CLI_PEER_ID.trim();let t=A(e);try{if(s.existsSync(t)){let e=s.readFileSync(t,`utf8`).trim();if(e)return e}}catch{}return``}function M(e,t){let n=A(t),i=l.dirname(n),a=e&&typeof e==`string`&&e.trim()?e.trim():`cli-${r().toLowerCase()}`;try{s.existsSync(i)||s.mkdirSync(i,{recursive:!0}),s.writeFileSync(n,a+`
1
+ import{a as e}from"./chunk-8V8biNmG.js";import{t}from"./chunk-uAI_Zi6n.js";import{t as n}from"./chunk-DoHbMaWn.js";import{t as r}from"./chunk-DxIsgrAF.js";import{r as i}from"./chunk-JBAAPRpe.js";import{a}from"./chunk-CS2NqF-O.js";import{t as o}from"./chunk-CAqvQuGr.js";import s,{constants as c}from"node:fs";import l from"node:path";import{fileURLToPath as u}from"node:url";import d from"node:process";import{exec as f}from"node:child_process";import{access as p,mkdir as m,readFile as h,stat as g,writeFile as _}from"node:fs/promises";import{Command as v}from"commander";import y from"process";import{Buffer as b}from"buffer";import x from"node:http";import S from"node:https";import{tmpdir as C}from"node:os";import w from"node:readline";function T(){let e=d.emitWarning;if(!e||e.__suppressed)return;let t=function(t,...n){if(!(typeof t==`string`&&(n[0]===`ExperimentalWarning`||t.includes(`ExperimentalWarning`)||t.includes(`SQLite`)))&&!(t&&typeof t==`object`&&(t.name===`ExperimentalWarning`||typeof t.message==`string`&&t.message.includes(`SQLite`))))return e.call(d,t,...n)};t.__suppressed=!0,d.emitWarning=t}T();function E(e){let t=e||(y.env.SHADOWCLAW_CACHE_DIR||``).trim()||l.join(y.cwd(),`.cache`);return l.join(t,`webrtc-ipc.sock`)}function D(e){try{s.unlinkSync(E(e))}catch{}}async function O(e){let t=E(e);try{return s.existsSync(t)?(await new Promise((e,n)=>{let r=x.request({socketPath:t,path:`/ping`,method:`GET`},t=>{t.resume(),t.statusCode===200?e():n(Error(`status ${t.statusCode}`))});r.setTimeout(1e3,()=>{r.destroy(),n(Error(`timeout`))}),r.on(`error`,n),r.end()}),{socketPath:t}):null}catch{return null}}function k(e,t,n,r,i){let a=e.socketPath||e.port;return new Promise((e,o)=>{let s=JSON.stringify({targetPeerId:t,action:n,args:r,timeoutMs:i}),c=x.request({socketPath:a,path:`/command`,method:`POST`,headers:{"Content-Type":`application/json`,"Content-Length":b.byteLength(s)}},t=>{let n=``;t.on(`data`,e=>n+=e),t.on(`end`,()=>{try{let r=JSON.parse(n);t.statusCode&&t.statusCode>=200&&t.statusCode<300?e(r):o(Error(r?.error||`IPC error ${t.statusCode}`))}catch{o(Error(`Bad IPC response: ${n}`))}})});c.setTimeout(i+2e3,()=>{c.destroy(),o(Error(`IPC request timed out`))}),c.on(`error`,e=>o(Error(`IPC connection failed: ${e.message}`))),c.write(s),c.end()})}function A(e){let t=e||(y.env.SHADOWCLAW_CACHE_DIR||``).trim()||l.join(y.cwd(),`.cache`);return l.join(t,`cli-peer-id`)}function j(e){if(y.env.SHADOWCLAW_CLI_PEER_ID)return y.env.SHADOWCLAW_CLI_PEER_ID.trim();let t=A(e);try{if(s.existsSync(t)){let e=s.readFileSync(t,`utf8`).trim();if(e)return e}}catch{}return``}function M(e,t){let n=A(t),i=l.dirname(n),a=e&&typeof e==`string`&&e.trim()?e.trim():`cli-${r().toLowerCase()}`;try{s.existsSync(i)||s.mkdirSync(i,{recursive:!0}),s.writeFileSync(n,a+`
2
2
  `,`utf8`)}catch{}return a}function N(e,t){return e&&typeof e==`string`&&e.trim()?e.trim():y.env.SHADOWCLAW_CLI_PEER_ID?y.env.SHADOWCLAW_CLI_PEER_ID.trim():j(t)||M(void 0,t)}async function P(){if(typeof globalThis<`u`&&globalThis.RTCPeerConnection!==void 0)return!0;try{let e=await import(`./chunk-DUYVjLFv.js`);if(e&&e.RTCPeerConnection)return Object.assign(globalThis,{RTCPeerConnection:e.RTCPeerConnection,RTCSessionDescription:e.RTCSessionDescription,RTCIceCandidate:e.RTCIceCandidate}),!0}catch(e){console.warn(`[webrtc-cli] Failed to load node-datachannel polyfill:`,e?.message||String(e))}return!1}var F=class{host;port;path;secure;rejectUnauthorized;peer;cacheDir;cliPeerId;constructor(e={}){this.host=e.host||y.env.SHADOWCLAW_HOST||`127.0.0.1`,this.port=e.port||parseInt(y.env.SHADOWCLAW_PORT||`8888`,10),this.path=e.path||`/`,this.secure=e.secure??!1,this.rejectUnauthorized=e.rejectUnauthorized??!1,this.peer=null,this.cacheDir=e.cacheDir,this.cliPeerId=e.peerId&&e.peerId.trim()?e.peerId.trim():N(void 0,e.cacheDir)}async _getPeer(){if(this.peer&&!this.peer.destroyed)return this.peer;await P();let t=await import(`./chunk-C43fWl2a.js`).then(t=>e(t.default,1)),n=t.default?.Peer||t.default||t.Peer;return new Promise((e,t)=>{let r={host:this.host,port:this.port,path:this.path,secure:this.secure};this.secure&&(r.config={iceServers:[]},r.wsOptions={rejectUnauthorized:this.rejectUnauthorized});let i=new n(this.cliPeerId,r);this.peer=i,i.on(`open`,()=>{e(i)}),i.on(`error`,e=>{t(Error(`PeerJS error: ${e.type||e.message||e}`))})})}async sendCommand(e,t,n={},i=3e4){let a=await O(this.cacheDir);if(a)return k(a,e,t,n,i);let o=await this._getPeer();return new Promise((a,s)=>{let c=null,l=null,u=()=>{if(c&&clearTimeout(c),l)try{l.close()}catch{}if(this.peer){try{this.peer.destroy()}catch{}this.peer=null}};c=setTimeout(()=>{u(),s(Error(`WebRTC command '${t}' to peer '${e}' timed out after ${i}ms`))},i);try{l=o.connect(e,{reliable:!0,serialization:`binary`}),l.on(`open`,()=>{let e=r(),i={id:r(),type:`command:execute`,payload:{commandId:e,action:t,args:n}};l.send(i)}),l.on(`data`,e=>{let t=e;if(typeof e==`string`)try{t=JSON.parse(e)}catch{}if(t&&t.method===`GetAgentCard`&&t.id){try{l.send({jsonrpc:`2.0`,id:t.id,result:{name:`ShadowClaw CLI`,description:`ShadowClaw Command Line Interface`,version:`1.0.0`}})}catch{}return}t&&t.type===`command:result`&&(u(),t.payload?.error?s(Error(t.payload.error)):a(t.payload))}),l.on(`error`,t=>{u(),s(Error(`WebRTC connection error to peer '${e}': ${t.message||String(t)}`))})}catch(e){u(),s(e)}})}async listClients(){let e=await O(this.cacheDir);if(!e)return[];let t=e.socketPath;return new Promise(e=>{let n=x.request({socketPath:t,path:`/clients`,method:`GET`},t=>{let n=``;t.on(`data`,e=>n+=e),t.on(`end`,()=>{try{e(JSON.parse(n).clients||[])}catch{e([])}})});n.setTimeout(2e3,()=>{n.destroy(),e([])}),n.on(`error`,()=>e([])),n.end()})}close(){if(this.peer){try{this.peer.destroy()}catch{}this.peer=null}}},I=class t{static _RECONNECT_BASE_MS=1e3;static _RECONNECT_MAX_MS=3e4;host;port;path;secure;rejectUnauthorized;cacheDir;verbose;handlers;trustedPeerIds;cliPeerId;_peer;_connections;_peerCards;_running;_reconnectAttempts;_reconnectTimer;constructor(e={}){this.host=e.host||y.env.SHADOWCLAW_HOST||`127.0.0.1`,this.port=e.port||parseInt(y.env.SHADOWCLAW_PORT||`8888`,10),this.path=e.path||`/`,this.secure=e.secure??!1,this.rejectUnauthorized=e.rejectUnauthorized??!1,this.cacheDir=e.cacheDir,this.verbose=e.verbose??!1,this.handlers=e.handlers||{},this.trustedPeerIds=new Set((e.trustedPeerIds||[]).map(e=>e.trim()).filter(Boolean)),this.cliPeerId=e.renewPeerId?M(e.peerId,e.cacheDir):N(e.peerId,e.cacheDir),this._peer=null,this._connections=new Map,this._peerCards=new Map,this._running=!1,this._reconnectAttempts=0,this._reconnectTimer=null}_log(e){this.verbose&&console.log(`[webrtc-listen] ${e}`)}_isTrusted(e){if(this.trustedPeerIds.size===0||this.trustedPeerIds.has(e))return!0;for(let t of this.trustedPeerIds)if(t.endsWith(`*`)&&e.startsWith(t.slice(0,-1)))return!0;return!1}_scheduleReconnect(){if(!this._running||this._reconnectTimer!==null)return;let e=Math.min(t._RECONNECT_BASE_MS*2**this._reconnectAttempts,t._RECONNECT_MAX_MS);this._reconnectAttempts++,console.log(`[webrtc-listen] Disconnected from signaling server — reconnecting in ${(e/1e3).toFixed(1)}s (attempt ${this._reconnectAttempts})…`),this._reconnectTimer=setTimeout(()=>{if(this._reconnectTimer=null,!(!this._running||!this._peer||this._peer.destroyed))try{this._peer.reconnect()}catch{this._scheduleReconnect()}},e)}async _handleCommand(e,t,n){let{commandId:i,action:a,args:o}=n.payload||{},s=this.handlers[a];if(!s){e.send({id:r(),type:`command:result`,payload:{commandId:i,success:!1,error:`Unknown action: ${a}`}});return}try{let t=await s(o||{});e.send({id:r(),type:`command:result`,payload:{commandId:i,success:!0,data:t}})}catch(t){e.send({id:r(),type:`command:result`,payload:{commandId:i,success:!1,error:t?.message||String(t)}})}}_setupConnection(e,t){e.on(`open`,()=>{this._connections.set(t,e),console.log(`[webrtc-listen] Connection opened from peer: ${t}`);try{e.send({jsonrpc:`2.0`,id:r(),method:`GetAgentCard`,params:{}})}catch{}}),e.on(`data`,async n=>{let r=n;if(typeof n==`string`)try{r=JSON.parse(n)}catch{return}if(!(!r||typeof r!=`object`)){if(r.result&&typeof r.result==`object`&&r.result.name){this._peerCards.set(t,r.result);return}if(r.method===`GetAgentCard`&&r.id){try{e.send({jsonrpc:`2.0`,id:r.id,result:{name:`ShadowClaw CLI`,description:`ShadowClaw Command Line Interface`,version:`1.0.0`,capabilities:[`cli`,`webrtc`,`control`]}})}catch{}return}r.type===`command:execute`&&await this._handleCommand(e,t,r)}}),e.on(`close`,()=>{this._connections.delete(t),this._peerCards.delete(t),console.log(`[webrtc-listen] Connection closed from peer: ${t}`)}),e.on(`error`,e=>{this._connections.delete(t),this._peerCards.delete(t),console.error(`[webrtc-listen] Connection error from ${t}: ${e?.message||e}`)})}async start(){await P();let t=await import(`./chunk-C43fWl2a.js`).then(t=>e(t.default,1)),n=t.default?.Peer||t.default||t.Peer;return new Promise((e,t)=>{let r=!1,i={host:this.host,port:this.port,path:this.path,secure:this.secure};this.secure&&(i.config={iceServers:[]},i.wsOptions={rejectUnauthorized:this.rejectUnauthorized});let a=new n(this.cliPeerId,i);this._peer=a,this._running=!0,a.on(`open`,t=>{r=!0,this._reconnectAttempts=0,this._reconnectTimer!==null&&(clearTimeout(this._reconnectTimer),this._reconnectTimer=null),console.log(`[webrtc-listen] Registered on signaling server as peer: ${t}`),console.log(`[webrtc-listen] Waiting for connections from browser peers…`),e(t)}),a.on(`connection`,e=>{let t=e.peer;if(!this._isTrusted(t)){console.warn(`[webrtc-listen] Rejecting untrusted peer: ${t}`);try{e.close()}catch{}return}this._setupConnection(e,t)}),a.on(`error`,e=>{if(!this._running)return;let n=e?.type||e?.message||String(e);console.error(`[webrtc-listen] PeerJS error: ${n}`),r?a.open||this._scheduleReconnect():t(Error(`PeerJS error: ${n}`))}),a.on(`disconnected`,()=>{this._running&&this._scheduleReconnect()}),a.on(`close`,()=>{this._running=!1,this._reconnectTimer!==null&&(clearTimeout(this._reconnectTimer),this._reconnectTimer=null),console.log(`[webrtc-listen] Peer closed.`)})})}close(){this._running=!1,this._reconnectTimer!==null&&(clearTimeout(this._reconnectTimer),this._reconnectTimer=null),this._reconnectAttempts=0;for(let e of this._connections.values())try{e.close()}catch{}if(this._connections.clear(),this._peerCards.clear(),this._peer){try{this._peer.destroy()}catch{}this._peer=null}}};function L(e,t,n){if(e&&typeof e==`string`&&e.trim())return[e.trim()];if(y.env.SHADOWCLAW_CONTROL_TOKEN)return[y.env.SHADOWCLAW_CONTROL_TOKEN.trim()];let r=t||(y.env.SHADOWCLAW_CACHE_DIR||``).trim(),i=l.join(C(),`shadow-claw`),a=typeof y.env.HOME==`string`?y.env.HOME:``,o=[],c=e=>{try{if(e&&s.existsSync(e)){let t=s.statSync(e),n=s.readFileSync(e,`utf8`),r=JSON.parse(n);if(r&&typeof r.token==`string`&&r.token.trim()){let n=Number(r.createdAt)||t.mtimeMs||0;o.push({token:r.token.trim(),timestamp:n,filePath:e})}}}catch{}},u=e=>{try{let t;if(typeof y.getBuiltinModule==`function`&&(t=y.getBuiltinModule(`node:sqlite`)),t&&t.DatabaseSync&&s.existsSync(e)){let n=s.statSync(e),r=new t.DatabaseSync(e),i=r.prepare(`SELECT value FROM metadata WHERE key = 'control_token'`).get();r.close(),i&&i.value&&o.push({token:`${i.value}`.trim(),timestamp:n.mtimeMs||0,filePath:e})}}catch{}};if(r)c(l.join(r,`control-token.json`)),u(l.join(r,`database`,`clients.db`)),u(l.join(r,`clients.db`));else{n&&c(l.join(i,`control-token-${n}.json`)),c(l.join(i,`control-token.json`)),u(l.join(i,`database`,`clients.db`)),c(l.join(y.cwd(),`.cache`,`control-token.json`)),c(l.join(y.cwd(),`control-token.json`)),u(l.join(y.cwd(),`.cache`,`database`,`clients.db`)),u(l.join(y.cwd(),`database`,`clients.db`));try{let e=s.readdirSync(y.cwd(),{withFileTypes:!0});for(let t of e)if(t.isDirectory()&&!t.name.startsWith(`node_modules`)&&!t.name.startsWith(`.`)){let e=l.join(y.cwd(),t.name);c(l.join(e,`.cache`,`control-token.json`)),c(l.join(e,`control-token.json`)),u(l.join(e,`.cache`,`database`,`clients.db`))}}catch{}try{let e=y.cwd();for(let t=0;t<4;t++){let t=l.dirname(e);if(!t||t===e)break;c(l.join(t,`.cache`,`control-token.json`)),c(l.join(t,`control-token.json`)),u(l.join(t,`.cache`,`database`,`clients.db`));try{let e=s.readdirSync(t,{withFileTypes:!0});for(let n of e)if(n.isDirectory()&&!n.name.startsWith(`node_modules`)&&!n.name.startsWith(`.`)){let e=l.join(t,n.name);c(l.join(e,`.cache`,`control-token.json`)),c(l.join(e,`control-token.json`)),u(l.join(e,`.cache`,`database`,`clients.db`))}}catch{}e=t}}catch{}a&&(c(l.join(a,`.config`,`shadow-claw`,`control-token.json`)),c(l.join(a,`.cache`,`shadow-claw`,`control-token.json`)))}o.sort((e,t)=>t.timestamp-e.timestamp);let d=new Set,f=[];for(let e of o)e.token&&!d.has(e.token)&&(d.add(e.token),f.push(e.token));return f}var R=class{host;port;candidateTokens;token;protocol;rejectUnauthorized;transport;cacheDir;_webrtcClient;constructor(e={}){this.host=e.host||y.env.SHADOWCLAW_HOST||`127.0.0.1`,this.port=e.port||parseInt(y.env.SHADOWCLAW_PORT||`8888`,10),this.candidateTokens=L(e.token,e.cacheDir,this.port),this.token=e.token||this.candidateTokens[0]||``,this.cacheDir=e.cacheDir;let t=!!(e.https||[`1`,`true`,`yes`].includes((y.env.SHADOWCLAW_HTTPS||``).toLowerCase().trim()));this.protocol=e.protocol||(t?`https`:`http`),this.rejectUnauthorized=e.rejectUnauthorized===void 0?e.insecure===!1:!!e.rejectUnauthorized,this.transport=e.transport||`http`,this._webrtcClient=this.transport===`webrtc`?new F({host:this.host,port:this.port,path:e.peerPath||`/`,secure:this.protocol===`https`,rejectUnauthorized:this.rejectUnauthorized,peerId:e.peerId,cacheDir:e.cacheDir,renewPeerId:!!e.renewPeerId}):null}async _request({method:e=`GET`,path:t,body:n=null,timeout:r=3e4}){let i=i=>new Promise((a,o)=>{let s=this.protocol===`https`?S:x,c={"Content-Type":`application/json`};i&&(c[`x-control-token`]=i);let l={hostname:this.host,port:this.port,path:t,method:e,headers:c,timeout:r};this.protocol===`https`&&(l.rejectUnauthorized=this.rejectUnauthorized);let u=s.request(l,e=>{let t=``;e.on(`data`,e=>t+=e),e.on(`end`,()=>{let n=t;try{n=JSON.parse(t)}catch{}if(e.statusCode&&e.statusCode>=200&&e.statusCode<300)a({ok:!0,statusCode:e.statusCode,data:n});else{let r=n?.error||`HTTP request failed with status ${e.statusCode}: ${t}`;a({ok:!1,statusCode:e.statusCode,error:r,data:n})}})});u.on(`error`,e=>{o(Error(`Failed to connect to ShadowClaw server at ${this.host}:${this.port}: ${e.message}`))}),u.on(`timeout`,()=>{u.destroy(),o(Error(`Request timed out after ${r}ms`))}),n&&u.write(typeof n==`string`?n:JSON.stringify(n)),u.end()}),a=await i(this.token);if(a.ok)return a.data;if(a.statusCode===401&&Array.isArray(this.candidateTokens)&&this.candidateTokens.length>1)for(let e of this.candidateTokens){if(e===this.token)continue;let t=await i(e);if(t.ok)return this.token=e,t.data}throw Error(a.error||`HTTP request failed with status ${a.statusCode}`)}async listClients(){if(this._webrtcClient){try{let e=await this._webrtcClient.listClients();if(e&&e.length>0)return e}catch{}try{return(await this._request({path:`/api/control/clients`,method:`GET`})).clients||[]}catch{return[]}}return(await this._request({path:`/api/control/clients`,method:`GET`})).clients||[]}async sendCommand(e,t,n={},r=3e4){if(this._webrtcClient){let i=e;if(e&&e.startsWith(`client-`))try{let t=(await this.listClients()).find(t=>t.clientId===e);t&&t.peerId?i=t.peerId:t&&!t.peerId&&console.warn(`Warning: client "${e}" has no PeerJS peer ID registered.\nEnsure the browser has PeerJS enabled in Settings → WebRTC/PeerJS and has connected to the signaling server at least once.\nAlternatively, pass the browser's PeerJS peer ID directly with --client <peerId>.`)}catch{}return this._webrtcClient.sendCommand(i,t,n,r)}return await this._request({path:`/api/control/command`,method:`POST`,body:{clientId:e,action:t,args:n,timeoutMs:r},timeout:r+5e3})}async listBackups(e){let t=e?`?clientId=${encodeURIComponent(e)}`:``;return(await this._request({path:`/api/backup/list${t}`,method:`GET`})).backups||[]}async deleteBackup(e,t){let n=t?`?clientId=${encodeURIComponent(t)}`:``;return await this._request({path:`/api/backup/${encodeURIComponent(e)}${n}`,method:`DELETE`})}async broadcastNotification({title:e=`ShadowClaw`,body:t,clientId:n}={}){return await this._request({path:`/push/broadcast`,method:`POST`,body:{title:e,body:t,...n?{clientId:n}:{}}})}async sendNotification(e){return this.broadcastNotification(e)}async listPushSubscriptions(){try{let e=await this._request({path:`/push/subscriptions`,method:`GET`});return Array.isArray(e)?e:[]}catch{return[]}}async listPushClients(){try{let e=await this._request({path:`/push/clients`,method:`GET`});if(e&&Array.isArray(e.clients))return e.clients}catch{}try{let e=await this.listPushSubscriptions();if(Array.isArray(e)&&e.length>0){let t=new Map;for(let n of e){let e=(n.client_id||``).trim()||(n.id?String(n.id):``);if(!e)continue;let r=t.get(e);r?!r.deviceLabel&&n.device_label&&(r.deviceLabel=n.device_label):t.set(e,{clientId:e,deviceLabel:n.device_label||void 0})}return Array.from(t.values())}}catch{}try{let e;if(typeof y.getBuiltinModule==`function`&&(e=y.getBuiltinModule(`node:sqlite`)),e&&e.DatabaseSync){let t=[l.join(y.cwd(),`.cache`,`database`,`push-subscriptions.db`),l.join(y.cwd(),`database`,`push-subscriptions.db`),l.join(C(),`shadow-claw`,`database`,`push-subscriptions.db`),l.join(C(),`shadow-claw`,`push-subscriptions.db`)];this.cacheDir&&t.unshift(l.join(this.cacheDir,`database`,`push-subscriptions.db`),l.join(this.cacheDir,`push-subscriptions.db`));for(let n of t)if(s.existsSync(n)){let t=new e.DatabaseSync(n),r=t.prepare(`SELECT client_id, device_label, id FROM subscriptions ORDER BY created_at DESC, id DESC`).all();if(t.close(),r&&r.length>0){let e=new Map;for(let t of r){let n=(t.client_id?`${t.client_id}`.trim():``)||(t.id?String(t.id):``);n&&(e.has(n)||e.set(n,{clientId:n,deviceLabel:t.device_label?`${t.device_label}`.trim():void 0}))}return Array.from(e.values())}}}}catch{}return[]}};async function ee(e={}){let t=new R(e);try{let e=await t.listClients();if(!e||e.length===0){console.log(`No clients currently registered or connected.`);return}console.log(`Connected / registered clients (${e.length}):\n`),e.forEach((e,t)=>{let n=Math.max(0,Math.floor((Date.now()-e.lastSeen)/1e3)),r=n<60?`${n}s ago`:`${Math.floor(n/60)}m ago`;console.log(` ${t+1}. ${e.deviceLabel} (id: ${e.clientId})`),e.peerId&&console.log(` Peer ID: ${e.peerId}`),console.log(` Capabilities: ${e.capabilities.join(`, `)||`none`}`),console.log(` Version: ${e.version}`),console.log(` Last seen: ${r}\n`)})}catch(e){console.error(`Error fetching clients: ${e.message}`),y.exitCode=1}}async function te(e,t={}){if(!e||typeof e!=`string`||!e.trim()){console.error(`Error: Message cannot be empty.`),y.exitCode=1;return}let n=new R(t);try{let r=t.client;if(!r){let e=await n.listClients();if(!e||e.length===0){console.error(`Error: No clients are connected.`),y.exitCode=1;return}r=e[0].clientId,console.log(`Targeting client: ${e[0].deviceLabel} (${r})`)}let i=r||``;console.log(`Sending message to ${i}...`);let a=await n.sendCommand(i,`send-message`,{text:e.trim(),groupId:t.group});a.success?(console.log(`Message successfully dispatched.`),a.data&&console.log(JSON.stringify(a.data,null,2))):(console.error(`Error from client: ${a.error}`),y.exitCode=1)}catch(e){console.error(`Error sending message: ${e.message}`),y.exitCode=1}}async function ne(e=`trigger`,t={}){let n=new R(t);try{if(e===`list`){let e=await n.listBackups(t.client);if(!e||e.length===0){console.log(`No backups found.`);return}console.log(`Available backups (${e.length}):\n`),e.forEach((e,t)=>{let n=new Date(e.timestamp).toISOString(),r=(e.totalBytes/(1024*1024)).toFixed(2);console.log(` ${t+1}. [${e.id}] Client: ${e.clientId}`),console.log(` Date: ${n}`),console.log(` Files: ${e.fileCount} (${r} MB)\n`)});return}if(e===`delete`){if(!t.backupId){console.error(`Error: --backup-id is required for delete action.`),y.exitCode=1;return}await n.deleteBackup(t.backupId,t.client),console.log(`Backup ${t.backupId} deleted.`);return}let r=t.client;if(!r){let e=await n.listClients();if(!e||e.length===0){console.error(`Error: No clients are connected to back up.`),y.exitCode=1;return}r=e[0].clientId}let i=r||``;console.log(`Requesting backup from client ${i}...`);let a=await n.sendCommand(i,`trigger-backup`,{groupId:t.group,token:n.token});a.success?(console.log(`Backup completed successfully.`),console.log(JSON.stringify(a.data,null,2))):(console.error(`Backup failed: ${a.error}`),y.exitCode=1)}catch(e){console.error(`Error executing backup command: ${e.message}`),y.exitCode=1}}async function re(e={}){let t=new R(e);try{let n=e.client;if(!n){let e=await t.listClients();if(!e||e.length===0){console.error(`Error: No clients connected.`),y.exitCode=1;return}n=e[0].clientId}let r=n||``;console.log(`Fetching tasks from client ${r}${e.group?` (group: ${e.group})`:``}...`);let i=await t.sendCommand(r,`list-tasks`,{groupId:e.group});if(i.success){let t=i.data?.tasks||[];if(t.length===0){console.log(e.group?`No tasks configured on client for group "${e.group}".`:`No tasks configured on client.`);return}console.log(`Tasks on ${n}${e.group?` (group: ${e.group})`:``} (${t.length}):\n`),t.forEach((e,t)=>{let n=e.enabled?`[enabled]`:`[disabled]`,r=e.name||e.prompt?.slice(0,30)||`Untitled task`;console.log(` ${t+1}. ${n} ${r} (${e.schedule||`manual`})`)})}else console.error(`Failed to list tasks: ${i.error}`),y.exitCode=1}catch(e){console.error(`Error executing tasks command: ${e.message}`),y.exitCode=1}}async function z(e=`get`,t={}){let n=t.cacheDir,r=A(n),i=!!(t.renew||e===`renew`||e===`generate`||e===`new`),a=t.set||(e===`set`&&t.id?t.id:null),o=``,s=!1;if(a)o=M(a,n),s=!0;else if(i)o=M(void 0,n),s=!0;else{let e=j(n);e?(o=e,s=!1):(o=N(void 0,n),s=!0)}return t.quiet?(console.log(o),{peerId:o,filePath:r,isRenewed:s}):t.json?(console.log(JSON.stringify({peerId:o,filePath:r,renewed:s},null,2)),{peerId:o,filePath:r,isRenewed:s}):(console.log(a?`WebRTC CLI Peer ID set to: ${o}`:s?`WebRTC CLI Peer ID created/renewed: ${o}`:`WebRTC CLI Peer ID: ${o}`),console.log(`Stored in: ${r}`),{peerId:o,filePath:r,isRenewed:s})}function ie(e,t){return new Promise((n,r)=>{let i=E(t);try{s.unlinkSync(i)}catch{}try{s.mkdirSync(l.dirname(i),{recursive:!0})}catch{}let a=x.createServer(async(t,n)=>{if(t.method===`GET`&&t.url===`/ping`){n.writeHead(200,{"Content-Type":`application/json`}),n.end(JSON.stringify({ok:!0,peerId:e.cliPeerId}));return}if(t.method===`GET`&&t.url===`/clients`){let t=Array.from(e._connections.keys()).map(t=>{let n=e._peerCards?.get(t);return{clientId:t,peerId:t,deviceLabel:n?.name||`Browser Peer (${t})`,capabilities:n?.capabilities||[`webrtc`,`peerjs`],version:n?.version||`1.0.0`,transport:`webrtc`,connectedAt:Date.now(),lastSeen:Date.now()}});n.writeHead(200,{"Content-Type":`application/json`}),n.end(JSON.stringify({ok:!0,clients:t}));return}if(t.method===`POST`&&t.url===`/command`){let r=``;t.on(`data`,e=>r+=e),t.on(`end`,async()=>{try{let{targetPeerId:t,action:i,args:a,timeoutMs:o}=JSON.parse(r);if(!t){n.writeHead(400,{"Content-Type":`application/json`}),n.end(JSON.stringify({error:`targetPeerId is required`}));return}let s=e._connections.get(t);if(!s){let r=Array.from(e._connections.keys());n.writeHead(503,{"Content-Type":`application/json`}),n.end(JSON.stringify({error:`No DataChannel open to peer "${t}". Make sure the browser has connected to this listener first.`+(r.length?` Connected peers: ${r.join(`, `)}`:` No peers are currently connected.`)}));return}let c=`${Date.now()}-${Math.random().toString(36).slice(2)}`,l={id:c,type:`command:execute`,payload:{commandId:c,action:i,args:a||{}}},u=await new Promise((t,n)=>{let r=setTimeout(()=>{e._pendingIpc.delete(c),n(Error(`Command "${i}" timed out after ${o||3e4}ms`))},o||3e4);e._pendingIpc.set(c,e=>{clearTimeout(r),t(e)});try{s.send(l)}catch(t){clearTimeout(r),e._pendingIpc.delete(c),n(t)}});n.writeHead(200,{"Content-Type":`application/json`}),n.end(JSON.stringify(u))}catch(e){n.writeHead(500,{"Content-Type":`application/json`}),n.end(JSON.stringify({error:e.message}))}});return}n.writeHead(404),n.end()});a.listen(i,()=>{console.log(`[webrtc-listen] IPC socket: ${i}`),n(a)}),a.on(`error`,r)})}async function ae(e={}){let t=e.host||y.env.SHADOWCLAW_HOST||`127.0.0.1`,n=e.port?parseInt(String(e.port),10):parseInt(y.env.SHADOWCLAW_PORT||`8888`,10),r=e.path||`/`,i=!!(e.secure||e.https||[`1`,`true`,`yes`].includes((y.env.SHADOWCLAW_HTTPS||``).toLowerCase().trim())),a=!!(e.insecure===!1||[`0`,`false`,`no`].includes((y.env.SHADOWCLAW_TLS_REJECT_UNAUTHORIZED||``).toLowerCase().trim())),o=e.trustedPeer?Array.isArray(e.trustedPeer)?e.trustedPeer:[e.trustedPeer]:[],s=N(e.peerId,e.cacheDir);console.log(`WebRTC CLI Peer ID : ${s}`),console.log(`Signaling server : ${i?`wss`:`ws`}://${t}:${n}${r}`),i&&!a&&console.log(`TLS verification : disabled (self-signed cert allowed)`),o.length>0?console.log(`Trusted peers : ${o.join(`, `)}`):console.log(`Trusted peers : (any — add --trusted-peer <id> to restrict)`),console.log(``),console.log(`Add this CLI Peer ID as a trusted peer in the browser:`),console.log(` Settings → WebRTC/PeerJS → Trusted Peer IDs → "${s}"`),console.log(``);let c=new I({host:t,port:n,path:r,secure:i,rejectUnauthorized:a,trustedPeerIds:o,peerId:e.peerId,cacheDir:e.cacheDir,renewPeerId:!!e.renewPeerId,verbose:!!e.verbose}),l=new Map;c._pendingIpc=l;let u=c._setupConnection.bind(c);c._setupConnection=function(e,t){u(e,t),e.on(`data`,e=>{let t=e;if(typeof e==`string`)try{t=JSON.parse(e)}catch{return}if(!(!t||typeof t!=`object`)&&t.type===`command:result`){let e=t.payload||{},n=l.get(e.commandId);n&&(l.delete(e.commandId),n(e))}})};let d=t=>{if(console.log(`
3
3
  [webrtc-listen] Shutting down…`),D(e.cacheDir),t)try{t.close()}catch{}c.close(),y.exit(0)};try{await c.start();let t=await ie(c,e.cacheDir);y.on(`SIGINT`,()=>d(t)),y.on(`SIGTERM`,()=>d(t)),console.log(`[webrtc-listen] Ready. Run commands with:
4
4
  node bin/cli.mjs send --transport webrtc --client <browser-peer-id> "message"`),await new Promise(()=>{})}catch(t){D(e.cacheDir),console.error(`Error starting WebRTC listener: ${t.message}`),y.exitCode=1}}const oe=l.dirname(u(import.meta.url));function se(){try{let e=l.resolve(oe,`../../../package.json`);if(s.existsSync(e)){let t=JSON.parse(s.readFileSync(e,`utf8`));if(t.version)return t.version}}catch{}return`1.27.1`}function B(e){return typeof e==`string`&&e.startsWith(`shadowclaw_client_`)?e.slice(18):e}function ce(e){return typeof e==`string`&&!e.startsWith(`shadowclaw_client_`)?`shadowclaw_client_${e}`:e}const le=[{name:`shadowclaw_server_list_clients`,description:`List connected browser and Electron clients, including device type, ID, and active capabilities.`,inputSchema:{type:`object`,properties:{}}},{name:`shadowclaw_server_send_message`,description:`Send a message or prompt to a connected ShadowClaw client's active AI orchestrator queue.`,inputSchema:{type:`object`,properties:{text:{type:`string`,description:`The prompt or message text to dispatch.`},clientId:{type:`string`,description:`Target client ID. If omitted, targets the first available connected client.`},groupId:{type:`string`,description:`Target conversation group ID (e.g. 'br:main'). If omitted, targets the active group.`}},required:[`text`]}},{name:`shadowclaw_server_read_state`,description:`Read the current orchestrator state, active group ID, and capabilities from a connected client.`,inputSchema:{type:`object`,properties:{clientId:{type:`string`,description:`Target client ID.`}}}},{name:`shadowclaw_server_list_tasks`,description:`List scheduled background tasks configured on a connected client.`,inputSchema:{type:`object`,properties:{clientId:{type:`string`},groupId:{type:`string`}}}},{name:`shadowclaw_server_set_active_client`,description:`Set the active default connected client used when no clientId is explicitly provided in tool calls.`,inputSchema:{type:`object`,properties:{clientId:{type:`string`,description:`Target client ID (or index '0', '1', prefix, or device label) to make active.`}},required:[`clientId`]}},{name:`shadowclaw_server_manage_backup`,description:`Trigger or manage OPFS workspace backups for a connected client (trigger, list, or delete).`,inputSchema:{type:`object`,properties:{action:{type:`string`,enum:[`trigger`,`list`,`delete`],default:`trigger`},clientId:{type:`string`},backupId:{type:`string`},groupId:{type:`string`}}}},{name:`shadowclaw_server_status`,description:`Query ShadowClaw Node server status, version, and active client count.`,inputSchema:{type:`object`,properties:{}}},{name:`shadowclaw_server_send_notification`,description:`Broadcast an OS-level push notification to subscribed devices via Web Push (VAPID), or send to a specific registered client. Works even when the client browser tab is closed, asleep, or running in the background.`,inputSchema:{type:`object`,properties:{title:{type:`string`,description:`Notification title (default: 'ShadowClaw').`},body:{type:`string`,description:`The notification body message text.`},clientId:{type:`string`,description:`Target client ID, prefix, or device label of a specific client that has registered in the past. If omitted, broadcasts to all subscribed devices.`}},required:[`body`]}}];function V(e={}){let t=e.client||new R(e),n=e.relayClientTools!==!1,r=e.targetClientId||e.clientTarget,i=r||``,a={name:`shadow-claw`,version:e.version||se()},o={tools:{listChanged:!0},extensions:{"io.modelcontextprotocol/tasks":{}}};async function s(e){let n=e||i||r;try{let e=await t.listClients();if(Array.isArray(e)&&e.length>0){if(n&&typeof n==`string`&&n.trim()){let t=n.trim(),r=e.find(e=>(e.clientId||e.id)===t);if(r)return r.clientId||r.id;let i=parseInt(t,10);if(!isNaN(i)&&i>=0&&i<e.length)return e[i].clientId||e[i].id;let a=e.find(e=>(e.clientId||e.id||``).startsWith(t)||(e.clientId||``).replace(/^client-/,``).startsWith(t));if(a)return a.clientId||a.id;let o=e.find(e=>e.deviceLabel?.toLowerCase().includes(t.toLowerCase()));return o?o.clientId||o.id:t}return e[0].clientId||e[0].id||``}}catch{}return typeof n==`string`?n.trim():``}let c=new Map,l=new Map;async function u(){if(!n)return[];let e=[];try{e=await t.listClients()}catch{}if(!Array.isArray(e)||e.length===0)return c.clear(),l.clear(),[];c.clear(),l.clear();for(let n of e){let e=n.clientId||n.id;if(e)try{let r=await t.sendCommand(e,`list-tools`,{});if(r&&r.success&&r.data?.tools&&Array.isArray(r.data.tools))for(let e of r.data.tools){let t=B(e.name);t===`send_notification`||t.startsWith(`shadowclaw_`)&&!t.startsWith(`shadowclaw_client_`)||(l.has(t)||(l.set(t,e),c.set(t,[])),c.get(t).push(n))}}catch{}}let r=await s(),i=[];for(let[t,n]of l.entries()){let a=c.get(t)||[],o=a.map(e=>e.clientId||e.id).filter(Boolean),s=a.find(e=>(e.clientId||e.id)===r)||a[0],l=s?.clientId||s?.id||``,u=s?.deviceLabel||`Client`,d=n.inputSchema&&typeof n.inputSchema==`object`?n.inputSchema:{type:`object`,properties:{}},f={...d.properties||{},clientId:{type:`string`,description:`Target ShadowClaw client ID (optional; defaults to ${l} [${u}]). Available on: ${a.map(e=>`${e.clientId||e.id} (${e.deviceLabel||`Client`})`).join(`, `)}`,enum:o}},p=e.length>1?a.length>1?` [Default: ${u} (${l.slice(0,14)}...)]`:` [Client: ${u} (${l.slice(0,14)}...)]`:``,m=ce(t);i.push({name:m,description:(n.description||`Relayed tool '${t}' from connected client.`)+p,inputSchema:{...d,type:`object`,properties:f},annotations:n.annotations})}return i}async function d(e,n={}){let r=e.id===void 0||e.id===null,d=e.id??null;if(n[`mcp-method`]&&n[`mcp-method`]!==e.method)return{jsonrpc:`2.0`,id:d,error:{code:-32020,message:`Mcp-Method header '${n[`mcp-method`]}' does not match '${e.method}'`}};switch(e.method){case`server/discover`:return{jsonrpc:`2.0`,id:d,result:{protocolVersion:`2026-07-28`,supportedProtocolVersions:[`2026-07-28`,`2025-11-25`,`2024-11-05`],capabilities:o,serverInfo:a,_meta:{"io.modelcontextprotocol/serverInfo":a}}};case`initialize`:return{jsonrpc:`2.0`,id:d,result:{protocolVersion:e.params?.protocolVersion||`2024-11-05`,capabilities:o,serverInfo:a}};case`notifications/initialized`:return null;case`tools/list`:{let e=[];try{if(typeof t.listPushClients==`function`)e=await t.listPushClients();else if(typeof t.listPushSubscriptions==`function`){let n=await t.listPushSubscriptions();if(Array.isArray(n)){let t=new Map;for(let e of n){let n=(e.client_id||``).trim()||(e.id?String(e.id):``);n&&!t.has(n)&&t.set(n,{clientId:n,deviceLabel:e.device_label||void 0})}e=Array.from(t.values())}}}catch{}let n=Array.isArray(e)?[...e].sort((e,t)=>(e.clientId||``).localeCompare(t.clientId||``)):[],r=n.map(e=>e.clientId).filter(Boolean),i=await u(),o=new Map;for(let e of le)o.set(e.name,e);for(let e of i)o.has(e.name)||o.set(e.name,e);if(r.length>0)for(let e of[`shadowclaw_server_send_notification`,`shadowclaw_send_notification`]){let t=o.get(e);t&&o.set(e,{...t,inputSchema:{...t.inputSchema,type:`object`,properties:{...t.inputSchema?.properties||{},clientId:{type:`string`,description:`Target client ID, prefix, or device label of a specific client registered for push notifications (optional; if omitted, broadcasts to all subscribed devices). Available on: ${n.map(e=>`${e.clientId} (${e.deviceLabel||`Client`})`).join(`, `)}`,enum:r}}}})}return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,ttlMs:5e3,cacheScope:`private`,tools:Array.from(o.values()).sort((e,t)=>e.name.localeCompare(t.name)),_meta:{"io.modelcontextprotocol/serverInfo":a}}}}case`tools/call`:{let n=e.params?.name,r=e.params?.arguments||{},o=e.params?.inputResponses;if(!n)return{jsonrpc:`2.0`,id:d,error:{code:-32602,message:`Missing required parameter 'name'`}};if(n===`shadowclaw_server_list_clients`||n===`shadowclaw_list_clients`)try{let e=await t.listClients();return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,content:[{type:`text`,text:JSON.stringify({clients:e},null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":a}}}}catch(e){return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error listing clients: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":a}}}}if(n===`shadowclaw_server_set_active_client`||n===`shadowclaw_set_active_client`){let e=await s(r.clientId);return e?(i=e,console.error(`[ShadowClaw MCP] Active default client set to: ${i}`),{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,content:[{type:`text`,text:`Active default client set to: ${i}`}],_meta:{activeClientId:i,"io.modelcontextprotocol/serverInfo":a}}}):{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error: Client '${r.clientId}' not found among connected clients.`}],_meta:{"io.modelcontextprotocol/serverInfo":a}}}}if(n===`shadowclaw_server_send_message`||n===`shadowclaw_send_message`){let e=await s(r.clientId);if(!e)return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error: No connected client available.`}],_meta:{"io.modelcontextprotocol/serverInfo":a}}};try{let n=await t.sendCommand(e,`send-message`,{text:r.text,groupId:r.groupId});return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!n.success,content:[{type:`text`,text:JSON.stringify(n.data||n,null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":a}}}}catch(e){return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error sending message: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":a}}}}}if(n===`shadowclaw_server_read_state`||n===`shadowclaw_read_state`){let e=await s(r.clientId);try{let n=await t.sendCommand(e,`read-state`,{});return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!n.success,content:[{type:`text`,text:JSON.stringify(n.data||n,null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":a}}}}catch(e){return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error reading state: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":a}}}}}if(n===`shadowclaw_server_list_tasks`||n===`shadowclaw_list_tasks`){let e=await s(r.clientId);try{let n=await t.sendCommand(e,`list-tasks`,{groupId:r.groupId});return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!n.success,content:[{type:`text`,text:JSON.stringify(n.data||n,null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":a}}}}catch(e){return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error listing tasks: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":a}}}}}if(n===`shadowclaw_server_manage_backup`||n===`shadowclaw_manage_backup`){let e=r.action||`trigger`,n=await s(r.clientId);try{if(e===`list`){let e=await t.listBackups(n);return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,content:[{type:`text`,text:JSON.stringify({backups:e},null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":a}}}}if(e===`delete`){let e=await t.deleteBackup(r.backupId,n);return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,content:[{type:`text`,text:JSON.stringify(e,null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":a}}}}let i=await t.sendCommand(n,`trigger-backup`,{groupId:r.groupId});return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!i.success,content:[{type:`text`,text:JSON.stringify(i.data||i,null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":a}}}}catch(e){return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error managing backup: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":a}}}}}if(n===`shadowclaw_server_status`||n===`shadowclaw_status`)try{let e=await t.listClients();return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,content:[{type:`text`,text:JSON.stringify({server:`ShadowClaw`,version:a.version,connectedClients:e.length,status:`healthy`},null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":a}}}}catch(e){return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error querying server status: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":a}}}}if(n===`shadowclaw_server_send_notification`||n===`shadowclaw_send_notification`||n===`send_notification`){let e=String(r.body||``).trim();if(!e)return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error: Notification 'body' parameter cannot be empty.`}],_meta:{"io.modelcontextprotocol/serverInfo":a}}};let n=String(r.title||`ShadowClaw`).trim(),i=typeof r.clientId==`string`&&r.clientId.trim()?r.clientId.trim():void 0;try{let r=await t.broadcastNotification({title:n,body:e,...i?{clientId:i}:{}}),o=r?.sent??0,s=r?.failed??0,c;return c=r?.notFound?`Warning: No push subscriptions found for client '${i}'. Ensure push notifications were registered by this client in ShadowClaw Settings.`:r?.noSubscribers?`Warning: Push notification broadcast completed, but no devices are currently subscribed to push notifications. Ensure push notifications are enabled in ShadowClaw Settings on the client first.`:i?`Push notification sent to client '${i}': ${o} recipient(s) delivered, ${s} failed.`:`Push notification broadcast sent: ${o} recipient(s) delivered, ${s} failed.`,{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!1,content:[{type:`text`,text:c}],_meta:{...r,...i?{targetClientId:i}:{},"io.modelcontextprotocol/serverInfo":a}}}}catch(e){return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Failed to send push notification: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":a}}}}}let f=B(n);if((f===`ask_user`||n===`ask_user`)&&o&&o.response)return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,content:[{type:`text`,text:String(o.response)}],_meta:{"io.modelcontextprotocol/serverInfo":a}}};l.size===0&&await u();let p=(c.get(f)||c.get(n)||[]).map(e=>e.clientId||e.id).filter(Boolean),m=``;if(r.clientId)m=await s(r.clientId);else{let e=await s();m=p.includes(e)?e:p.length>0?p[0]:e}if(!m)return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error: No connected client available.`}],_meta:{"io.modelcontextprotocol/serverInfo":a}}};if(p.length>0&&!p.includes(m))return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error: Tool '${n}' is not enabled or available on client '${m}'. (Available on: ${p.join(`, `)})`}],_meta:{clientId:m,"io.modelcontextprotocol/serverInfo":a}}};try{console.error(`[ShadowClaw MCP] Executing '${f}' on client: ${m}`);let e={...r};delete e.clientId;let n=f===`ask_user`?await t.sendCommand(m,`invoke-tool`,{toolName:f,input:e},3e5):await t.sendCommand(m,`invoke-tool`,{toolName:f,input:e}),i=n.data?.result===void 0?n.data:n.data.result,o=typeof i==`string`?i:JSON.stringify(i,null,2),s=n.error||n.data&&n.data.error||`Unknown tool execution error`;return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!n.success,content:[{type:`text`,text:n.success?o||``:o&&o!==`null`&&o!==`{}`?`${o}\n${s}`:`Tool execution error: ${s}`}],_meta:{clientId:m,"io.modelcontextprotocol/serverInfo":a}}}}catch(e){return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Tool error: ${e.message}`}],_meta:{clientId:m,"io.modelcontextprotocol/serverInfo":a}}}}}case`tasks/get`:return{jsonrpc:`2.0`,id:d,result:{resultType:`complete`,task:{taskId:e.params?.taskId||`task-1`,status:`completed`},_meta:{"io.modelcontextprotocol/serverInfo":a}}};default:return r?null:{jsonrpc:`2.0`,id:d,error:{code:-32601,message:`Method not found: '${e.method}'`}}}}return{handleMessage:d,getActiveClientId:()=>i,setActiveClientId:e=>{i=e}}}async function ue(e={}){if((e.mcpTransport||(e.http?`http`:`stdio`))===`http`){let t=parseInt(String(e.port||y.env.MCP_PORT||`8888`),10),n=e.host||`127.0.0.1`,r=V(e);x.createServer(async(e,t)=>{if(e.method!==`POST`||e.url?.split(`?`)[0]!==`/mcp`){t.writeHead(404,{"Content-Type":`application/json`}),t.end(JSON.stringify({error:`Not found`}));return}let n=``;e.on(`data`,e=>n+=e),e.on(`end`,async()=>{let i;try{i=JSON.parse(n)}catch{t.writeHead(400,{"Content-Type":`application/json`}),t.end(JSON.stringify({jsonrpc:`2.0`,id:null,error:{code:-32700,message:`Parse error`}}));return}try{let n={"mcp-protocol-version":e.headers[`mcp-protocol-version`],"mcp-method":e.headers[`mcp-method`],"mcp-name":e.headers[`mcp-name`]},a=await r.handleMessage(i,n);if(a===null){t.writeHead(202),t.end();return}t.writeHead(200,{"Content-Type":`application/json`,"MCP-Protocol-Version":`2026-07-28`}),t.end(JSON.stringify(a))}catch(e){t.writeHead(500,{"Content-Type":`application/json`}),t.end(JSON.stringify({jsonrpc:`2.0`,id:i?.id??null,error:{code:-32603,message:e?.message||`Internal error`}}))}})}).listen(t,n,()=>{console.error(`[ShadowClaw MCP] HTTP MCP server listening at http://${n}:${t}/mcp (2026-07-28)`)});return}console.log=(...e)=>console.error(...e),console.info=(...e)=>console.error(...e);let t=V(e);w.createInterface({input:y.stdin,output:y.stdout,terminal:!1}).on(`line`,async e=>{let n=e.trim();if(!n)return;let r;try{r=JSON.parse(n)}catch{y.stdout.write(JSON.stringify({jsonrpc:`2.0`,id:null,error:{code:-32700,message:`Parse error`}})+`
5
5
  `);return}try{let e=await t.handleMessage(r);e!==null&&y.stdout.write(JSON.stringify(e)+`
6
6
  `)}catch(e){let t={jsonrpc:`2.0`,id:r?.id??null,error:{code:-32603,message:e?.message||`Internal error`}};y.stdout.write(JSON.stringify(t)+`
7
- `)}}),console.error(`[ShadowClaw MCP] STDIO MCP server active (2026-07-28)`)}async function H(e={}){let t=e.core||await o();t.setHeadlessMode(!0);let n,r;if(e.workspace)n=l.resolve(e.workspace),r=e.databaseDir?l.resolve(e.databaseDir):e.cacheDir?l.resolve(e.cacheDir,`database`):l.resolve(n,`database`);else{let t=await a({contentRoot:d.cwd(),cacheDir:e.cacheDir,databaseDir:e.databaseDir,tmp:e.tmp||e.temp,yes:e.yes||e.y,quiet:e.quiet,isTTY:e.isTTY,stdin:e.stdin,stdout:e.stdout});n=t.cacheDir,r=t.databaseDir}await m(n,{recursive:!0}),await m(r,{recursive:!0});let i=l.join(r,`agent.db`),s=t.openSqliteDatabase(i);return t.setDB(s),t.setStorageRootFromPath(n),t.setPostHandler(n=>{switch(n.type){case`response`:!e.quiet&&n.payload?.text&&console.log(n.payload.text);break;case`error`:!e.quiet&&n.payload?.error&&console.error(`Error: ${n.payload.error}`);break;case`tool-activity`:!e.quiet&&e.verbose&&n.payload&&console.log(`[Tool] ${n.payload.tool} (${n.payload.status||`executing`})`);break;case`request-native-ai-task`:if(n.payload&&typeof t.executeNativeAiTask==`function`){let{id:e,groupId:r,taskType:i,input:a}=n.payload;t.executeNativeAiTask({taskType:i,input:a,groupId:r,db:s}).then(t=>{let n=globalThis.pendingNativeAiResolvers;n&&n[e]&&(n[e].resolve(t),delete n[e])}).catch(t=>{let n=globalThis.pendingNativeAiResolvers;n&&n[e]&&(n[e].reject(t),delete n[e])})}break}}),{db:s,workspaceDir:n,dbPath:i,core:t}}function de(e={}){let{force:t=!1,stdin:n=d.stdin,timeoutMs:r}=e,i=n;return!t&&i?.isTTY?Promise.resolve(null):new Promise((e,t)=>{let n=[],a=!1,o;r!=null&&r>0&&(o=setTimeout(()=>{a=!0,typeof i?.destroy==`function`&&i.destroy(),e(null)},r)),typeof i?.setEncoding==`function`&&i.setEncoding(`utf8`),i.on(`data`,e=>{a||n.push(typeof e==`string`?e:e.toString(`utf8`))}),i.on(`end`,()=>{if(o&&clearTimeout(o),a)return;let t=n.join(``).trim();e(t.length>0?t:null)}),i.on(`error`,e=>{o&&clearTimeout(o),!a&&t(e)})})}function fe(e,t){let n=t&&typeof t==`object`?Object.keys(t.properties||{}):[];for(let t of[`text`,`prompt`,`content`,`input`])if(n.includes(t))return{[t]:e};return{input:e}}const U=new Set([`ask_user`,`attach_file_to_chat`,`clear_chat`,`create_room`,`invite_to_room`,`leave_room`,`list_components`,`list_room_members`,`open_file`,`render_component`,`send_file`,`show_toast`,`send_notification`,`spawn_subagent`]),W=`server:main`,pe=[`shadow-claw.config.json`,`shadow-claw-config.json`,`shadowclaw.config.json`,`site-config.json`];async function me(e){try{return await p(e,c.F_OK),!0}catch{return!1}}async function G(e,t){let n=[];if(e&&n.push(l.resolve(e)),t){let e=l.resolve(t);n.includes(e)||n.push(e)}if(e&&l.basename(l.resolve(e))===`.cache`){let t=l.dirname(l.resolve(e));n.includes(t)||n.push(t)}for(let e of n)for(let t of pe){let n=l.join(e,t);if(await me(n))try{let e=await h(n,`utf8`),t=JSON.parse(e);if(t&&typeof t==`object`)return{configPath:n,config:t}}catch{}}return null}async function he(e={}){let t;if(e.workspace)t=l.resolve(e.workspace);else{let{resolveCacheDir:n}=await import(`./chunk-B8sv2cCp.js`);t=(await n({contentRoot:d.cwd(),cacheDir:e.cacheDir,databaseDir:e.databaseDir,tmp:e.tmp||e.temp,yes:e.yes||e.y,quiet:e.quiet,isTTY:e.isTTY,stdin:e.stdin,stdout:e.stdout})).cacheDir}let n=l.join(t,`.agents`,`skills`),r=l.join(t,`.agents`,`tools`),i=l.join(t,`database`);await m(t,{recursive:!0}),await m(n,{recursive:!0}),await m(r,{recursive:!0}),await m(i,{recursive:!0});let a=e.provider,o=e.model,s=e.stdin?!!e.stdin.isTTY:!!d.stdin.isTTY,c=!e.stdin&&!d.stdin.isTTY&&!!(d.stderr.isTTY||d.stdout.isTTY),u=e.isTTY===void 0?s||c:!!e.isTTY,f=e.isCI===void 0?e.isTTY===void 0&&!!(d.env.CI&&![`0`,`false`].includes(d.env.CI.toLowerCase())):!!e.isCI,p=u&&!f&&!e.quiet&&!e.yes&&!e.y;if(!a&&!o&&p){let{promptForAgentModel:n}=await import(`./chunk-C4UfzPK4.js`),r=await n({workspaceDir:t,contentRoot:d.cwd(),cacheDir:e.cacheDir,stdin:e.stdin,stdout:e.stdout,quiet:e.quiet,isTTY:u});a=r.providerId,o=r.model}if(a||=`transformers_js_local`,!o){let{DEFAULT_LOCAL_MODEL:e}=await import(`./chunk-C4UfzPK4.js`);o=a===`transformers_js_local`?e:`openrouter/free`}if(await G(t)||await _(l.join(t,`shadow-claw.config.json`),JSON.stringify({$schema:`https://json-schema.org/draft/2020-12/schema`,site:{title:`ShadowClaw Agent Workspace`,description:`Headless CLI agent workspace`},settings:{defaultProvider:`openrouter`,defaultModel:`openrouter/free`},agent:{defaultProvider:a,defaultModel:o}},null,2)+`
8
- `,`utf8`),e.download&&(a===`transformers_js_local`||a===`llamafile`)){let{downloadLocalModel:t}=await import(`./chunk-C4UfzPK4.js`);await t(o,{cacheDir:e.cacheDir,verbose:e.verbose,isTTY:e.isTTY})}return await H({workspace:t,quiet:!0}),{success:!0,workspace:t}}async function ge(e={}){let{db:t,core:n}=await H(e),r=e.group||n.DEFAULT_SERVER_GROUP_ID||W,i=await n.discoverSkills(t,r);return{skills:i.skills,diagnostics:i.diagnostics}}async function _e(e={}){let{db:t,core:n}=await H(e),r=null;if(e.toolsProfile||e.profile){let i=String(e.toolsProfile||e.profile).trim().toLowerCase(),a=n.DEFAULT_BUILTIN_PROFILE||null,o=[];if(typeof n.getConfig==`function`)try{let e=await n.getConfig(t,n.CONFIG_KEYS?.TOOL_PROFILES||`tool_profiles`);typeof e==`string`?o=JSON.parse(e):Array.isArray(e)&&(o=e)}catch{}let s=[a,...o].filter(Boolean).find(e=>e.id&&String(e.id).toLowerCase()===i||e.name&&String(e.name).toLowerCase()===i);s&&(r=new Set(s.enabledToolNames||[]))}return{tools:(n.TOOL_DEFINITIONS||[]).map(e=>({name:e.name,description:e.description,headlessSafe:!U.has(e.name),...r?{enabled:r.has(e.name)}:{}}))}}async function K(e,t,n={}){let{db:r,workspaceDir:i,core:a}=await H(n),o=n.group||a.DEFAULT_SERVER_GROUP_ID||W,s=(a.TOOL_DEFINITIONS||[]).find(t=>t.name===e);if(!s&&typeof a.loadDeclarativeTools==`function`)try{s=(await a.loadDeclarativeTools(r,o)).tools.find(t=>t.name===e)}catch{}if(!s){let t=`Error: Tool "${e}" not found.`;return n.quiet||console.error(t),d.exitCode=1,{success:!1,error:t}}let c=!U.has(s.name),u=t??n.input;if(u===`-`&&(u=void 0),u==null&&n._stdinData!=null){let e=n._stdinData,t;try{t=JSON.parse(e)}catch{t=fe(e,s.input_schema)}u=t}if(u!=null){let t={};if(typeof u==`string`)try{t=JSON.parse(u)}catch(e){let t=`Error: Failed to parse input JSON: ${e.message}`;return n.quiet||console.error(t),d.exitCode=1,{success:!1,error:t}}else typeof u==`object`&&(t=u);let f;try{let e=await q(r,a,i,n);f={db:r,provider:e.providerId,model:e.model,apiKey:e.apiKey}}catch{}try{let i=await a.executeTool(r,e,t,o,{invokeContext:f}),u=typeof i==`string`?i:JSON.stringify(i,null,2);return n.output?(await _(l.resolve(n.output),u,`utf8`),n.quiet||d.stderr.write(`Output written to ${n.output}\n`)):n.quiet||d.stdout.write(u+`
7
+ `)}}),console.error(`[ShadowClaw MCP] STDIO MCP server active (2026-07-28)`)}async function H(e={}){let t=e.core||await o();t.setHeadlessMode(!0);let n,r;if(e.workspace)n=l.resolve(e.workspace),r=e.databaseDir?l.resolve(e.databaseDir):e.cacheDir?l.resolve(e.cacheDir,`database`):l.resolve(n,`database`);else{let t=await a({contentRoot:d.cwd(),cacheDir:e.cacheDir,databaseDir:e.databaseDir,tmp:e.tmp||e.temp,yes:e.yes||e.y,quiet:e.quiet,isTTY:e.isTTY,stdin:e.stdin,stdout:e.stdout});n=t.cacheDir,r=t.databaseDir}await m(n,{recursive:!0}),await m(r,{recursive:!0});let i=l.join(r,`agent.db`),s=t.openSqliteDatabase(i);return t.setDB(s),t.setStorageRootFromPath(n),t.setPostHandler(n=>{switch(n.type){case`response`:!e.quiet&&n.payload?.text&&console.log(n.payload.text);break;case`error`:!e.quiet&&n.payload?.error&&console.error(`Error: ${n.payload.error}`);break;case`tool-activity`:!e.quiet&&e.verbose&&n.payload&&console.log(`[Tool] ${n.payload.tool} (${n.payload.status||`executing`})`);break;case`request-native-ai-task`:if(n.payload&&typeof t.executeNativeAiTask==`function`){let{id:e,groupId:r,taskType:i,input:a}=n.payload;t.executeNativeAiTask({taskType:i,input:a,groupId:r,db:s}).then(t=>{let n=globalThis.pendingNativeAiResolvers;n&&n[e]&&(n[e].resolve(t),delete n[e])}).catch(t=>{let n=globalThis.pendingNativeAiResolvers;n&&n[e]&&(n[e].reject(t),delete n[e])})}break}}),{db:s,workspaceDir:n,dbPath:i,core:t}}function de(e={}){let{force:t=!1,stdin:n=d.stdin,timeoutMs:r}=e,i=n;return!t&&i?.isTTY?Promise.resolve(null):new Promise((e,t)=>{let n=[],a=!1,o;r!=null&&r>0&&(o=setTimeout(()=>{a=!0,typeof i?.destroy==`function`&&i.destroy(),e(null)},r)),typeof i?.setEncoding==`function`&&i.setEncoding(`utf8`),i.on(`data`,e=>{a||n.push(typeof e==`string`?e:e.toString(`utf8`))}),i.on(`end`,()=>{if(o&&clearTimeout(o),a)return;let t=n.join(``).trim();e(t.length>0?t:null)}),i.on(`error`,e=>{o&&clearTimeout(o),!a&&t(e)})})}function fe(e,t){let n=t&&typeof t==`object`?Object.keys(t.properties||{}):[];for(let t of[`text`,`prompt`,`content`,`input`])if(n.includes(t))return{[t]:e};return{input:e}}const U=new Set([`ask_user`,`attach_file_to_chat`,`clear_chat`,`create_room`,`invite_to_room`,`leave_room`,`list_components`,`list_room_members`,`open_file`,`render_component`,`send_file`,`show_toast`,`send_notification`,`spawn_subagent`]),W=`server:main`,pe=[`shadow-claw.config.json`,`shadow-claw-config.json`,`shadowclaw.config.json`,`site-config.json`];async function me(e){try{return await p(e,c.F_OK),!0}catch{return!1}}async function G(e,t){let n=[];if(e&&n.push(l.resolve(e)),t){let e=l.resolve(t);n.includes(e)||n.push(e)}if(e&&l.basename(l.resolve(e))===`.cache`){let t=l.dirname(l.resolve(e));n.includes(t)||n.push(t)}for(let e of n)for(let t of pe){let n=l.join(e,t);if(await me(n))try{let e=await h(n,`utf8`),t=JSON.parse(e);if(t&&typeof t==`object`)return{configPath:n,config:t}}catch{}}return null}async function he(e={}){let t;if(e.workspace)t=l.resolve(e.workspace);else{let{resolveCacheDir:n}=await import(`./chunk-B8sv2cCp.js`);t=(await n({contentRoot:d.cwd(),cacheDir:e.cacheDir,databaseDir:e.databaseDir,tmp:e.tmp||e.temp,yes:e.yes||e.y,quiet:e.quiet,isTTY:e.isTTY,stdin:e.stdin,stdout:e.stdout})).cacheDir}let n=l.join(t,`.agents`,`skills`),r=l.join(t,`.agents`,`tools`),i=l.join(t,`database`);await m(t,{recursive:!0}),await m(n,{recursive:!0}),await m(r,{recursive:!0}),await m(i,{recursive:!0});let a=e.provider,o=e.model,s=e.stdin?!!e.stdin.isTTY:!!d.stdin.isTTY,c=!e.stdin&&!d.stdin.isTTY&&!!(d.stderr.isTTY||d.stdout.isTTY),u=e.isTTY===void 0?s||c:!!e.isTTY,f=e.isCI===void 0?e.isTTY===void 0&&!!(d.env.CI&&![`0`,`false`].includes(d.env.CI.toLowerCase())):!!e.isCI,p=u&&!f&&!e.quiet&&!e.yes&&!e.y;if(!a&&!o&&p){let{promptForAgentModel:n}=await import(`./chunk-DTbrldk_.js`),r=await n({workspaceDir:t,contentRoot:d.cwd(),cacheDir:e.cacheDir,stdin:e.stdin,stdout:e.stdout,quiet:e.quiet,isTTY:u});a=r.providerId,o=r.model}if(a||=`transformers_js_local`,!o){let{DEFAULT_LOCAL_MODEL:e}=await import(`./chunk-DTbrldk_.js`);o=a===`transformers_js_local`?e:`openrouter/free`}if(await G(t)||await _(l.join(t,`shadow-claw.config.json`),JSON.stringify({$schema:`https://json-schema.org/draft/2020-12/schema`,site:{title:`ShadowClaw Agent Workspace`,description:`Headless CLI agent workspace`},settings:{defaultProvider:`openrouter`,defaultModel:`openrouter/free`},agent:{defaultProvider:a,defaultModel:o}},null,2)+`
8
+ `,`utf8`),e.download&&(a===`transformers_js_local`||a===`llamafile`)){let{downloadLocalModel:t}=await import(`./chunk-DTbrldk_.js`);await t(o,{cacheDir:e.cacheDir,verbose:e.verbose,isTTY:e.isTTY})}return await H({workspace:t,quiet:!0}),{success:!0,workspace:t}}async function ge(e={}){let{db:t,core:n}=await H(e),r=e.group||n.DEFAULT_SERVER_GROUP_ID||W,i=await n.discoverSkills(t,r);return{skills:i.skills,diagnostics:i.diagnostics}}async function _e(e={}){let{db:t,core:n}=await H(e),r=e.group||n.DEFAULT_SERVER_GROUP_ID||W,i=null;if(e.toolsProfile||e.profile){let r=String(e.toolsProfile||e.profile).trim().toLowerCase(),a=n.DEFAULT_BUILTIN_PROFILE||null,o=[];if(typeof n.getConfig==`function`)try{let e=await n.getConfig(t,n.CONFIG_KEYS?.TOOL_PROFILES||`tool_profiles`);typeof e==`string`?o=JSON.parse(e):Array.isArray(e)&&(o=e)}catch{}let s=[a,...o].filter(Boolean).find(e=>e.id&&String(e.id).toLowerCase()===r||e.name&&String(e.name).toLowerCase()===r);s&&(i=new Set(s.enabledToolNames||[]))}let a=[...n.TOOL_DEFINITIONS||[]];if(typeof n.loadDeclarativeTools==`function`)try{let e=await n.loadDeclarativeTools(t,r);if(e&&Array.isArray(e.tools))for(let t of e.tools)a.some(e=>e.name===t.name)||a.push(t)}catch{}return{tools:a.map(e=>({name:e.name,description:e.description,headlessSafe:!U.has(e.name),...i?{enabled:i.has(e.name)}:{}}))}}async function K(e,t,n={}){let{db:r,workspaceDir:i,core:a}=await H(n),o=n.group||a.DEFAULT_SERVER_GROUP_ID||W,s=(a.TOOL_DEFINITIONS||[]).find(t=>t.name===e);if(!s&&typeof a.loadDeclarativeTools==`function`)try{s=(await a.loadDeclarativeTools(r,o)).tools.find(t=>t.name===e)}catch{}if(!s){let t=`Error: Tool "${e}" not found.`;return n.quiet||console.error(t),d.exitCode=1,{success:!1,error:t}}let c=!U.has(s.name),u=t??n.input;if(u===`-`&&(u=void 0),u==null&&n._stdinData!=null){let e=n._stdinData,t;try{t=JSON.parse(e)}catch{t=fe(e,s.input_schema)}u=t}if(u!=null){let t={};if(typeof u==`string`)try{t=JSON.parse(u)}catch(e){let t=`Error: Failed to parse input JSON: ${e.message}`;return n.quiet||console.error(t),d.exitCode=1,{success:!1,error:t}}else typeof u==`object`&&(t=u);let f;try{let e=await q(r,a,i,{...n,interactive:!1});f={db:r,provider:e.providerId,model:e.model,apiKey:e.apiKey}}catch{}try{let i=await a.executeTool(r,e,t,o,{invokeContext:f}),u=typeof i==`string`?i:JSON.stringify(i,null,2);return n.output?(await _(l.resolve(n.output),u,`utf8`),n.quiet||d.stderr.write(`Output written to ${n.output}\n`)):n.quiet||d.stdout.write(u+`
9
9
  `),{success:!0,tool:s,headlessSafe:c,output:i}}catch(t){let r=t instanceof Error?t.message:String(t);return n.quiet||console.error(`Error executing tool "${e}": ${r}`),d.exitCode=1,{success:!1,error:r}}}if(!n.quiet){let e=c?`[headless-safe]`:`[browser-only]`;console.log(`Tool: ${s.name} ${e}\n`),console.log(`Description:\n ${s.description}\n`),s.input_schema&&(console.log(`Parameters (JSON Schema):`),console.log(JSON.stringify(s.input_schema,null,2)),console.log()),console.log(`Usage:`),console.log(` Direct CLI: npx shadow-claw agent tool ${s.name} '<json-input>'`),console.log(` Pipe input: echo '<text>' | npx shadow-claw agent tool ${s.name}`),console.log(` Agent Prompt: npx shadow-claw agent run "<instruction>"
10
- `)}return{success:!0,tool:s,headlessSafe:c}}async function ve(e,t={}){let{db:n,core:r}=await H(t),i=t.group||r.DEFAULT_SERVER_GROUP_ID||W,a=await r.loadSkill(n,i,e);if(!a)throw Error(`Skill "${e}" not found in workspace.`);if(a.execution?.type===`tools`&&Array.isArray(a.execution.tools)){let e=a.execution.tools.map(e=>({name:e.name||e.tool,input:e.input||e.arguments||{},suppressOutput:e.suppressOutput})),t=await r.executeToolChain(n,i,e,{isManual:!0});return{success:!0,skill:a,results:t.results,rawOutputs:t.rawOutputs}}return{success:!0,skill:a,message:`Skill "${e}" loaded (no declarative tools defined).`}}async function q(e,t,n,r={}){let i=r.contentRoot,a=await G(n,i),o=a?.config||{},s=o.settings||{},c=o.agent||s.agent||{},l=r.provider||d.env.SHADOW_CLAW_PROVIDER||d.env.SHADOW_CLAW_DEFAULT_PROVIDER;!l&&typeof t.getConfig==`function`&&(l=await t.getConfig(e,t.CONFIG_KEYS?.PROVIDER||`provider`)),l||=c.defaultProvider||c.provider||s.defaultProvider||s.provider||o.defaultProvider;let u=r.stdin?!!r.stdin.isTTY:!!d.stdin.isTTY,f=!r.stdin&&!d.stdin.isTTY&&!!(d.stderr.isTTY||d.stdout.isTTY),p=r.isTTY===void 0?u||f:!!r.isTTY,m=r.isCI===void 0?r.isTTY===void 0&&!!(d.env.CI&&![`0`,`false`].includes(d.env.CI.toLowerCase())):!!r.isCI,h=p&&!m&&!r.quiet;if(!l)if(h){let{promptForAgentModel:e}=await import(`./chunk-C4UfzPK4.js`),t=await e({workspaceDir:n,contentRoot:i,cacheDir:r.cacheDir,stdin:r.stdin,stdout:r.stdout,quiet:r.quiet,isTTY:p,service:r._transformersService});l=t.providerId,r.model=t.model}else l=`openrouter`;let g=typeof t.getProvider==`function`?t.getProvider(l):null;if(!g){let e=`Error: Unknown provider "${l}".`;throw Error(e)}let _;if(r.apiKey!==void 0)_=r.apiKey;else{if(_=d.env.SHADOW_CLAW_API_KEY,!_)switch(l){case`openrouter`:_=d.env.OPENROUTER_API_KEY;break;case`huggingface`:_=d.env.HUGGINGFACE_API_KEY||d.env.HF_TOKEN;break;case`gemini_proxy`:_=d.env.GEMINI_API_KEY;break}!_&&typeof t.getConfig==`function`&&(_=await t.getConfig(e,`api_key:${l}`)||await t.getConfig(e,`apiKey`))}let v=r.model||d.env.SHADOW_CLAW_MODEL||d.env.SHADOW_CLAW_DEFAULT_MODEL||(typeof t.getConfig==`function`?await t.getConfig(e,t.CONFIG_KEYS?.MODEL||`model`):null)||c.defaultModel||c.model||s.defaultModel||s.model||o.defaultModel||g?.defaultModel||(l===`transformers_js_local`?(await import(`./chunk-C4UfzPK4.js`)).DEFAULT_LOCAL_MODEL:`default`);if(l===`transformers_js_local`||l===`llamafile`){let{isModelLocallyCached:e,downloadLocalModel:t}=await import(`./chunk-C4UfzPK4.js`);if(!e(v,r.cacheDir)){let e=r.stdout||d.stderr;if(r.download)r.quiet||e.write(`\nDownloading ${v} from Hugging Face...\n`),await t(v,{cacheDir:r.cacheDir,stream:e,isTTY:p,service:r._transformersService,progress:r.progress!==!1&&!r.noProgress,verbose:r.verbose});else if(h){let n=await import(`node:readline/promises`),i=await import(`node:tty`),a=await import(`node:fs`),o=r.stdin||d.stdin,s=e,c=!1,l=null;if(o===d.stdin&&!d.stdin.isTTY&&!d.env.CI&&(d.stderr.isTTY||d.stdout.isTTY))try{let e=d.platform===`win32`?`CONIN$`:`/dev/tty`;l=a.openSync(e,`r`),o=new i.ReadStream(l),s=d.stderr.isTTY?d.stderr:d.stdout,c=!0}catch{try{let e=d.platform===`win32`?`CONIN$`:`/dev/tty`;o=a.createReadStream(e),s=d.stderr.isTTY?d.stderr:d.stdout,c=!0}catch{}}let u=n.createInterface({input:o,output:s}),f=!1,m=()=>{if(!f){f=!0,s.write(`
10
+ `)}return{success:!0,tool:s,headlessSafe:c}}async function ve(e,t={}){let{db:n,core:r}=await H(t),i=t.group||r.DEFAULT_SERVER_GROUP_ID||W,a=await r.loadSkill(n,i,e);if(!a)throw Error(`Skill "${e}" not found in workspace.`);if(a.execution?.type===`tools`&&Array.isArray(a.execution.tools)){let e=a.execution.tools.map(e=>({name:e.name||e.tool,input:e.input||e.arguments||{},suppressOutput:e.suppressOutput})),t=await r.executeToolChain(n,i,e,{isManual:!0});return{success:!0,skill:a,results:t.results,rawOutputs:t.rawOutputs}}return{success:!0,skill:a,message:`Skill "${e}" loaded (no declarative tools defined).`}}async function q(e,t,n,r={}){let i=r.contentRoot,a=await G(n,i),o=a?.config||{},s=o.settings||{},c=o.agent||s.agent||{},l=r.provider||d.env.SHADOW_CLAW_PROVIDER||d.env.SHADOW_CLAW_DEFAULT_PROVIDER;!l&&typeof t.getConfig==`function`&&(l=await t.getConfig(e,t.CONFIG_KEYS?.PROVIDER||`provider`)),l||=c.defaultProvider||c.provider||s.defaultProvider||s.provider||o.defaultProvider;let u=r.stdin?!!r.stdin.isTTY:!!d.stdin.isTTY,f=!r.stdin&&!d.stdin.isTTY&&!!(d.stderr.isTTY||d.stdout.isTTY),p=r.isTTY===void 0?u||f:!!r.isTTY,m=r.isCI===void 0?r.isTTY===void 0&&!!(d.env.CI&&![`0`,`false`].includes(d.env.CI.toLowerCase())):!!r.isCI,h=p&&!m&&!r.quiet&&r.interactive!==!1;if(!l)if(h){let{promptForAgentModel:e}=await import(`./chunk-DTbrldk_.js`),t=await e({workspaceDir:n,contentRoot:i,cacheDir:r.cacheDir,stdin:r.stdin,stdout:r.stdout,quiet:r.quiet,isTTY:p,service:r._transformersService});l=t.providerId,r.model=t.model}else l=`openrouter`;let g=typeof t.getProvider==`function`?t.getProvider(l):null;if(!g){let e=`Error: Unknown provider "${l}".`;throw Error(e)}let _;if(r.apiKey!==void 0)_=r.apiKey;else{if(_=d.env.SHADOW_CLAW_API_KEY,!_)switch(l){case`openrouter`:_=d.env.OPENROUTER_API_KEY;break;case`huggingface`:_=d.env.HUGGINGFACE_API_KEY||d.env.HF_TOKEN;break;case`gemini_proxy`:_=d.env.GEMINI_API_KEY;break}!_&&typeof t.getConfig==`function`&&(_=await t.getConfig(e,`api_key:${l}`)||await t.getConfig(e,`apiKey`))}let v=r.model||d.env.SHADOW_CLAW_MODEL||d.env.SHADOW_CLAW_DEFAULT_MODEL||(typeof t.getConfig==`function`?await t.getConfig(e,t.CONFIG_KEYS?.MODEL||`model`):null)||c.defaultModel||c.model||s.defaultModel||s.model||o.defaultModel||g?.defaultModel||(l===`transformers_js_local`?(await import(`./chunk-DTbrldk_.js`)).DEFAULT_LOCAL_MODEL:`default`);if(l===`transformers_js_local`||l===`llamafile`){let{isModelLocallyCached:e,downloadLocalModel:t}=await import(`./chunk-DTbrldk_.js`);if(!e(v,r.cacheDir)){let e=r.stdout||d.stderr;if(r.download)r.quiet||e.write(`\nDownloading ${v} from Hugging Face...\n`),await t(v,{cacheDir:r.cacheDir,stream:e,isTTY:p,service:r._transformersService,progress:r.progress!==!1&&!r.noProgress,verbose:r.verbose});else if(h){let n=await import(`node:readline/promises`),i=await import(`node:tty`),a=await import(`node:fs`),o=r.stdin||d.stdin,s=e,c=!1,l=null;if(o===d.stdin&&!d.stdin.isTTY&&!d.env.CI&&(d.stderr.isTTY||d.stdout.isTTY))try{let e=d.platform===`win32`?`CONIN$`:`/dev/tty`;l=a.openSync(e,`r`),o=new i.ReadStream(l),s=d.stderr.isTTY?d.stderr:d.stdout,c=!0}catch{try{let e=d.platform===`win32`?`CONIN$`:`/dev/tty`;o=a.createReadStream(e),s=d.stderr.isTTY?d.stderr:d.stdout,c=!0}catch{}}let u=n.createInterface({input:o,output:s}),f=!1,m=()=>{if(!f){f=!0,s.write(`
11
11
  Operation cancelled.
12
- `);try{u.close()}catch{}typeof r.onExit==`function`?r.onExit(130):d.exit(130)}};u.on(`SIGINT`,m),o&&typeof o.on==`function`&&o!==d.stdin&&o.on(`SIGINT`,m);let h=()=>m();d.on(`SIGINT`,h);let g=e=>{let t=typeof e==`string`?e:e.toString(`binary`);(t.includes(``)||t.includes(``))&&m()};o&&typeof o.on==`function`&&o.on(`data`,g);let _=``;try{_=(await u.question(`\nModel "${v}" is not yet downloaded to local disk.\nDownload model weights now? (Y/n) [default: Y]: `)).trim().toLowerCase()}finally{d.removeListener(`SIGINT`,h),o&&typeof o.removeListener==`function`&&(o!==d.stdin&&o.removeListener(`SIGINT`,m),o.removeListener(`data`,g));try{u.close()}catch{}if(c){if(o&&typeof o.destroy==`function`)try{o.destroy()}catch{}if(l!=null)try{a.closeSync(l)}catch{}}}(_===``||_===`y`||_===`yes`)&&(e.write(`\nDownloading ${v} from Hugging Face...\n`),await t(v,{cacheDir:r.cacheDir,stream:e,isTTY:p,service:r._transformersService,progress:r.progress!==!1&&!r.noProgress,verbose:r.verbose}))}}}return{providerId:l,providerConfig:g,apiKey:_||``,model:v,workspaceConfigData:a,workspaceConfig:o,workspaceSettings:s,workspaceAgent:c}}async function ye(e,t,n,r,i,a,o){let s=[...t.TOOL_DEFINITIONS||[]];if(typeof t.loadDeclarativeTools==`function`)try{let r=await t.loadDeclarativeTools(e,n);if(r&&Array.isArray(r.tools))for(let e of r.tools)s.some(t=>t.name===e.name)||s.push(e)}catch{}let c=s.filter(e=>!U.has(e.name)),l=c,u=null;async function d(){let n=t.DEFAULT_BUILTIN_PROFILE||null,a=[];if(typeof t.getConfig==`function`)try{let n=await t.getConfig(e,t.CONFIG_KEYS?.TOOL_PROFILES||`tool_profiles`);typeof n==`string`?a=JSON.parse(n):Array.isArray(n)&&(a=n)}catch{}let o=r?.toolProfiles||i?.toolProfiles||r?.profiles||[];return[n,...a,...o].filter(Boolean)}if(o.noTools===!0||o.tools===!1||o.tools===`none`||o.tools===``)return l=[],{enabledTools:l,profileSystemPromptOverride:u};if(o.tools!==void 0&&o.tools!==null)return l=(Array.isArray(o.tools)?o.tools:String(o.tools).split(`,`)).map(e=>String(e).trim()).filter(Boolean).map(e=>c.find(t=>t.name===e)).filter(Boolean),{enabledTools:l,profileSystemPromptOverride:u};if(o.toolsProfile){let e=await d(),t=String(o.toolsProfile).trim().toLowerCase(),n=e.find(e=>e.id&&String(e.id).toLowerCase()===t||e.name&&String(e.name).toLowerCase()===t);if(!n)throw Error(`Error: Tool profile "${o.toolsProfile}" not found.`);let r=new Set(n.enabledToolNames||[]);if(l=c.filter(e=>r.has(e.name)),n.customTools&&Array.isArray(n.customTools))for(let e of n.customTools)!U.has(e.name)&&!l.some(t=>t.name===e.name)&&l.push(e);return n.systemPromptOverride&&(u=n.systemPromptOverride),{enabledTools:l,profileSystemPromptOverride:u}}let f=a?.tools??a?.enabledTools;if(f!=null)return f===!1||f===`none`||f===``?(l=[],{enabledTools:l,profileSystemPromptOverride:u}):(l=(Array.isArray(f)?f:String(f).split(`,`)).map(e=>String(e).trim()).filter(Boolean).map(e=>c.find(t=>t.name===e)).filter(Boolean),{enabledTools:l,profileSystemPromptOverride:u});let p=a?.toolsProfile||a?.defaultToolsProfile;if(p){let e=await d(),t=String(p).trim().toLowerCase(),n=e.find(e=>e.id&&String(e.id).toLowerCase()===t||e.name&&String(e.name).toLowerCase()===t);if(n){let e=new Set(n.enabledToolNames||[]);return l=c.filter(t=>e.has(t.name)),n.systemPromptOverride&&(u=n.systemPromptOverride),{enabledTools:l,profileSystemPromptOverride:u}}}return{enabledTools:l,profileSystemPromptOverride:u}}async function be(e,t={}){let{db:n,workspaceDir:r,core:i}=await H(t),a=t.group||i.DEFAULT_SERVER_GROUP_ID||W,o=t._stdinData??null;if(e===`-`?e=o||``:o&&(e=e?`${e}\n\n${o}`:o),!e){let e=`Error: Prompt required. Provide a prompt argument or pipe text to stdin.`;return t.quiet||console.error(e),d.exitCode=1,{success:!1,error:e}}let s,c,u,f,p,m,g,v;try{let e=await q(n,i,r,t);s=e.providerId,c=e.providerConfig,u=e.apiKey,f=e.model,p=e.workspaceConfigData,m=e.workspaceConfig,g=e.workspaceSettings,v=e.workspaceAgent}catch(e){return t.quiet||console.error(e.message),d.exitCode=1,{success:!1,error:e.message}}if(c.requiresApiKey!==!1&&!u){let e=s===`huggingface`?`HUGGINGFACE_API_KEY`:`${s.toUpperCase()}_API_KEY`,n=`Error: Provider "${s}" requires an API key, but none was provided.\nPlease provide an API key via --api-key <key> or export ${e}="...".`;return t.quiet||console.error(n),d.exitCode=1,{success:!1,error:n}}let y=[];if(typeof i.getRecentMessages==`function`)try{y=await i.getRecentMessages(n,a,50)}catch{}let b={id:`msg_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,groupId:a,role:`user`,content:e,timestamp:Date.now()};if(typeof i.saveMessage==`function`)try{await i.saveMessage(n,b)}catch{}let x=c?.supportsStreaming===!0,S=t.stream!==!1&&t.streaming!==!1&&!t.noStream,C=x&&S,w=Number(t.maxTokens)||(typeof i.getModelMaxTokens==`function`?i.getModelMaxTokens(f):i.DEFAULT_MAX_TOKENS||8192);if(t.verbose&&!t.quiet){let e=c?.name||s,t=C?`streaming`:`standard`;d.stderr.write(`[Agent] Connecting to ${e} (${f}) [${t}]...\n`),d.stderr.write(`[Agent] Workspace: ${r}\n[Agent] Group: ${a}\n[Agent] Max tokens: ${w}\n`)}let T,E,D=!1,O=[];i.setPostHandler(async e=>{switch(e.type){case`streaming-start`:D=!0;break;case`streaming-chunk`:e.payload?.text&&(D=!0,T=(T||``)+e.payload.text,!t.quiet&&!t.output&&d.stdout.write(e.payload.text));break;case`streaming-done`:case`streaming-end`:break;case`response`:if(e.payload?.text)if(T=e.payload.text,t.output){let n=_(l.resolve(t.output),e.payload.text,`utf8`).then(()=>{t.quiet||d.stderr.write(`Output written to ${t.output}\n`)}).catch(()=>{});O.push(n)}else t.quiet||(D?e.payload.text.endsWith(`
12
+ `);try{u.close()}catch{}typeof r.onExit==`function`?r.onExit(130):d.exit(130)}};u.on(`SIGINT`,m),o&&typeof o.on==`function`&&o!==d.stdin&&o.on(`SIGINT`,m);let h=()=>m();d.on(`SIGINT`,h);let g=e=>{let t=typeof e==`string`?e:e.toString(`binary`);(t.includes(``)||t.includes(``))&&m()};o&&typeof o.on==`function`&&o.on(`data`,g);let _=``;try{_=(await u.question(`\nModel "${v}" is not yet downloaded to local disk.\nDownload model weights now? (Y/n) [default: Y]: `)).trim().toLowerCase()}finally{d.removeListener(`SIGINT`,h),o&&typeof o.removeListener==`function`&&(o!==d.stdin&&o.removeListener(`SIGINT`,m),o.removeListener(`data`,g));try{u.close()}catch{}if(c){if(o&&typeof o.destroy==`function`)try{o.destroy()}catch{}if(l!=null)try{a.closeSync(l)}catch{}}}(_===``||_===`y`||_===`yes`)&&(e.write(`\nDownloading ${v} from Hugging Face...\n`),await t(v,{cacheDir:r.cacheDir,stream:e,isTTY:p,service:r._transformersService,progress:r.progress!==!1&&!r.noProgress,verbose:r.verbose}))}}}return{providerId:l,providerConfig:g,apiKey:_||``,model:v,workspaceConfigData:a,workspaceConfig:o,workspaceSettings:s,workspaceAgent:c}}async function ye(e,t,n,r,i,a,o){let s=[...t.TOOL_DEFINITIONS||[]];if(typeof t.loadDeclarativeTools==`function`)try{let r=await t.loadDeclarativeTools(e,n);if(r&&Array.isArray(r.tools))for(let e of r.tools)s.some(t=>t.name===e.name)||s.push(e)}catch{}let c=s.filter(e=>!U.has(e.name)),l=c,u=null;async function d(){let n=t.DEFAULT_BUILTIN_PROFILE||null,a=[];if(typeof t.getConfig==`function`)try{let n=await t.getConfig(e,t.CONFIG_KEYS?.TOOL_PROFILES||`tool_profiles`);typeof n==`string`?a=JSON.parse(n):Array.isArray(n)&&(a=n)}catch{}let o=r?.toolProfiles||i?.toolProfiles||r?.profiles||[];return[n,...a,...o].filter(Boolean)}if(o.noTools===!0||o.tools===!1||o.tools===`none`||o.tools===``)return l=[],{enabledTools:l,profileSystemPromptOverride:u};if(o.tools!==void 0&&o.tools!==null)return l=(Array.isArray(o.tools)?o.tools:String(o.tools).split(`,`)).map(e=>String(e).trim()).filter(Boolean).map(e=>c.find(t=>t.name===String(e))).filter(Boolean),{enabledTools:l,profileSystemPromptOverride:u};if(o.toolsProfile){let e=await d(),t=String(o.toolsProfile).trim().toLowerCase(),n=e.find(e=>e.id&&String(e.id).toLowerCase()===t||e.name&&String(e.name).toLowerCase()===t);if(!n)throw Error(`Error: Tool profile "${o.toolsProfile}" not found.`);let r=new Set(n.enabledToolNames||[]);if(l=c.filter(e=>r.has(e.name)),n.customTools&&Array.isArray(n.customTools))for(let e of n.customTools)!U.has(e.name)&&!l.some(t=>t.name===e.name)&&l.push(e);return n.systemPromptOverride&&(u=n.systemPromptOverride),{enabledTools:l,profileSystemPromptOverride:u}}let f=a?.tools??a?.enabledTools;if(f!=null)return f===!1||f===`none`||f===``?(l=[],{enabledTools:l,profileSystemPromptOverride:u}):(l=(Array.isArray(f)?f:String(f).split(`,`)).map(e=>String(e).trim()).filter(Boolean).map(e=>c.find(t=>t.name===e)).filter(Boolean),{enabledTools:l,profileSystemPromptOverride:u});let p=a?.toolsProfile||a?.defaultToolsProfile;if(p){let e=await d(),t=String(p).trim().toLowerCase(),n=e.find(e=>e.id&&String(e.id).toLowerCase()===t||e.name&&String(e.name).toLowerCase()===t);if(n){let e=new Set(n.enabledToolNames||[]);return l=c.filter(t=>e.has(t.name)),n.systemPromptOverride&&(u=n.systemPromptOverride),{enabledTools:l,profileSystemPromptOverride:u}}}return{enabledTools:l,profileSystemPromptOverride:u}}async function be(e,t={}){let{db:n,workspaceDir:r,core:i}=await H(t),a=t.group||i.DEFAULT_SERVER_GROUP_ID||W,o=t._stdinData??null;if(e===`-`?e=o||``:o&&(e=e?`${e}\n\n${o}`:o),!e){let e=`Error: Prompt required. Provide a prompt argument or pipe text to stdin.`;return t.quiet||console.error(e),d.exitCode=1,{success:!1,error:e}}let s,c,u,f,p,m,g,v;try{let e=await q(n,i,r,t);s=e.providerId,c=e.providerConfig,u=e.apiKey,f=e.model,p=e.workspaceConfigData,m=e.workspaceConfig,g=e.workspaceSettings,v=e.workspaceAgent}catch(e){return t.quiet||console.error(e.message),d.exitCode=1,{success:!1,error:e.message}}if(c.requiresApiKey!==!1&&!u){let e=s===`huggingface`?`HUGGINGFACE_API_KEY`:`${s.toUpperCase()}_API_KEY`,n=`Error: Provider "${s}" requires an API key, but none was provided.\nPlease provide an API key via --api-key <key> or export ${e}="...".`;return t.quiet||console.error(n),d.exitCode=1,{success:!1,error:n}}let y=[];if(typeof i.getRecentMessages==`function`)try{y=await i.getRecentMessages(n,a,50)}catch{}let b={id:`msg_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,groupId:a,role:`user`,content:e,timestamp:Date.now()};if(typeof i.saveMessage==`function`)try{await i.saveMessage(n,b)}catch{}let x=c?.supportsStreaming===!0,S=t.stream!==!1&&t.streaming!==!1&&!t.noStream,C=x&&S,w=Number(t.maxTokens)||(typeof i.getModelMaxTokens==`function`?i.getModelMaxTokens(f):i.DEFAULT_MAX_TOKENS||8192);if(t.verbose&&!t.quiet){let e=c?.name||s,t=C?`streaming`:`standard`;d.stderr.write(`[Agent] Connecting to ${e} (${f}) [${t}]...\n`),d.stderr.write(`[Agent] Workspace: ${r}\n[Agent] Group: ${a}\n[Agent] Max tokens: ${w}\n`)}let T,E,D=!1,O=[];i.setPostHandler(async e=>{switch(e.type){case`streaming-start`:D=!0;break;case`streaming-chunk`:e.payload?.text&&(D=!0,T=(T||``)+e.payload.text,!t.quiet&&!t.output&&d.stdout.write(e.payload.text));break;case`streaming-done`:case`streaming-end`:break;case`response`:if(e.payload?.text)if(T=e.payload.text,t.output){let n=_(l.resolve(t.output),e.payload.text,`utf8`).then(()=>{t.quiet||d.stderr.write(`Output written to ${t.output}\n`)}).catch(()=>{});O.push(n)}else t.quiet||(D?e.payload.text.endsWith(`
13
13
  `)||d.stdout.write(`
14
14
  `):d.stdout.write(e.payload.text+`
15
15
  `));break;case`intermediate-response`:t.verbose&&!t.quiet&&e.payload?.text&&d.stderr.write(`[Thought] ${e.payload.text}\n`);break;case`error`:e.payload?.error&&(E=e.payload.error,t.quiet||console.error(`Error: ${e.payload.error}`));break;case`tool-activity`:if(t.verbose&&!t.quiet&&e.payload){let t=e.payload.tool||`tool`,n=e.payload.status||`executing`;d.stderr.write(`[Tool] ${t} (${n})\n`)}break;case`status`:if(t.verbose&&!t.quiet&&e.payload){let t=e.payload.label?`[${e.payload.label}] `:``;d.stderr.write(`${t}${e.payload.message||``}\n`)}break;case`log`:if(t.verbose&&!t.quiet&&e.payload){let t=e.payload.label||e.payload.level||`Log`;d.stderr.write(`[${t}] ${e.payload.message||``}\n`)}break;case`token-usage`:if(t.verbose&&!t.quiet&&e.payload?.usage){let t=e.payload.usage,n=t.prompt_tokens??t.input_tokens??0,r=t.completion_tokens??t.output_tokens??0,i=t.total_tokens??n+r;d.stderr.write(`[Tokens] Prompt: ${n}, Completion: ${r}, Total: ${i}\n`)}break;case`request-native-ai-task`:if(e.payload&&typeof i.executeNativeAiTask==`function`){let{id:t,groupId:r,taskType:a,input:o}=e.payload;i.executeNativeAiTask({taskType:a,input:o,groupId:r,db:n}).then(e=>{let n=globalThis.pendingNativeAiResolvers;n&&n[t]&&(n[t].resolve(e),delete n[t])}).catch(e=>{let n=globalThis.pendingNativeAiResolvers;n&&n[t]&&(n[t].reject(e),delete n[t])})}break}});let k;try{k=await ye(n,i,a,m,g,v,t)}catch(e){let n=e.message||String(e);return t.quiet||console.error(n),d.exitCode=1,{success:!1,error:n}}let{enabledTools:A,profileSystemPromptOverride:j}=k,M=t.systemPrompt;if(!M&&t.systemPromptFile)try{M=await h(l.resolve(t.systemPromptFile),`utf8`)}catch(e){let n=`Error: Failed to read system prompt file "${t.systemPromptFile}": ${e.message}`;return t.quiet||console.error(n),d.exitCode=1,{success:!1,error:n}}if(M||=d.env.SHADOW_CLAW_SYSTEM_PROMPT||d.env.SHADOWCLAW_SYSTEM_PROMPT,!M&&j&&(M=j),!M&&v?.systemPromptFile)try{let e=p?.configPath?l.dirname(p.configPath):r;M=await h(l.resolve(e,v.systemPromptFile),`utf8`)}catch(e){t.verbose&&!t.quiet&&console.error(`Warning: Failed to read systemPromptFile from config: ${e.message}`)}if(M||=v?.systemPrompt||g?.systemPrompt||g?.systemPromptOverride,!M&&typeof i.getConfig==`function`)try{let e=await i.getConfig(n,i.CONFIG_KEYS?.SYSTEM_PROMPT_OVERRIDE||`system_prompt_override`);e&&typeof e==`string`&&(M=e)}catch{}M||=`You are ShadowClaw, a helpful AI assistant operating in a headless workspace. Answer concisely.`;let N={apiKey:u||``,assistantName:`ShadowClaw`,enabledTools:A,groupId:a,maxTokens:w,messages:[...y,b],model:f,provider:s,streaming:C,verbose:!!t.verbose,systemPrompt:M},P=new AbortController;t.abortSignal&&(t.abortSignal.aborted?P.abort():t.abortSignal.addEventListener(`abort`,()=>P.abort(),{once:!0}));let F=!1,I=()=>{if(!F){F=!0,P.abort();try{typeof i.cleanupAllLlamafileProcesses==`function`&&i.cleanupAllLlamafileProcesses()}catch{}}};d.on(`SIGINT`,I);let L=t.invokeHandler||i.handleInvoke;try{await L(n,N,P.signal)}catch(e){E=e instanceof Error?e.message:String(e),!F&&!t.quiet&&console.error(`Error: ${E}`)}finally{d.removeListener(`SIGINT`,I)}if(F)return t.quiet||d.stderr.write(`
16
16
  Operation cancelled.
17
17
  `),d.exitCode=130,typeof t.onExit==`function`&&t.onExit(130),{success:!1,error:`Operation cancelled.`};if(E&&D&&!t.quiet&&!t.output&&d.stdout.write(`
18
- `),E)return d.exitCode=1,{success:!1,error:E};if(T&&typeof i.saveMessage==`function`)try{await i.saveMessage(n,{id:`msg_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,groupId:a,role:`assistant`,content:T,timestamp:Date.now()})}catch{}if(t.output&&T&&O.length===0){let e=_(l.resolve(t.output),T,`utf8`).then(()=>{t.quiet||d.stderr.write(`Output written to ${t.output}\n`)}).catch(()=>{});O.push(e)}return await Promise.all(O),typeof i.setPostHandler==`function`&&i.setPostHandler(null),{success:!0,response:T,model:f,provider:s}}async function xe(e=`list`,t,n={}){let{listLocalModels:r,listLlamafileModels:i,downloadLocalModel:a,fetchRemoteModels:o,DEFAULT_LOCAL_MODEL:s}=await import(`./chunk-C4UfzPK4.js`),c=n.workspace?l.resolve(n.workspace):d.cwd(),u=e||`list`;if(u===`list`||u===`remote`){let e=u===`remote`||!!(n.remote||n.all||n.huggingface),a=await G(c),l=a?.config?.agent?.defaultModel||a?.config?.settings?.defaultModel||s;if(e){n.quiet||d.stdout.write(`
18
+ `),E)return d.exitCode=1,{success:!1,error:E};if(T&&typeof i.saveMessage==`function`)try{await i.saveMessage(n,{id:`msg_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,groupId:a,role:`assistant`,content:T,timestamp:Date.now()})}catch{}if(t.output&&T&&O.length===0){let e=_(l.resolve(t.output),T,`utf8`).then(()=>{t.quiet||d.stderr.write(`Output written to ${t.output}\n`)}).catch(()=>{});O.push(e)}return await Promise.all(O),typeof i.setPostHandler==`function`&&i.setPostHandler(null),{success:!0,response:T,model:f,provider:s}}async function xe(e=`list`,t,n={}){let{listLocalModels:r,listLlamafileModels:i,downloadLocalModel:a,fetchRemoteModels:o,DEFAULT_LOCAL_MODEL:s}=await import(`./chunk-DTbrldk_.js`),c=n.workspace?l.resolve(n.workspace):d.cwd(),u=e||`list`;if(u===`list`||u===`remote`){let e=u===`remote`||!!(n.remote||n.all||n.huggingface),a=await G(c),l=a?.config?.agent?.defaultModel||a?.config?.settings?.defaultModel||s;if(e){n.quiet||d.stdout.write(`
19
19
  Fetching available ONNX models from Hugging Face (onnx-community)...
20
20
  `);let e=await o({cacheDir:n.cacheDir,query:n.query||(u===`remote`&&t?t:void 0)});if(!n.quiet)if(e.length===0)d.stdout.write(`No models found on Hugging Face or could not reach huggingface.co.
21
21
 
@@ -29,13 +29,14 @@ Curated Transformers.js Models (Local ONNX):
29
29
  `);for(let e of f){let t=e.id===l,n=e.cached?` [Cached]`:` [Not downloaded]`,r=t?` (Default)`:``;d.stdout.write(` • ${e.id}${r}${n}\n`),d.stdout.write(` Name: ${e.name}\n`),d.stdout.write(` Context: ${e.contextLength.toLocaleString()} tokens | Tools: ${e.supportsTools?`Yes`:`No`}\n`),d.stdout.write(` ${e.description}\n\n`)}d.stdout.write(`Curated Llamafile Models (Local Executable):
30
30
 
31
31
  `);for(let e of p){let t=e.fileName===l||e.id===l||l.endsWith(e.fileName),n=e.cached?` [Cached]`:` [Not downloaded]`,r=t?` (Default)`:``;d.stdout.write(` • ${e.fileName}${r}${n}\n`),d.stdout.write(` Name: ${e.name}\n`),d.stdout.write(` URL: ${e.url}\n`),d.stdout.write(` ${e.description}\n\n`)}d.stdout.write("Tip: Run `shadow-claw agent model list --remote` (or `shadow-claw agent model remote`) to browse all ONNX models from Hugging Face.\n\n")}return{success:!0,models:f,llamafileModels:p,defaultModel:l}}if(u===`download`){let e=t||n.model||s;n.verbose&&!n.quiet&&d.stderr.write(`Preparing to download model: ${e}\n`);let r=await a(e,{cacheDir:n.cacheDir,verbose:n.verbose,isTTY:n.isTTY,progress:n.progress!==!1&&!n.noProgress});return r.success||(d.exitCode=1),r}if(u===`set`){let e=t||n.model;if(!e){let e=`Error: Please specify a model ID to set as default.`;return n.quiet||console.error(e),d.exitCode=1,{success:!1,error:e}}let r=await G(c),i=r?.configPath||l.join(c,`shadow-claw.config.json`),a=r?.config||{},o={...a,agent:{...a.agent||{},defaultModel:e}};return await _(i,JSON.stringify(o,null,2)+`
32
- `,`utf8`),n.quiet||d.stdout.write(`Updated default CLI agent model to: ${e}\n`),{success:!0,model:e,configPath:i}}let f=`Unknown model action: "${u}". Available: list, download, set`;return n.quiet||console.error(f),d.exitCode=1,{success:!1,error:f}}async function Se(e,t=[],n={}){let r=t,i=n;if(!Array.isArray(t)&&typeof t==`object`&&(i=t,r=[]),i._stdinData===void 0)try{i={...i,_stdinData:d.stdin.isTTY?null:await de({timeoutMs:500})}}catch{i={...i,_stdinData:null}}switch(e){case`init`:{let e=r[0]||i.workspace,t=await he({...i,workspace:e});return console.log(`Headless agent workspace initialized at: ${t.workspace}`),t}case`skills`:{let e=await ge(i);if(e.skills.length===0)console.log(`No skills found in workspace (.agents/skills/).`);else{console.log(`Available skills (${e.skills.length}):\n`);for(let t of e.skills)console.log(` - ${t.name}: ${t.description||`No description`}`)}return e}case`tools`:{let e=r[0];if(e)return await K(e,r[1],i);let t=await _e(i);console.log(`Available tools (${t.tools.length}):\n`);for(let e of t.tools){let t=e.headlessSafe?`[headless-safe]`:`[browser-only]`;console.log(` - ${e.name.padEnd(25)} ${t} ${e.description||``}`)}return t}case`tool`:{let e=r[0];if(!e){console.error(`Error: Tool name required. Usage: shadow-claw agent tool <name> [input-json]`),d.exitCode=1;return}return await K(e,r[1],i)}case`skill`:{let e=r[0];if(!e){console.error(`Error: Skill name required. Usage: shadow-claw agent skill <name>`),d.exitCode=1;return}return await ve(e,i)}case`run`:return await be(r.join(` `)||`-`,i);case`models`:case`model`:{let e=r[0]||`list`,t=r[1];return await xe(e,t,i)}default:console.log(`Usage: shadow-claw agent <init|model|skills|tools|tool|skill|run> [args...]`)}}const J=t(import.meta.url),Y=new Set;function Ce(e){return typeof e==`function`?(Y.add(e),()=>Y.delete(e)):()=>!1}let X=!1;const we=(e,t)=>{X&&d.exit(t),X=!0;for(let t of Y)try{t(e)}catch{}d.stderr.write(`\nProcess interrupted (${e}).\n`),d.exit(t)};d.on(`SIGINT`,()=>we(`SIGINT`,130)),d.on(`SIGTERM`,()=>we(`SIGTERM`,143)),d.on(`exit`,()=>{for(let e of Y)try{e(`exit`)}catch{}});async function Te(){try{let e=await h(l.join(J,`package.json`),`utf8`);return JSON.parse(e).version||`1.0.0`}catch{return`1.0.0`}}async function Z(e){try{return await g(e),!0}catch{return!1}}function Ee(e){let t=d.platform===`darwin`?`open`:d.platform===`win32`?`start`:`xdg-open`;try{f(`${t} ${e}`)}catch{}}const De=await Te(),Q=new v;Q.name(`shadow-claw`).description(`Browser-native personal AI assistant and static site publisher`).version(De,`-v, --version`,`Output the current version`),Q.commandsGroup(`Development:`),Q.command(`build`).description(`Build the static site bundle for production or staging`).optionsGroup(`Build Mode Options:`).option(`--prod, --production`,`Build in production mode with minification and optimizations`,!1).option(`--prerender-pages <mode>`,`Prerender page mode (all, auto, none)`,`auto`).option(`--copy-all-assets`,`Copy entire assets/ directory into output`,!1).optionsGroup(`Path & Routing Options:`).option(`--origin <url>`,`Canonical origin URL (e.g. https://user.github.io/repo/)`).option(`--base-path <path>`,`URL base path prefix (e.g. /repo/)`).option(`--out-dir <dir>`,`Output directory relative to content root`,`dist/public`).option(`--content-root <dir>`,`Content root directory`,d.cwd()).action(async e=>{try{let t=l.resolve(e.contentRoot||d.cwd()),r=!!(e.prod||e.production||d.env.NODE_ENV===`production`);console.log(`Building ShadowClaw site from ${t}...`),await n({contentRoot:t,toolchainRoot:J,outDir:e.outDir||`dist/public`,isProduction:r,pagesOrigin:e.origin||d.env.PAGES_ORIGIN,basePath:e.basePath||d.env.PAGES_BASE_PATH,prerenderPages:e.prerenderPages,copyAllAssets:e.copyAllAssets})}catch(e){console.error(`Build failed:`,e),d.exit(1)}});async function $(e,t){try{let r=l.resolve(t.contentRoot||d.cwd()),i=parseInt(e||t.port||d.env.PORT||`8888`,10),o=t.host||t.ip||d.env.SHADOWCLAW_DEV_IP||`127.0.0.1`,s=t.outDir||`dist/public`,c=l.resolve(r,s),u=await a({contentRoot:r,cacheDir:t.cacheDir,databaseDir:t.databaseDir,tmp:t.tmp||t.temp,yes:t.yes}),f=u.cacheDir,p=u.databaseDir;console.log(`Preparing ShadowClaw dev build for ${r}...`),await n({contentRoot:r,toolchainRoot:J,outDir:s,isProduction:!1,pagesOrigin:t.origin||d.env.PAGES_ORIGIN,basePath:t.basePath||d.env.PAGES_BASE_PATH,prerenderPages:t.prerenderPages||`auto`,copyAllAssets:t.copyAllAssets});let m=await Z(l.join(J,`dist/server.js`))?l.join(J,`dist/server.js`):l.join(J,`src/server/server.ts`);d.env.SHADOWCLAW_ROOT_PATH=c,d.env.SHADOWCLAW_CACHE_DIR=f,d.env.SHADOWCLAW_DATABASE_DIR=p,d.env.SHADOWCLAW_DEV_IP=o;let{startServer:h}=await import(m),g=new Set((t.corsAllowOrigin||d.env.SHADOWCLAW_CORS_ALLOWED_ORIGINS||`https://xt-ml.github.io`).split(`,`).map(e=>e.trim()).filter(Boolean)),_=!!(t.https||[`1`,`true`,`yes`].includes((d.env.SHADOWCLAW_HTTPS||``).toLowerCase().trim())),v=t.cert||(d.env.SHADOWCLAW_TLS_CERT||d.env.SHADOWCLAW_CERT||``).trim()||void 0,y=t.key||(d.env.SHADOWCLAW_TLS_KEY||d.env.SHADOWCLAW_KEY||``).trim()||void 0,b=l.resolve(r,t.sslDir||d.env.SHADOWCLAW_SSL_DIR||d.env.SHADOWCLAW_TLS_DIR||l.join(f,`tls`));await h({port:i,bindHost:o,corsMode:t.corsMode||`localhost`,allowedOrigins:g,verbose:!!t.verbose,peerjs:!!t.peerjs,rootPath:c,cacheDir:f,databaseDir:p,allowPrivateProxy:!!t.allowPrivateProxy,https:_,certPath:v,keyPath:y,sslDir:b});let x=`${_?`https`:`http`}://${o}:${i}`;t.open&&Ee(x)}catch(e){console.error(`Dev server error:`,e),d.exit(1)}}Q.command(`dev [port]`).description(`Build and launch the development server`).optionsGroup(`Server & Network Options:`).option(`-p, --port <port>`,`Port to listen on (default: 8888)`).option(`--host <host>`,`Bind host/IP`,`127.0.0.1`).option(`--ip <host>`,`Bind host/IP (alias)`).option(`--open`,`Automatically open default browser`,!1).option(`-v, --verbose`,`Enable verbose request/proxy logging`,!1).optionsGroup(`Site & Build Options:`).option(`--content-root <dir>`,`Content root directory`,d.cwd()).option(`--out-dir <dir>`,`Output directory relative to content root`,`dist/public`).optionsGroup(`Security & Proxy Options:`).option(`--cors-mode <mode>`,`CORS policy: localhost | private | all`,`localhost`).option(`--allow-private-proxy`,`Allow proxy to reach private/loopback addresses`,!1).option(`--peerjs`,`Enable built-in PeerJS signaling server`,!1).optionsGroup(`TLS / HTTPS Options:`).option(`--https`,`Enable HTTPS dev server`,!1).option(`--cert <path>`,`Path to existing TLS certificate file`).option(`--key <path>`,`Path to existing TLS private key file`).option(`--ssl-dir <path>`,`Directory for TLS certificate generation/storage`).optionsGroup(`Storage & Database Options:`).option(`--database-dir <dir>`,`Directory where SQLite databases are stored`).option(`--cache-dir <dir>`,`Custom cache directory for databases, tokens, and logs`).option(`--tmp, --temp`,`Store cache and databases in system temporary directory`,!1).option(`-y, --yes`,`Skip interactive cache directory prompt and use default .cache`,!1).action($),Q.command(`run [port]`).description(`Alias for dev: build and launch the development server`).optionsGroup(`Server & Network Options:`).option(`-p, --port <port>`,`Port to listen on (default: 8888)`).option(`--host <host>`,`Bind host/IP`,`127.0.0.1`).option(`--ip <host>`,`Bind host/IP (alias)`).option(`--open`,`Automatically open default browser`,!1).option(`-v, --verbose`,`Enable verbose request/proxy logging`,!1).optionsGroup(`Site & Build Options:`).option(`--content-root <dir>`,`Content root directory`,d.cwd()).option(`--out-dir <dir>`,`Output directory relative to content root`,`dist/public`).optionsGroup(`Security & Proxy Options:`).option(`--cors-mode <mode>`,`CORS policy: localhost | private | all`,`localhost`).option(`--allow-private-proxy`,`Allow proxy to reach private/loopback addresses`,!1).option(`--peerjs`,`Enable built-in PeerJS signaling server`,!1).optionsGroup(`TLS / HTTPS Options:`).option(`--https`,`Enable HTTPS dev server`,!1).option(`--cert <path>`,`Path to existing TLS certificate file`).option(`--key <path>`,`Path to existing TLS private key file`).option(`--ssl-dir <path>`,`Directory for TLS certificate generation/storage`).optionsGroup(`Storage & Database Options:`).option(`--database-dir <dir>`,`Directory where SQLite databases are stored`).option(`--cache-dir <dir>`,`Custom cache directory for databases, tokens, and logs`).option(`--tmp, --temp`,`Store cache and databases in system temporary directory`,!1).option(`-y, --yes`,`Skip interactive cache directory prompt and use default .cache`,!1).action($),Q.commandsGroup(`Server:`),Q.command(`serve [port]`).description(`Serve an existing static site build and start the backend proxy`).optionsGroup(`Server & Network Options:`).option(`-p, --port <port>`,`Port to listen on (default: 8888)`).option(`--host <host>`,`Bind host/IP`,`127.0.0.1`).option(`--no-static`,`Disable static file and UI serving (services-only mode)`).option(`--open`,`Automatically open default browser`,!1).option(`-v, --verbose`,`Enable verbose request/proxy logging`,!1).optionsGroup(`Site Options:`).option(`--content-root <dir>`,`Content root directory`,d.cwd()).option(`--out-dir <dir>`,`Output directory relative to content root`,`dist/public`).optionsGroup(`Security & Proxy Options:`).option(`--cors-mode <mode>`,`CORS policy: localhost | private | all`,`localhost`).option(`--allow-private-proxy`,`Allow proxy to reach private/loopback addresses`,!1).option(`--peerjs`,`Enable built-in PeerJS signaling server`,!1).optionsGroup(`TLS / HTTPS Options:`).option(`--https`,`Enable HTTPS dev server`,!1).option(`--cert <path>`,`Path to existing TLS certificate file`).option(`--key <path>`,`Path to existing TLS private key file`).option(`--ssl-dir <path>`,`Directory for TLS certificate generation/storage`).optionsGroup(`Storage & Database Options:`).option(`--database-dir <dir>`,`Directory where SQLite databases are stored`).option(`--cache-dir <dir>`,`Custom cache directory for databases, tokens, and logs`).option(`--tmp, --temp`,`Store cache and databases in system temporary directory`,!1).option(`-y, --yes`,`Skip interactive cache directory prompt and use default .cache`,!1).action(async(e,t)=>{try{let n=l.resolve(t.contentRoot||d.cwd()),r=parseInt(e||t.port||d.env.PORT||`8888`,10),i=t.host||t.ip||d.env.SHADOWCLAW_DEV_IP||`127.0.0.1`,o=t.outDir||`dist/public`,s=l.resolve(n,o),c=await a({contentRoot:n,cacheDir:t.cacheDir,databaseDir:t.databaseDir,tmp:t.tmp||t.temp,yes:t.yes}),u=c.cacheDir,f=c.databaseDir,p=t.static!==!1;p&&!await Z(l.join(s,`index.html`))&&(console.error(`Error: No index.html found in ${s}. Run "shadow-claw build" first.`),d.exit(1));let m=await Z(l.join(J,`dist/server.js`))?l.join(J,`dist/server.js`):l.join(J,`src/server/server.ts`);d.env.SHADOWCLAW_ROOT_PATH=s,d.env.SHADOWCLAW_CACHE_DIR=u,d.env.SHADOWCLAW_DATABASE_DIR=f,d.env.SHADOWCLAW_DEV_IP=i;let{startServer:h}=await import(m),g=new Set((t.corsAllowOrigin||d.env.SHADOWCLAW_CORS_ALLOWED_ORIGINS||`https://xt-ml.github.io`).split(`,`).map(e=>e.trim()).filter(Boolean)),_=!!(t.https||[`1`,`true`,`yes`].includes((d.env.SHADOWCLAW_HTTPS||``).toLowerCase().trim())),v=t.cert||(d.env.SHADOWCLAW_TLS_CERT||d.env.SHADOWCLAW_CERT||``).trim()||void 0,y=t.key||(d.env.SHADOWCLAW_TLS_KEY||d.env.SHADOWCLAW_KEY||``).trim()||void 0,b=l.resolve(n,t.sslDir||d.env.SHADOWCLAW_SSL_DIR||d.env.SHADOWCLAW_TLS_DIR||l.join(u,`tls`));await h({port:r,bindHost:i,corsMode:t.corsMode||`localhost`,allowedOrigins:g,verbose:!!t.verbose,peerjs:!!t.peerjs,rootPath:s,cacheDir:u,databaseDir:f,allowPrivateProxy:!!t.allowPrivateProxy,https:_,certPath:v,keyPath:y,sslDir:b,serveStatic:p});let x=`${_?`https`:`http`}://${i}:${r}`;p&&t.open&&Ee(x)}catch(e){console.error(`Serve error:`,e),d.exit(1)}});async function Oe(e,t){try{let n=l.resolve(t.contentRoot||d.cwd()),r=parseInt(e||t.port||d.env.PORT||`8888`,10),i=t.host||t.ip||d.env.SHADOWCLAW_DEV_IP||`127.0.0.1`,o=await a({contentRoot:n,cacheDir:t.cacheDir,databaseDir:t.databaseDir,tmp:t.tmp||t.temp,yes:t.yes}),s=o.cacheDir,c=o.databaseDir,u=await Z(l.join(J,`dist/server.js`))?l.join(J,`dist/server.js`):l.join(J,`src/server/server.ts`);d.env.SHADOWCLAW_CACHE_DIR=s,d.env.SHADOWCLAW_DATABASE_DIR=c,d.env.SHADOWCLAW_DEV_IP=i,d.env.SHADOWCLAW_SERVE_STATIC=`false`;let{startServer:f}=await import(u),p=new Set((t.corsAllowOrigin||d.env.SHADOWCLAW_CORS_ALLOWED_ORIGINS||`https://xt-ml.github.io`).split(`,`).map(e=>e.trim()).filter(Boolean)),m=!!(t.https||[`1`,`true`,`yes`].includes((d.env.SHADOWCLAW_HTTPS||``).toLowerCase().trim())),h=t.cert||(d.env.SHADOWCLAW_TLS_CERT||d.env.SHADOWCLAW_CERT||``).trim()||void 0,g=t.key||(d.env.SHADOWCLAW_TLS_KEY||d.env.SHADOWCLAW_KEY||``).trim()||void 0,_=l.resolve(n,t.sslDir||d.env.SHADOWCLAW_SSL_DIR||d.env.SHADOWCLAW_TLS_DIR||l.join(s,`tls`));await f({port:r,bindHost:i,corsMode:t.corsMode||`localhost`,allowedOrigins:p,verbose:!!t.verbose,peerjs:!!t.peerjs,rootPath:``,cacheDir:s,databaseDir:c,controlToken:t.controlToken||d.env.SHADOWCLAW_CONTROL_TOKEN||void 0,allowPrivateProxy:!!t.allowPrivateProxy,https:m,certPath:h,keyPath:g,sslDir:_,serveStatic:!1})}catch(e){console.error(`Server error:`,e),d.exit(1)}}Q.command(`server [port]`).aliases([`services`,`api`]).description(`Start backend services (Express, MCP, control plane) without building or serving the UI (aliases: services, api)`).optionsGroup(`Server & Network Options:`).option(`-p, --port <port>`,`Port to listen on (default: 8888)`).option(`--host <host>`,`Bind host/IP`,`127.0.0.1`).option(`--ip <host>`,`Bind host/IP (alias)`).option(`-v, --verbose`,`Enable verbose request/proxy logging`,!1).optionsGroup(`Security & Proxy Options:`).option(`--cors-mode <mode>`,`CORS policy: localhost | private | all`,`localhost`).option(`--cors-allow-origin <origin>`,`Explicit allowed origins (comma-separated)`).option(`--control-token <token>`,`Secret token for control-plane authentication`).option(`--peerjs`,`Enable built-in PeerJS signaling server`,!1).option(`--allow-private-proxy`,`Allow proxy to reach private/loopback addresses`,!1).optionsGroup(`TLS / HTTPS Options:`).option(`--https`,`Enable HTTPS server`,!1).option(`--cert <path>`,`Path to existing TLS certificate file`).option(`--key <path>`,`Path to existing TLS private key file`).option(`--ssl-dir <path>`,`Directory for TLS certificate generation/storage`).optionsGroup(`Storage & Database Options:`).option(`--content-root <dir>`,`Content root directory`,d.cwd()).option(`--database-dir <dir>`,`Directory where SQLite databases are stored`).option(`--cache-dir <dir>`,`Custom cache directory for databases, tokens, and logs`).option(`--tmp, --temp`,`Store cache and databases in system temporary directory`,!1).option(`-y, --yes`,`Skip interactive cache directory prompt and use default .cache`,!1).action(Oe),Q.command(`mcp`).description(`Run the official Stateless Model Context Protocol (MCP 2026-07-28) server`).optionsGroup(`MCP Protocol Options:`).option(`--mcp-transport <transport>`,`MCP transport: stdio | http`,`stdio`).option(`--relay-client-tools`,`Discover and relay tools from connected browser clients`,!0).option(`--no-relay-client-tools`,`Disable relaying browser client tools`).optionsGroup(`Target Client Options:`).option(`--client <id>`,`Target client ID (defaults to first active client)`).optionsGroup(`Control Plane Connection Options:`).option(`--host <host>`,`Control plane host`).option(`--port <port>`,`Control plane port or HTTP MCP port`).option(`--token <token>`,`Control token`).option(`--https`,`Connect to server via HTTPS`,!1).option(`-k, --insecure`,`Allow self-signed TLS certificates`,!0).optionsGroup(`Transport & Peer Options:`).option(`--transport <transport>`,`Control plane client transport: http | webrtc`,`http`).option(`--peer-id <id>`,`Custom WebRTC CLI peer ID`).option(`--cache-dir <dir>`,`Custom cache directory for control token and databases`).action(async e=>{await ue(e)}),Q.commandsGroup(`Control Plane & Client Bridge:`),Q.command(`clients`).description(`List connected / registered browser and Electron clients`).optionsGroup(`Control Plane Connection Options:`).option(`--host <host>`,`Control plane host`).option(`--port <port>`,`Control plane port`).option(`--token <token>`,`Control token`).option(`--https`,`Connect to server via HTTPS`,!1).option(`-k, --insecure`,`Allow self-signed TLS certificates`,!0).optionsGroup(`Transport & Peer Options:`).option(`--transport <transport>`,`Transport to use: http | webrtc`,`http`).option(`--peer-id <id>`,`Custom WebRTC CLI peer ID`).option(`--renew-peer-id`,`Renew WebRTC CLI peer ID before connecting`,!1).option(`--cache-dir <dir>`,`Custom cache directory`).action(async e=>{await ee(e)}),Q.command(`send <message>`).description(`Send a message/prompt to a connected client`).optionsGroup(`Target Options:`).option(`--client <id>`,`Target client ID (defaults to first available)`).option(`--group <groupId>`,`Target conversation group ID`).optionsGroup(`Control Plane Connection Options:`).option(`--host <host>`,`Control plane host`).option(`--port <port>`,`Control plane port`).option(`--token <token>`,`Control token`).option(`--https`,`Connect to server via HTTPS`,!1).option(`-k, --insecure`,`Allow self-signed TLS certificates`,!0).optionsGroup(`Transport & Peer Options:`).option(`--transport <transport>`,`Transport to use: http | webrtc`,`http`).option(`--peer-id <id>`,`Custom WebRTC CLI peer ID`).option(`--renew-peer-id`,`Renew WebRTC CLI peer ID before sending`,!1).option(`--cache-dir <dir>`,`Custom cache directory`).action(async(e,t)=>{await te(e,t)}),Q.command(`tasks`).description(`List scheduled tasks on a connected client`).optionsGroup(`Target Options:`).option(`--client <id>`,`Target client ID`).option(`--group <groupId>`,`Filter tasks by conversation group ID`).optionsGroup(`Control Plane Connection Options:`).option(`--host <host>`,`Control plane host`).option(`--port <port>`,`Control plane port`).option(`--token <token>`,`Control token`).option(`--https`,`Connect to server via HTTPS`,!1).option(`-k, --insecure`,`Allow self-signed TLS certificates`,!0).optionsGroup(`Transport & Peer Options:`).option(`--transport <transport>`,`Transport to use: http | webrtc`,`http`).option(`--peer-id <id>`,`Custom WebRTC CLI peer ID`).option(`--renew-peer-id`,`Renew WebRTC CLI peer ID before connecting`,!1).option(`--cache-dir <dir>`,`Custom cache directory`).action(async e=>{await re(e)}),Q.command(`backup [action]`).description(`Trigger or manage client workspace backups (trigger | list | delete)`).optionsGroup(`Target Options:`).option(`--client <id>`,`Client ID`).option(`--backup-id <id>`,`Backup ID (for delete)`).option(`--group <groupId>`,`Specific workspace group ID`).optionsGroup(`Control Plane Connection Options:`).option(`--host <host>`,`Control plane host`).option(`--port <port>`,`Control plane port`).option(`--token <token>`,`Control token`).option(`--https`,`Connect to server via HTTPS`,!1).option(`-k, --insecure`,`Allow self-signed TLS certificates`,!0).optionsGroup(`Transport & Peer Options:`).option(`--transport <transport>`,`Transport to use: http | webrtc`,`http`).option(`--peer-id <id>`,`Custom WebRTC CLI peer ID`).option(`--renew-peer-id`,`Renew WebRTC CLI peer ID before connecting`,!1).option(`--cache-dir <dir>`,`Custom cache directory`).action(async(e,t)=>{await ne(e||`trigger`,t)}),Q.commandsGroup(`WebRTC:`),Q.command(`webrtc [action] [customId]`).summary(`Manage WebRTC CLI configuration and peer identity (.cache/cli-peer-id)`).description(`Manage WebRTC CLI configuration and peer identity (.cache/cli-peer-id)
32
+ `,`utf8`),n.quiet||d.stdout.write(`Updated default CLI agent model to: ${e}\n`),{success:!0,model:e,configPath:i}}let f=`Unknown model action: "${u}". Available: list, download, set`;return n.quiet||console.error(f),d.exitCode=1,{success:!1,error:f}}async function Se(e,t={}){let n=(e||``).trim();if(!n){let e=`Error: Discovery URL or site URL required. Usage: shadow-claw agent import <url> [options]`;return t.quiet||console.error(e),d.exitCode=1,{success:!1,error:e}}let{db:r,core:i}=await H(t),a=t.group||i.DEFAULT_SERVER_GROUP_ID||W,o=i.fetchDiscoveryManifest||(await import(`./chunk-kcJSXcbq2.js`)).fetchDiscoveryManifest,s=i.importRemoteArtifacts||(await import(`./chunk-Ea7nXmgb2.js`)).importRemoteArtifacts,c=t.fetchFn||globalThis.fetch;t.quiet||console.log(`Fetching discovery manifest from ${n}...`);let l;try{l=await o(n,c)}catch(e){let n=`Failed to fetch discovery manifest: ${e instanceof Error?e.message:String(e)}`;return t.quiet||console.error(`Error: ${n}`),d.exitCode=1,{success:!1,error:n}}let{manifest:u,siteUrl:f,manifestUrl:p}=l,m=u.tools||[],h=u.skills||[],g=u.scripts||[];t.quiet||console.log(`Discovered: ${u.name||`Remote Site`} (${h.length} skill${h.length===1?``:`s`}, ${m.length} tool${m.length===1?``:`s`}, ${g.length} script${g.length===1?``:`s`})`);let _=m.map(e=>e.name),v=h.map(e=>e.name),y=g.map(e=>e.name),b,x,S;if((t.tools||t.skills||t.scripts)&&!t.all){let e=e=>e?Array.isArray(e)?e.map(e=>String(e).trim()).filter(Boolean):String(e).split(`,`).map(e=>e.trim()).filter(Boolean):[];b=e(t.tools),x=e(t.skills),S=e(t.scripts)}else b=_,x=v,S=y;let C=t.autoEnable!==!1,w=!!t.overwrite,T;try{T=await s(r,a,u,{toolNames:b,skillNames:x,scriptNames:S},{autoEnable:C,overwrite:w,fetchFn:c,siteSlug:t.siteSlug,targetSubdir:t.targetSubdir})}catch(e){let n=`Import failed: ${e instanceof Error?e.message:String(e)}`;return t.quiet||console.error(`Error: ${n}`),d.exitCode=1,{success:!1,error:n}}let E=T.tools.filter(e=>e.status===`imported`),D=T.skills.filter(e=>e.status===`imported`),O=T.scripts.filter(e=>e.status===`imported`),k=T.tools.filter(e=>e.status===`skipped`),A=T.skills.filter(e=>e.status===`skipped`),j=T.scripts.filter(e=>e.status===`skipped`),M=T.tools.filter(e=>e.status===`failed`),N=T.skills.filter(e=>e.status===`failed`),P=T.scripts.filter(e=>e.status===`failed`),F=E.length+D.length+O.length,I=k.length+A.length+j.length,L=M.length+N.length+P.length;if(!t.quiet){console.log(`
33
+ Importing artifacts:`);for(let e of[...T.tools,...T.skills,...T.scripts]){let t=T.tools.includes(e)?`tool`:T.skills.includes(e)?`skill`:`script`;e.status===`imported`?console.log(` [${t}] ${e.name} -> ${e.path} (imported)`):e.status===`skipped`?console.log(` [${t}] ${e.name} -> ${e.path} (skipped, already exists - use --overwrite to replace)`):console.log(` [${t}] ${e.name} (failed: ${e.error||`unknown error`})`)}console.log(L>0?`\nCompleted with ${L} error${L===1?``:`s`}. Successfully imported ${F} items, ${I} skipped.`:`\nSuccessfully imported ${F} item${F===1?``:`s`} (${E.length} tool${E.length===1?``:`s`}, ${D.length} skill${D.length===1?``:`s`}, ${O.length} script${O.length===1?``:`s`}).`)}let R=L===0||F>0;return R||(d.exitCode=1),{success:R,manifest:u,siteUrl:f,manifestUrl:p,result:T,importedCount:F,skippedCount:I,failedCount:L}}async function Ce(e,t=[],n={}){let r=t,i=n;if(!Array.isArray(t)&&typeof t==`object`&&(i=t,r=[]),i._stdinData===void 0)try{i={...i,_stdinData:d.stdin.isTTY?null:await de({timeoutMs:500})}}catch{i={...i,_stdinData:null}}switch(e){case`init`:{let e=r[0]||i.workspace,t=await he({...i,workspace:e});return console.log(`Headless agent workspace initialized at: ${t.workspace}`),t}case`skills`:{let e=await ge(i);if(e.skills.length===0)console.log(`No skills found in workspace (.agents/skills/).`);else{console.log(`Available skills (${e.skills.length}):\n`);for(let t of e.skills)console.log(` - ${t.name}: ${t.description||`No description`}`)}return e}case`tools`:{let e=r[0];if(e)return await K(e,r[1],i);let t=await _e(i);console.log(`Available tools (${t.tools.length}):\n`);for(let e of t.tools){let t=e.headlessSafe?`[headless-safe]`:`[browser-only]`;console.log(` - ${e.name.padEnd(25)} ${t} ${e.description||``}`)}return t}case`tool`:{let e=r[0];if(!e){console.error(`Error: Tool name required. Usage: shadow-claw agent tool <name> [input-json]`),d.exitCode=1;return}return await K(e,r[1],i)}case`skill`:{let e=r[0];if(!e){console.error(`Error: Skill name required. Usage: shadow-claw agent skill <name>`),d.exitCode=1;return}return await ve(e,i)}case`run`:return await be(r.join(` `)||`-`,i);case`models`:case`model`:{let e=r[0]||`list`,t=r[1];return await xe(e,t,i)}case`import`:{let e=r[0];return e?await Se(e,i):(console.error(`Error: Discovery URL or site URL required. Usage: shadow-claw agent import <url> [options]`),d.exitCode=1,{success:!1,error:`Discovery URL or site URL required. Usage: shadow-claw agent import <url> [options]`})}default:console.log(`Usage: shadow-claw agent <init|model|skills|tools|tool|skill|import|run> [args...]`)}}const J=t(import.meta.url),Y=new Set;function we(e){return typeof e==`function`?(Y.add(e),()=>Y.delete(e)):()=>!1}let X=!1;const Z=(e,t)=>{X&&d.exit(t),X=!0;for(let t of Y)try{t(e)}catch{}d.stderr.write(`\nProcess interrupted (${e}).\n`),d.exit(t)};d.on(`SIGINT`,()=>Z(`SIGINT`,130)),d.on(`SIGTERM`,()=>Z(`SIGTERM`,143)),d.on(`exit`,()=>{for(let e of Y)try{e(`exit`)}catch{}});async function Te(){try{let e=await h(l.join(J,`package.json`),`utf8`);return JSON.parse(e).version||`1.0.0`}catch{return`1.0.0`}}async function Q(e){try{return await g(e),!0}catch{return!1}}function Ee(e){let t=d.platform===`darwin`?`open`:d.platform===`win32`?`start`:`xdg-open`;try{f(`${t} ${e}`)}catch{}}const De=await Te(),$=new v;$.name(`shadow-claw`).description(`Browser-native personal AI assistant and static site publisher`).version(De,`-v, --version`,`Output the current version`),$.commandsGroup(`Development:`),$.command(`build`).description(`Build the static site bundle for production or staging`).optionsGroup(`Build Mode Options:`).option(`--prod, --production`,`Build in production mode with minification and optimizations`,!1).option(`--prerender-pages <mode>`,`Prerender page mode (all, auto, none)`,`auto`).option(`--copy-all-assets`,`Copy entire assets/ directory into output`,!1).optionsGroup(`Path & Routing Options:`).option(`--origin <url>`,`Canonical origin URL (e.g. https://user.github.io/repo/)`).option(`--base-path <path>`,`URL base path prefix (e.g. /repo/)`).option(`--out-dir <dir>`,`Output directory relative to content root`,`dist/public`).option(`--content-root <dir>`,`Content root directory`,d.cwd()).action(async e=>{try{let t=l.resolve(e.contentRoot||d.cwd()),r=!!(e.prod||e.production||d.env.NODE_ENV===`production`);console.log(`Building ShadowClaw site from ${t}...`),await n({contentRoot:t,toolchainRoot:J,outDir:e.outDir||`dist/public`,isProduction:r,pagesOrigin:e.origin||d.env.PAGES_ORIGIN,basePath:e.basePath||d.env.PAGES_BASE_PATH,prerenderPages:e.prerenderPages,copyAllAssets:e.copyAllAssets})}catch(e){console.error(`Build failed:`,e),d.exit(1)}});async function Oe(e,t){try{let r=l.resolve(t.contentRoot||d.cwd()),i=parseInt(e||t.port||d.env.PORT||`8888`,10),o=t.host||t.ip||d.env.SHADOWCLAW_DEV_IP||`127.0.0.1`,s=t.outDir||`dist/public`,c=l.resolve(r,s),u=await a({contentRoot:r,cacheDir:t.cacheDir,databaseDir:t.databaseDir,tmp:t.tmp||t.temp,yes:t.yes}),f=u.cacheDir,p=u.databaseDir;console.log(`Preparing ShadowClaw dev build for ${r}...`),await n({contentRoot:r,toolchainRoot:J,outDir:s,isProduction:!1,pagesOrigin:t.origin||d.env.PAGES_ORIGIN,basePath:t.basePath||d.env.PAGES_BASE_PATH,prerenderPages:t.prerenderPages||`auto`,copyAllAssets:t.copyAllAssets});let m=await Q(l.join(J,`dist/server.js`))?l.join(J,`dist/server.js`):l.join(J,`src/server/server.ts`);d.env.SHADOWCLAW_ROOT_PATH=c,d.env.SHADOWCLAW_CACHE_DIR=f,d.env.SHADOWCLAW_DATABASE_DIR=p,d.env.SHADOWCLAW_DEV_IP=o;let{startServer:h}=await import(m),g=new Set((t.corsAllowOrigin||d.env.SHADOWCLAW_CORS_ALLOWED_ORIGINS||`https://xt-ml.github.io`).split(`,`).map(e=>e.trim()).filter(Boolean)),_=!!(t.https||[`1`,`true`,`yes`].includes((d.env.SHADOWCLAW_HTTPS||``).toLowerCase().trim())),v=t.cert||(d.env.SHADOWCLAW_TLS_CERT||d.env.SHADOWCLAW_CERT||``).trim()||void 0,y=t.key||(d.env.SHADOWCLAW_TLS_KEY||d.env.SHADOWCLAW_KEY||``).trim()||void 0,b=l.resolve(r,t.sslDir||d.env.SHADOWCLAW_SSL_DIR||d.env.SHADOWCLAW_TLS_DIR||l.join(f,`tls`));await h({port:i,bindHost:o,corsMode:t.corsMode||`localhost`,allowedOrigins:g,verbose:!!t.verbose,peerjs:!!t.peerjs,rootPath:c,cacheDir:f,databaseDir:p,allowPrivateProxy:!!t.allowPrivateProxy,https:_,certPath:v,keyPath:y,sslDir:b});let x=`${_?`https`:`http`}://${o}:${i}`;t.open&&Ee(x)}catch(e){console.error(`Dev server error:`,e),d.exit(1)}}$.command(`dev [port]`).description(`Build and launch the development server`).optionsGroup(`Server & Network Options:`).option(`-p, --port <port>`,`Port to listen on (default: 8888)`).option(`--host <host>`,`Bind host/IP`,`127.0.0.1`).option(`--ip <host>`,`Bind host/IP (alias)`).option(`--open`,`Automatically open default browser`,!1).option(`-v, --verbose`,`Enable verbose request/proxy logging`,!1).optionsGroup(`Site & Build Options:`).option(`--content-root <dir>`,`Content root directory`,d.cwd()).option(`--out-dir <dir>`,`Output directory relative to content root`,`dist/public`).optionsGroup(`Security & Proxy Options:`).option(`--cors-mode <mode>`,`CORS policy: localhost | private | all`,`localhost`).option(`--allow-private-proxy`,`Allow proxy to reach private/loopback addresses`,!1).option(`--peerjs`,`Enable built-in PeerJS signaling server`,!1).optionsGroup(`TLS / HTTPS Options:`).option(`--https`,`Enable HTTPS dev server`,!1).option(`--cert <path>`,`Path to existing TLS certificate file`).option(`--key <path>`,`Path to existing TLS private key file`).option(`--ssl-dir <path>`,`Directory for TLS certificate generation/storage`).optionsGroup(`Storage & Database Options:`).option(`--database-dir <dir>`,`Directory where SQLite databases are stored`).option(`--cache-dir <dir>`,`Custom cache directory for databases, tokens, and logs`).option(`--tmp, --temp`,`Store cache and databases in system temporary directory`,!1).option(`-y, --yes`,`Skip interactive cache directory prompt and use default .cache`,!1).action(Oe),$.command(`run [port]`).description(`Alias for dev: build and launch the development server`).optionsGroup(`Server & Network Options:`).option(`-p, --port <port>`,`Port to listen on (default: 8888)`).option(`--host <host>`,`Bind host/IP`,`127.0.0.1`).option(`--ip <host>`,`Bind host/IP (alias)`).option(`--open`,`Automatically open default browser`,!1).option(`-v, --verbose`,`Enable verbose request/proxy logging`,!1).optionsGroup(`Site & Build Options:`).option(`--content-root <dir>`,`Content root directory`,d.cwd()).option(`--out-dir <dir>`,`Output directory relative to content root`,`dist/public`).optionsGroup(`Security & Proxy Options:`).option(`--cors-mode <mode>`,`CORS policy: localhost | private | all`,`localhost`).option(`--allow-private-proxy`,`Allow proxy to reach private/loopback addresses`,!1).option(`--peerjs`,`Enable built-in PeerJS signaling server`,!1).optionsGroup(`TLS / HTTPS Options:`).option(`--https`,`Enable HTTPS dev server`,!1).option(`--cert <path>`,`Path to existing TLS certificate file`).option(`--key <path>`,`Path to existing TLS private key file`).option(`--ssl-dir <path>`,`Directory for TLS certificate generation/storage`).optionsGroup(`Storage & Database Options:`).option(`--database-dir <dir>`,`Directory where SQLite databases are stored`).option(`--cache-dir <dir>`,`Custom cache directory for databases, tokens, and logs`).option(`--tmp, --temp`,`Store cache and databases in system temporary directory`,!1).option(`-y, --yes`,`Skip interactive cache directory prompt and use default .cache`,!1).action(Oe),$.commandsGroup(`Server:`),$.command(`serve [port]`).description(`Serve an existing static site build and start the backend proxy`).optionsGroup(`Server & Network Options:`).option(`-p, --port <port>`,`Port to listen on (default: 8888)`).option(`--host <host>`,`Bind host/IP`,`127.0.0.1`).option(`--no-static`,`Disable static file and UI serving (services-only mode)`).option(`--open`,`Automatically open default browser`,!1).option(`-v, --verbose`,`Enable verbose request/proxy logging`,!1).optionsGroup(`Site Options:`).option(`--content-root <dir>`,`Content root directory`,d.cwd()).option(`--out-dir <dir>`,`Output directory relative to content root`,`dist/public`).optionsGroup(`Security & Proxy Options:`).option(`--cors-mode <mode>`,`CORS policy: localhost | private | all`,`localhost`).option(`--allow-private-proxy`,`Allow proxy to reach private/loopback addresses`,!1).option(`--peerjs`,`Enable built-in PeerJS signaling server`,!1).optionsGroup(`TLS / HTTPS Options:`).option(`--https`,`Enable HTTPS dev server`,!1).option(`--cert <path>`,`Path to existing TLS certificate file`).option(`--key <path>`,`Path to existing TLS private key file`).option(`--ssl-dir <path>`,`Directory for TLS certificate generation/storage`).optionsGroup(`Storage & Database Options:`).option(`--database-dir <dir>`,`Directory where SQLite databases are stored`).option(`--cache-dir <dir>`,`Custom cache directory for databases, tokens, and logs`).option(`--tmp, --temp`,`Store cache and databases in system temporary directory`,!1).option(`-y, --yes`,`Skip interactive cache directory prompt and use default .cache`,!1).action(async(e,t)=>{try{let n=l.resolve(t.contentRoot||d.cwd()),r=parseInt(e||t.port||d.env.PORT||`8888`,10),i=t.host||t.ip||d.env.SHADOWCLAW_DEV_IP||`127.0.0.1`,o=t.outDir||`dist/public`,s=l.resolve(n,o),c=await a({contentRoot:n,cacheDir:t.cacheDir,databaseDir:t.databaseDir,tmp:t.tmp||t.temp,yes:t.yes}),u=c.cacheDir,f=c.databaseDir,p=t.static!==!1;p&&!await Q(l.join(s,`index.html`))&&(console.error(`Error: No index.html found in ${s}. Run "shadow-claw build" first.`),d.exit(1));let m=await Q(l.join(J,`dist/server.js`))?l.join(J,`dist/server.js`):l.join(J,`src/server/server.ts`);d.env.SHADOWCLAW_ROOT_PATH=s,d.env.SHADOWCLAW_CACHE_DIR=u,d.env.SHADOWCLAW_DATABASE_DIR=f,d.env.SHADOWCLAW_DEV_IP=i;let{startServer:h}=await import(m),g=new Set((t.corsAllowOrigin||d.env.SHADOWCLAW_CORS_ALLOWED_ORIGINS||`https://xt-ml.github.io`).split(`,`).map(e=>e.trim()).filter(Boolean)),_=!!(t.https||[`1`,`true`,`yes`].includes((d.env.SHADOWCLAW_HTTPS||``).toLowerCase().trim())),v=t.cert||(d.env.SHADOWCLAW_TLS_CERT||d.env.SHADOWCLAW_CERT||``).trim()||void 0,y=t.key||(d.env.SHADOWCLAW_TLS_KEY||d.env.SHADOWCLAW_KEY||``).trim()||void 0,b=l.resolve(n,t.sslDir||d.env.SHADOWCLAW_SSL_DIR||d.env.SHADOWCLAW_TLS_DIR||l.join(u,`tls`));await h({port:r,bindHost:i,corsMode:t.corsMode||`localhost`,allowedOrigins:g,verbose:!!t.verbose,peerjs:!!t.peerjs,rootPath:s,cacheDir:u,databaseDir:f,allowPrivateProxy:!!t.allowPrivateProxy,https:_,certPath:v,keyPath:y,sslDir:b,serveStatic:p});let x=`${_?`https`:`http`}://${i}:${r}`;p&&t.open&&Ee(x)}catch(e){console.error(`Serve error:`,e),d.exit(1)}});async function ke(e,t){try{let n=l.resolve(t.contentRoot||d.cwd()),r=parseInt(e||t.port||d.env.PORT||`8888`,10),i=t.host||t.ip||d.env.SHADOWCLAW_DEV_IP||`127.0.0.1`,o=await a({contentRoot:n,cacheDir:t.cacheDir,databaseDir:t.databaseDir,tmp:t.tmp||t.temp,yes:t.yes}),s=o.cacheDir,c=o.databaseDir,u=await Q(l.join(J,`dist/server.js`))?l.join(J,`dist/server.js`):l.join(J,`src/server/server.ts`);d.env.SHADOWCLAW_CACHE_DIR=s,d.env.SHADOWCLAW_DATABASE_DIR=c,d.env.SHADOWCLAW_DEV_IP=i,d.env.SHADOWCLAW_SERVE_STATIC=`false`;let{startServer:f}=await import(u),p=new Set((t.corsAllowOrigin||d.env.SHADOWCLAW_CORS_ALLOWED_ORIGINS||`https://xt-ml.github.io`).split(`,`).map(e=>e.trim()).filter(Boolean)),m=!!(t.https||[`1`,`true`,`yes`].includes((d.env.SHADOWCLAW_HTTPS||``).toLowerCase().trim())),h=t.cert||(d.env.SHADOWCLAW_TLS_CERT||d.env.SHADOWCLAW_CERT||``).trim()||void 0,g=t.key||(d.env.SHADOWCLAW_TLS_KEY||d.env.SHADOWCLAW_KEY||``).trim()||void 0,_=l.resolve(n,t.sslDir||d.env.SHADOWCLAW_SSL_DIR||d.env.SHADOWCLAW_TLS_DIR||l.join(s,`tls`));await f({port:r,bindHost:i,corsMode:t.corsMode||`localhost`,allowedOrigins:p,verbose:!!t.verbose,peerjs:!!t.peerjs,rootPath:``,cacheDir:s,databaseDir:c,controlToken:t.controlToken||d.env.SHADOWCLAW_CONTROL_TOKEN||void 0,allowPrivateProxy:!!t.allowPrivateProxy,https:m,certPath:h,keyPath:g,sslDir:_,serveStatic:!1})}catch(e){console.error(`Server error:`,e),d.exit(1)}}$.command(`server [port]`).aliases([`services`,`api`]).description(`Start backend services (Express, MCP, control plane) without building or serving the UI (aliases: services, api)`).optionsGroup(`Server & Network Options:`).option(`-p, --port <port>`,`Port to listen on (default: 8888)`).option(`--host <host>`,`Bind host/IP`,`127.0.0.1`).option(`--ip <host>`,`Bind host/IP (alias)`).option(`-v, --verbose`,`Enable verbose request/proxy logging`,!1).optionsGroup(`Security & Proxy Options:`).option(`--cors-mode <mode>`,`CORS policy: localhost | private | all`,`localhost`).option(`--cors-allow-origin <origin>`,`Explicit allowed origins (comma-separated)`).option(`--control-token <token>`,`Secret token for control-plane authentication`).option(`--peerjs`,`Enable built-in PeerJS signaling server`,!1).option(`--allow-private-proxy`,`Allow proxy to reach private/loopback addresses`,!1).optionsGroup(`TLS / HTTPS Options:`).option(`--https`,`Enable HTTPS server`,!1).option(`--cert <path>`,`Path to existing TLS certificate file`).option(`--key <path>`,`Path to existing TLS private key file`).option(`--ssl-dir <path>`,`Directory for TLS certificate generation/storage`).optionsGroup(`Storage & Database Options:`).option(`--content-root <dir>`,`Content root directory`,d.cwd()).option(`--database-dir <dir>`,`Directory where SQLite databases are stored`).option(`--cache-dir <dir>`,`Custom cache directory for databases, tokens, and logs`).option(`--tmp, --temp`,`Store cache and databases in system temporary directory`,!1).option(`-y, --yes`,`Skip interactive cache directory prompt and use default .cache`,!1).action(ke),$.command(`mcp`).description(`Run the official Stateless Model Context Protocol (MCP 2026-07-28) server`).optionsGroup(`MCP Protocol Options:`).option(`--mcp-transport <transport>`,`MCP transport: stdio | http`,`stdio`).option(`--relay-client-tools`,`Discover and relay tools from connected browser clients`,!0).option(`--no-relay-client-tools`,`Disable relaying browser client tools`).optionsGroup(`Target Client Options:`).option(`--client <id>`,`Target client ID (defaults to first active client)`).optionsGroup(`Control Plane Connection Options:`).option(`--host <host>`,`Control plane host`).option(`--port <port>`,`Control plane port or HTTP MCP port`).option(`--token <token>`,`Control token`).option(`--https`,`Connect to server via HTTPS`,!1).option(`-k, --insecure`,`Allow self-signed TLS certificates`,!0).optionsGroup(`Transport & Peer Options:`).option(`--transport <transport>`,`Control plane client transport: http | webrtc`,`http`).option(`--peer-id <id>`,`Custom WebRTC CLI peer ID`).option(`--cache-dir <dir>`,`Custom cache directory for control token and databases`).action(async e=>{await ue(e)}),$.commandsGroup(`Control Plane & Client Bridge:`),$.command(`clients`).description(`List connected / registered browser and Electron clients`).optionsGroup(`Control Plane Connection Options:`).option(`--host <host>`,`Control plane host`).option(`--port <port>`,`Control plane port`).option(`--token <token>`,`Control token`).option(`--https`,`Connect to server via HTTPS`,!1).option(`-k, --insecure`,`Allow self-signed TLS certificates`,!0).optionsGroup(`Transport & Peer Options:`).option(`--transport <transport>`,`Transport to use: http | webrtc`,`http`).option(`--peer-id <id>`,`Custom WebRTC CLI peer ID`).option(`--renew-peer-id`,`Renew WebRTC CLI peer ID before connecting`,!1).option(`--cache-dir <dir>`,`Custom cache directory`).action(async e=>{await ee(e)}),$.command(`send <message>`).description(`Send a message/prompt to a connected client`).optionsGroup(`Target Options:`).option(`--client <id>`,`Target client ID (defaults to first available)`).option(`--group <groupId>`,`Target conversation group ID`).optionsGroup(`Control Plane Connection Options:`).option(`--host <host>`,`Control plane host`).option(`--port <port>`,`Control plane port`).option(`--token <token>`,`Control token`).option(`--https`,`Connect to server via HTTPS`,!1).option(`-k, --insecure`,`Allow self-signed TLS certificates`,!0).optionsGroup(`Transport & Peer Options:`).option(`--transport <transport>`,`Transport to use: http | webrtc`,`http`).option(`--peer-id <id>`,`Custom WebRTC CLI peer ID`).option(`--renew-peer-id`,`Renew WebRTC CLI peer ID before sending`,!1).option(`--cache-dir <dir>`,`Custom cache directory`).action(async(e,t)=>{await te(e,t)}),$.command(`tasks`).description(`List scheduled tasks on a connected client`).optionsGroup(`Target Options:`).option(`--client <id>`,`Target client ID`).option(`--group <groupId>`,`Filter tasks by conversation group ID`).optionsGroup(`Control Plane Connection Options:`).option(`--host <host>`,`Control plane host`).option(`--port <port>`,`Control plane port`).option(`--token <token>`,`Control token`).option(`--https`,`Connect to server via HTTPS`,!1).option(`-k, --insecure`,`Allow self-signed TLS certificates`,!0).optionsGroup(`Transport & Peer Options:`).option(`--transport <transport>`,`Transport to use: http | webrtc`,`http`).option(`--peer-id <id>`,`Custom WebRTC CLI peer ID`).option(`--renew-peer-id`,`Renew WebRTC CLI peer ID before connecting`,!1).option(`--cache-dir <dir>`,`Custom cache directory`).action(async e=>{await re(e)}),$.command(`backup [action]`).description(`Trigger or manage client workspace backups (trigger | list | delete)`).optionsGroup(`Target Options:`).option(`--client <id>`,`Client ID`).option(`--backup-id <id>`,`Backup ID (for delete)`).option(`--group <groupId>`,`Specific workspace group ID`).optionsGroup(`Control Plane Connection Options:`).option(`--host <host>`,`Control plane host`).option(`--port <port>`,`Control plane port`).option(`--token <token>`,`Control token`).option(`--https`,`Connect to server via HTTPS`,!1).option(`-k, --insecure`,`Allow self-signed TLS certificates`,!0).optionsGroup(`Transport & Peer Options:`).option(`--transport <transport>`,`Transport to use: http | webrtc`,`http`).option(`--peer-id <id>`,`Custom WebRTC CLI peer ID`).option(`--renew-peer-id`,`Renew WebRTC CLI peer ID before connecting`,!1).option(`--cache-dir <dir>`,`Custom cache directory`).action(async(e,t)=>{await ne(e||`trigger`,t)}),$.commandsGroup(`WebRTC:`),$.command(`webrtc [action] [customId]`).summary(`Manage WebRTC CLI configuration and peer identity (.cache/cli-peer-id)`).description(`Manage WebRTC CLI configuration and peer identity (.cache/cli-peer-id)
33
34
 
34
35
  Actions:
35
36
  (default) Show or generate the CLI peer ID
36
37
  listen Register as a live PeerJS peer — browser tabs can then
37
- connect directly without a control-plane connection`).optionsGroup(`Identity Options:`).option(`-r, --renew`,`Force renewal / generation of a new WebRTC CLI peer ID`).option(`--set <id>`,`Set a specific custom WebRTC CLI peer ID`).option(`--cache-dir <dir>`,`Custom cache directory (defaults to .cache)`).option(`-q, --quiet`,`Output only the peer ID string`).option(`--json`,`Output peer ID and file path as JSON`).optionsGroup(`Signaling & Listener Options (for listen action):`).option(`--host <host>`,`PeerJS signaling server host (for listen)`).option(`--port <port>`,`PeerJS signaling server port (for listen)`,`8888`).option(`--path <path>`,`PeerJS signaling server path (for listen)`,`/`).option(`--secure`,`Use TLS (wss://) for the signaling server (for listen)`,!1).option(`--https`,`Alias for --secure: use TLS (wss://) for the signaling server`,!1).option(`--trusted-peer <id>`,`Accept connections only from this peer ID (repeatable, for listen)`,(e,t)=>t?[...t,e]:[e],[]).option(`--verbose`,`Verbose connection logging (for listen)`,!1).option(`--renew-peer-id`,`Renew CLI peer ID before listening`,!1).option(`-k, --insecure`,`Allow self-signed TLS certificates for the signaling server (wss://)`,!0).action(async(e,t,n)=>{if(e===`listen`){await ae(n);return}let r={...n};t&&!r.set&&(r.set=t),await z(e,r)}),Q.command(`peer-id [action] [customId]`).alias(`webrtc-peer-id`).description(`Get, generate, or renew the WebRTC CLI peer ID stored in .cache/cli-peer-id`).optionsGroup(`Identity Options:`).option(`-r, --renew`,`Force renewal / generation of a new WebRTC CLI peer ID`).option(`--set <id>`,`Set a specific custom WebRTC CLI peer ID`).option(`--cache-dir <dir>`,`Custom cache directory (defaults to .cache)`).option(`-q, --quiet`,`Output only the peer ID string`).option(`--json`,`Output peer ID and file path as JSON`).action(async(e,t,n)=>{let r={...n};t&&!r.set&&(r.set=t),await z(e,r)}),Q.commandsGroup(`Project:`),Q.command(`init [dir]`).description(`Initialize a new ShadowClaw content template in the specified directory`).action(async e=>{try{let t=l.resolve(e||d.cwd());await m(l.join(t,`pages/main`),{recursive:!0});let n=l.join(t,`shadow-claw-config.json`),r=l.join(t,`shadow-claw.config.json`),i=l.join(t,`site-config.json`);!await Z(n)&&!await Z(r)&&!await Z(i)&&(await _(n,JSON.stringify({$schema:`https://json-schema.org/draft/2020-12/schema`,site:{title:`My ShadowClaw Site`,description:`Personal AI assistant and knowledge hub powered by ShadowClaw.`},branding:{titleText:`My ShadowClaw Site`},pages:{sortOrder:`asc`,defaultPinnedPage:`/pages/main/index.html`}},null,2)+`
38
- `,`utf8`),console.log(`Created ${n}`));let a=l.join(t,`pages/main/index.html`);await Z(a)||(await _(a,`---
38
+ connect directly without a control-plane connection`).optionsGroup(`Identity Options:`).option(`-r, --renew`,`Force renewal / generation of a new WebRTC CLI peer ID`).option(`--set <id>`,`Set a specific custom WebRTC CLI peer ID`).option(`--cache-dir <dir>`,`Custom cache directory (defaults to .cache)`).option(`-q, --quiet`,`Output only the peer ID string`).option(`--json`,`Output peer ID and file path as JSON`).optionsGroup(`Signaling & Listener Options (for listen action):`).option(`--host <host>`,`PeerJS signaling server host (for listen)`).option(`--port <port>`,`PeerJS signaling server port (for listen)`,`8888`).option(`--path <path>`,`PeerJS signaling server path (for listen)`,`/`).option(`--secure`,`Use TLS (wss://) for the signaling server (for listen)`,!1).option(`--https`,`Alias for --secure: use TLS (wss://) for the signaling server`,!1).option(`--trusted-peer <id>`,`Accept connections only from this peer ID (repeatable, for listen)`,(e,t)=>t?[...t,e]:[e],[]).option(`--verbose`,`Verbose connection logging (for listen)`,!1).option(`--renew-peer-id`,`Renew CLI peer ID before listening`,!1).option(`-k, --insecure`,`Allow self-signed TLS certificates for the signaling server (wss://)`,!0).action(async(e,t,n)=>{if(e===`listen`){await ae(n);return}let r={...n};t&&!r.set&&(r.set=t),await z(e,r)}),$.command(`peer-id [action] [customId]`).alias(`webrtc-peer-id`).description(`Get, generate, or renew the WebRTC CLI peer ID stored in .cache/cli-peer-id`).optionsGroup(`Identity Options:`).option(`-r, --renew`,`Force renewal / generation of a new WebRTC CLI peer ID`).option(`--set <id>`,`Set a specific custom WebRTC CLI peer ID`).option(`--cache-dir <dir>`,`Custom cache directory (defaults to .cache)`).option(`-q, --quiet`,`Output only the peer ID string`).option(`--json`,`Output peer ID and file path as JSON`).action(async(e,t,n)=>{let r={...n};t&&!r.set&&(r.set=t),await z(e,r)}),$.commandsGroup(`Project:`),$.command(`init [dir]`).description(`Initialize a new ShadowClaw content template in the specified directory`).action(async e=>{try{let t=l.resolve(e||d.cwd());await m(l.join(t,`pages/main`),{recursive:!0});let n=l.join(t,`shadow-claw-config.json`),r=l.join(t,`shadow-claw.config.json`),i=l.join(t,`site-config.json`);!await Q(n)&&!await Q(r)&&!await Q(i)&&(await _(n,JSON.stringify({$schema:`https://json-schema.org/draft/2020-12/schema`,site:{title:`My ShadowClaw Site`,description:`Personal AI assistant and knowledge hub powered by ShadowClaw.`},branding:{titleText:`My ShadowClaw Site`},pages:{sortOrder:`asc`,defaultPinnedPage:`/pages/main/index.html`}},null,2)+`
39
+ `,`utf8`),console.log(`Created ${n}`));let a=l.join(t,`pages/main/index.html`);await Q(a)||(await _(a,`---
39
40
  title: "Welcome to ShadowClaw"
40
41
  created: "${new Date().toISOString()}"
41
42
  updated: "${new Date().toISOString()}"
@@ -46,8 +47,8 @@ slug: "home"
46
47
  <h1>Welcome to ShadowClaw</h1>
47
48
  <p>Your browser-native personal AI assistant and static site publisher.</p>
48
49
  </article>
49
- `,`utf8`),console.log(`Created ${a}`));let o=l.join(t,`.gitignore`);await Z(o)||(await _(o,`dist/
50
+ `,`utf8`),console.log(`Created ${a}`));let o=l.join(t,`.gitignore`);await Q(o)||(await _(o,`dist/
50
51
  .cache/
51
52
  node_modules/
52
53
  `,`utf8`),console.log(`Created ${o}`)),console.log(`\nShadowClaw template successfully initialized in ${t}`),console.log(`To start developing, run:`),console.log(` npx shadow-claw dev
53
- `)}catch(e){console.error(`Init failed:`,e),d.exit(1)}}),Q.command(`skills:index [dir]`).alias(`agent-skills`).description(`Generate or update .well-known/agent-skills/index.json per the Agent Skills Discovery RFC`).optionsGroup(`Output & Path Options:`).option(`--out-dir <dir>`,`Output directory relative to content root (default: .well-known/agent-skills)`).option(`--out-file <file>`,`Explicit destination path for index.json`).option(`--metadata-root <dir>`,`Directory to read site metadata from (default: content root)`).option(`--config <file>`,`Explicit path to shadow-claw.config.json or site-config.json`).optionsGroup(`Generation Options:`).option(`--no-bundled`,`Exclude bundled ShadowClaw skills from index`).option(`--stdout`,`Print generated index.json to stdout`,!1).option(`--no-write`,`Skip writing file to disk`).action(async(e,t)=>{try{await i(e,t)}catch(e){console.error(`Failed to generate skills index:`,e),d.exit(1)}}),Q.commandsGroup(`Headless Agent:`),Q.command(`agent [action] [args...]`).description(`Run the headless CLI agent (init | model | skills | tools | tool | skill | run)`).optionsGroup(`Agent Options:`).option(`--workspace <dir>`,`Workspace directory (default: .cache)`).option(`--database-dir <dir>`,`Directory where SQLite databases are stored`).option(`--cache-dir <dir>`,`Custom cache directory for databases and logs`).option(`--tmp, --temp`,`Store cache, token, and databases in OS temporary directory`).option(`-y, --yes`,`Skip interactive cache directory prompt and accept defaults`).option(`--group <groupId>`,`Conversation group ID`,`server:main`).option(`--provider <provider>`,`LLM provider ID`).option(`--model <model>`,`Model name`).option(`--download`,`Prewarm and download the model during agent init or execution`,!1).option(`--api-key <key>`,`API key`).option(`-v, --verbose`,`Enable verbose execution logging`,!1).option(`-o, --output <file>`,`Write command output to a file instead of stdout`).option(`--stream`,`Stream response tokens to stdout as they arrive (default: true)`,!0).option(`--no-stream`,`Disable streaming response tokens to stdout`).option(`--progress`,`Show progress bar during model downloads (default: true)`,!0).option(`--no-progress`,`Disable download progress bar`).option(`--system-prompt <text>`,`Override system prompt with inline text`).option(`--system-prompt-file <file>`,`Load system prompt from a text or markdown file`).option(`--tools <tools>`,`Comma-separated list of tools to enable (e.g. bash,read_file)`).option(`--tools-profile <name>`,`Tools profile to activate (e.g. __builtin_default)`).option(`-r, --remote`,`List or search available models from Hugging Face onnx-community repository`,!1).option(`--huggingface, --hf`,`Alias for --remote to query Hugging Face`,!1).option(`--query <query>`,`Filter models by search query`).option(`-q, --quiet`,`Suppress all non-error output`,!1).action(async(e,t,n)=>{await Se(e,t,n)}),Q.commandsGroup(`Help & Utility:`),Q.helpCommand(`help [command]`,`display help for command`);async function ke(e=d.argv){await Q.parseAsync(e)}export{ke as main,Q as program,Ce as registerTerminationCleanup};
54
+ `)}catch(e){console.error(`Init failed:`,e),d.exit(1)}}),$.command(`skills:index [dir]`).alias(`agent-skills`).description(`Generate or update .well-known/agent-skills/index.json per the Agent Skills Discovery RFC`).optionsGroup(`Output & Path Options:`).option(`--out-dir <dir>`,`Output directory relative to content root (default: .well-known/agent-skills)`).option(`--out-file <file>`,`Explicit destination path for index.json`).option(`--metadata-root <dir>`,`Directory to read site metadata from (default: content root)`).option(`--config <file>`,`Explicit path to shadow-claw.config.json or site-config.json`).optionsGroup(`Generation Options:`).option(`--no-bundled`,`Exclude bundled ShadowClaw skills from index`).option(`--stdout`,`Print generated index.json to stdout`,!1).option(`--no-write`,`Skip writing file to disk`).action(async(e,t)=>{try{await i(e,t)}catch(e){console.error(`Failed to generate skills index:`,e),d.exit(1)}}),$.commandsGroup(`Headless Agent:`),$.command(`agent [action] [args...]`).description(`Run the headless CLI agent (init | model | skills | tools | tool | skill | import | run)`).optionsGroup(`Agent Options:`).option(`--workspace <dir>`,`Workspace directory (default: .cache)`).option(`--database-dir <dir>`,`Directory where SQLite databases are stored`).option(`--cache-dir <dir>`,`Custom cache directory for databases and logs`).option(`--tmp, --temp`,`Store cache, token, and databases in OS temporary directory`).option(`-y, --yes`,`Skip interactive cache directory prompt and accept defaults`).option(`--group <groupId>`,`Conversation group ID`,`server:main`).option(`--provider <provider>`,`LLM provider ID`).option(`--model <model>`,`Model name`).option(`--download`,`Prewarm and download the model during agent init or execution`,!1).option(`--api-key <key>`,`API key`).option(`-v, --verbose`,`Enable verbose execution logging`,!1).option(`-o, --output <file>`,`Write command output to a file instead of stdout`).option(`--stream`,`Stream response tokens to stdout as they arrive (default: true)`,!0).option(`--no-stream`,`Disable streaming response tokens to stdout`).option(`--progress`,`Show progress bar during model downloads (default: true)`,!0).option(`--no-progress`,`Disable download progress bar`).option(`--system-prompt <text>`,`Override system prompt with inline text`).option(`--system-prompt-file <file>`,`Load system prompt from a text or markdown file`).option(`--tools <tools>`,`Comma-separated list of tools to enable or import (e.g. bash,read_file)`).option(`--skills <skills>`,`Comma-separated list of skills to filter or import`).option(`--scripts <scripts>`,`Comma-separated list of scripts to import`).option(`--all`,`Import all tools, skills, and scripts from discovery manifest`,!1).option(`--overwrite`,`Overwrite existing skills, tools, or scripts during import`,!1).option(`--auto-enable`,`Automatically enable imported declarative tools (default: true)`,!0).option(`--no-auto-enable`,`Do not automatically enable imported declarative tools`).option(`--tools-profile <name>`,`Tools profile to activate (e.g. __builtin_default)`).option(`-r, --remote`,`List or search available models from Hugging Face onnx-community repository`,!1).option(`--huggingface, --hf`,`Alias for --remote to query Hugging Face`,!1).option(`--query <query>`,`Filter models by search query`).option(`-q, --quiet`,`Suppress all non-error output`,!1).action(async(e,t,n)=>{await Ce(e,t,n)}),$.commandsGroup(`Help & Utility:`),$.helpCommand(`help [command]`,`display help for command`);async function Ae(e=d.argv){await $.parseAsync(e)}export{Ae as main,$ as program,we as registerTerminationCleanup};