shadow-claw 1.52.0 → 1.52.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/.well-known/mcp/server-card.json +1 -1
  2. package/.well-known/mcp.json +1 -1
  3. package/README.md +9 -9
  4. package/dist/cli/build/build.js +1 -1
  5. package/dist/cli/{chunk-DYq-orHK.js → chunk-BgTv9w0K.js} +1 -1
  6. package/dist/cli/{chunk-C6jii2Fl.js → chunk-d5hIhj8t.js} +1 -1
  7. package/dist/cli/cli.js +1 -1
  8. package/dist/lib/components/index.js +1 -1
  9. package/dist/lib/components/shadow-claw-pages.js +1 -1
  10. package/dist/lib/index.js +1 -1
  11. package/dist/lib/{shadow-claw-pages-kA2qa-4B.js → shadow-claw-pages-CjHS50HN.js} +2 -2
  12. package/dist/lib/{shadow-claw-pages-kA2qa-4B.js.map → shadow-claw-pages-CjHS50HN.js.map} +1 -1
  13. package/dist/public/.well-known/mcp/server-card.json +1 -1
  14. package/dist/public/.well-known/mcp.json +1 -1
  15. package/dist/public/AGENTS.md +1 -1
  16. package/dist/public/README.md +9 -9
  17. package/dist/public/docs/README.md +1 -1
  18. package/dist/public/docs/architecture/orchestrator.md +2 -2
  19. package/dist/public/docs/architecture/overview.md +3 -3
  20. package/dist/public/docs/architecture/worker-protocol.md +29 -29
  21. package/dist/public/docs/example/article/index.html +1 -1
  22. package/dist/public/docs/example/article.html +1 -1
  23. package/dist/public/docs/publishing/index.html +1 -1
  24. package/dist/public/docs/publishing.html +1 -1
  25. package/dist/public/docs/skill-creator/index.html +1 -1
  26. package/dist/public/docs/skill-creator.html +1 -1
  27. package/dist/public/docs/subsystems/local-models.md +1 -1
  28. package/dist/public/docs/subsystems/providers.md +11 -4
  29. package/dist/public/e2e/README.md +2 -2
  30. package/dist/public/index.html +1 -1
  31. package/dist/public/index.js +1 -1
  32. package/dist/public/llms.txt +1 -1
  33. package/dist/public/main/index.html +1 -1
  34. package/dist/public/main/memory/index.html +1 -1
  35. package/dist/public/main/memory.html +1 -1
  36. package/dist/public/main.html +1 -1
  37. package/dist/public/service-worker.js +1 -1
  38. package/dist/public/{shadow-claw-Ba2ZFE9m.js → shadow-claw-T9oPpqxT.js} +1 -1
  39. package/dist/public/{shadow-claw-pages-Cy6T0G9y.js → shadow-claw-pages-IW_LNEL_.js} +1 -1
  40. package/package.json +1 -1
  41. package/src/cli/build/build.test.ts +95 -0
  42. package/src/cli/build/build.ts +5 -1
  43. package/src/cli/commands/agent.test.ts +134 -0
  44. package/src/cli/commands/backup.test.ts +85 -0
  45. package/src/cli/commands/clients.test.ts +32 -0
  46. package/src/cli/commands/mcp.test.ts +260 -1
  47. package/src/cli/commands/send-file.test.ts +73 -0
  48. package/src/cli/commands/send.test.ts +58 -0
  49. package/src/cli/commands/tasks.test.ts +78 -0
  50. package/src/cli/commands/webrtc-listen.test.ts +74 -0
  51. package/src/cli/tools/assert-version-bump.test.ts +30 -1
  52. package/src/cli/tools/file-search-replace.test.ts +33 -1
  53. package/src/cli/tools/patch-service-worker-trusted-types.test.ts +24 -1
  54. package/src/cli/tools/touch-nojekyll.test.ts +12 -0
  55. package/src/cli/tools/version.test.ts +109 -5
  56. package/src/cli/utils/agent-core.test.ts +40 -0
  57. package/src/cli/utils/control-client.test.ts +239 -2
  58. package/src/cli/utils/load-workspace-config.test.ts +63 -0
  59. package/src/cli/utils/local-models.test.ts +98 -0
  60. package/src/cli/utils/progress-bar.test.ts +41 -2
  61. package/src/cli/utils/resolve-cache-dir.test.ts +61 -0
  62. package/src/cli/utils/resolve-project-root.test.ts +17 -0
  63. package/src/cli/utils/stdin.test.ts +38 -0
  64. package/src/cli/utils/stdio.test.ts +51 -1
  65. package/src/cli/utils/suppress-warnings.test.ts +9 -0
  66. package/src/cli/utils/webrtc-control-client.test.ts +569 -0
  67. package/src/common/utils/frontmatter.test.ts +117 -0
  68. package/src/components/common/help/providers.test.ts +67 -0
  69. package/src/components/common/shadow-claw-provider-model-picker/shadow-claw-provider-model-picker.test.ts +121 -0
  70. package/src/components/settings/shadow-claw-accounts/shadow-claw-accounts.test.ts +131 -0
  71. package/src/components/settings/shadow-claw-git/shadow-claw-git.test.ts +130 -0
  72. package/src/components/settings/shadow-claw-integrations/connection-test-auth.test.ts +12 -0
  73. package/src/components/settings/shadow-claw-integrations/shadow-claw-integrations.test.ts +328 -0
  74. package/src/components/settings/shadow-claw-llm/shadow-claw-llm.test.ts +530 -8
  75. package/src/components/settings/shadow-claw-mcp-remote/shadow-claw-mcp-remote.test.ts +459 -0
  76. package/src/components/settings/shadow-claw-networking/shadow-claw-networking.test.ts +88 -0
  77. package/src/components/settings/shadow-claw-notifications/shadow-claw-notifications.test.ts +92 -0
  78. package/src/components/settings/shadow-claw-peerjs/shadow-claw-peerjs.test.ts +127 -0
  79. package/src/components/settings/shadow-claw-storage/shadow-claw-storage.test.ts +173 -0
  80. package/src/components/settings/shadow-claw-task-server/shadow-claw-task-server.test.ts +62 -0
  81. package/src/components/settings/shadow-claw-webvm/shadow-claw-webvm.test.ts +104 -0
  82. package/src/components/shadow-claw/shadow-claw.test.ts +112 -0
  83. package/src/components/shadow-claw-a2ui/shadow-claw-a2ui.test.ts +109 -0
  84. package/src/components/shadow-claw-conversations/shadow-claw-conversations.test.ts +361 -0
  85. package/src/components/shadow-claw-dialog/shadow-claw-dialog.test.ts +76 -0
  86. package/src/components/shadow-claw-file-viewer/shadow-claw-file-viewer.test.ts +307 -0
  87. package/src/components/shadow-claw-files/shadow-claw-files.test.ts +398 -1
  88. package/src/components/shadow-claw-pages/shadow-claw-pages.test.ts +85 -0
  89. package/src/components/shadow-claw-pages/shadow-claw-pages.ts +2 -1
  90. package/src/components/shadow-claw-pdf-viewer/shadow-claw-pdf-viewer.test.ts +229 -0
  91. package/src/components/shadow-claw-settings/shadow-claw-settings.test.ts +233 -0
  92. package/src/components/shadow-claw-tasks/shadow-claw-tasks.test.ts +223 -1
  93. package/src/components/shadow-claw-toast/shadow-claw-toast.test.ts +79 -0
  94. package/src/components/shadow-claw-tools/shadow-claw-tools.test.ts +229 -1
  95. package/src/server/logger.test.ts +57 -0
  96. package/src/server/peer.test.ts +47 -0
  97. package/src/server/routes/gemini.test.ts +244 -0
  98. package/src/server/server-peer.test.ts +245 -11
  99. package/src/server/services/llamafile-manager.test.ts +668 -0
  100. package/src/share-target/pending-shares.test.ts +90 -0
  101. package/src/shell/fs.test.ts +125 -0
  102. package/src/shell/shell.test.ts +8 -0
  103. package/src/subsystems/git/credentials.test.ts +260 -0
  104. package/src/subsystems/git/git.test.ts +64 -0
  105. package/src/subsystems/providers/executeNativeAiTask.test.ts +78 -0
  106. package/src/subsystems/providers/utils/parseLocalModelToolCall.test.ts +57 -0
  107. package/src/worker/tools/builtin-ai/builtin-ai.test.ts +88 -0
  108. package/src/worker/tools/email/email.test.ts +358 -0
  109. package/src/worker/tools/email/utils/resolveIntegrationEmailAuth.test.ts +120 -0
  110. package/src/worker/tools/email/utils/resolveUniqueAttachmentPath.test.ts +80 -0
  111. package/src/worker/tools/fetch-file/fetch-file.test.ts +111 -0
  112. package/src/worker/tools/fetch-url/fetch-url.test.ts +295 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://modelcontextprotocol.io/schemas/server-card/v1.json",
3
3
  "name": "shadow-claw",
4
- "version": "1.52.0",
4
+ "version": "1.52.1",
5
5
  "description": "Multi-runtime AI assistant with local and remote LLM orchestration, Web Workers, OPFS storage, and agentic tool execution.",
6
6
  "title": "ShadowClaw MCP Server",
7
7
  "websiteUrl": "https://xt-ml.github.io/shadow-claw/",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://modelcontextprotocol.io/schemas/server-card/v1.json",
3
3
  "name": "shadow-claw",
4
- "version": "1.52.0",
4
+ "version": "1.52.1",
5
5
  "description": "Multi-runtime AI assistant with local and remote LLM orchestration, Web Workers, OPFS storage, and agentic tool execution.",
6
6
  "title": "ShadowClaw MCP Server",
7
7
  "websiteUrl": "https://xt-ml.github.io/shadow-claw/",
package/README.md CHANGED
@@ -38,7 +38,7 @@ For external AI hosts, ShadowClaw provides multiple ways to interact with the br
38
38
  npx shadow-claw dev --open
39
39
  ```
40
40
 
41
- Open Settings, configure your preferred provider (or run with the default OpenRouter or Prompt API), and start chatting.
41
+ Open Settings, configure your preferred provider (or run with the default Transformers.js or OpenRouter), and start chatting.
42
42
 
43
43
  ### 2. Run Headless Server-Side Agent directly from Terminal
44
44
 
@@ -201,11 +201,11 @@ Last-active conversation persists across reloads. On first launch, a default "Ma
201
201
 
202
202
  ShadowClaw supports multiple LLM providers with a unified adapter pattern and configurable defaults:
203
203
 
204
- | Category | Examples | Notes |
205
- | :---------- | :------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------- |
206
- | **Cloud** | OpenRouter, OpenAI, Anthropic, Google Gemini, AWS Bedrock, Vertex AI | Defaults out-of-the-box to OpenRouter (`openrouter/free`); API key required |
207
- | **Local** | Ollama, Llamafile, Agentfile, Mesh LLM, Transformers.js | Runs on local server or in-process; automatic Hugging Face model downloading & LocalBinaryDriver execution |
208
- | **Browser** | Prompt API (`window.LanguageModel`), LiteRT | WebGPU in-browser inference with transparent CPU/WASM polyfills |
204
+ | Category | Examples | Notes |
205
+ | :---------- | :--------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------- |
206
+ | **Cloud** | OpenRouter, OpenAI, Anthropic, Google Gemini, AWS Bedrock, Vertex AI | Defaults out-of-the-box to OpenRouter (`openrouter/free`); API key required |
207
+ | **Local** | Ollama, Llamafile, Agentfile, Mesh LLM, Transformers.js | Runs on local server or in-process; automatic Hugging Face model downloading & LocalBinaryDriver execution |
208
+ | **Browser** | Transformers.js (Browser), Prompt API (`window.LanguageModel`), LiteRT | Defaults out-of-the-box to Transformers.js (`onnx-community/Qwen3-0.6B-ONNX`); in-browser WebGPU inference with transparent CPU/WASM fallback |
209
209
 
210
210
  **Provider & Model Hierarchy:**
211
211
 
@@ -215,14 +215,14 @@ ShadowClaw resolves default LLM providers and models via a strict precedence cas
215
215
  2. **Environment Variable:** `SHADOW_CLAW_PROVIDER` / `SHADOW_CLAW_MODEL` (or provider-specific keys like `OPENROUTER_API_KEY`, `HUGGINGFACE_API_KEY`, `GEMINI_API_KEY`, `ANTHROPIC_API_KEY`)
216
216
  3. **Database Configuration:** `CONFIG_KEYS.PROVIDER` / `CONFIG_KEYS.MODEL`
217
217
  4. **Declarative Workspace Config:** `settings.defaultProvider` and `settings.defaultModel` in `shadow-claw.config.json`
218
- 5. **Default Fallback:** Defaults to Prompt API (`prompt_api`) in browser contexts (with onboarding dialog and task API polyfills), and OpenRouter (`openrouter` with model `openrouter/free`) for headless CLI agent execution.
218
+ 5. **Default Fallback:** Defaults to Transformers.js (`transformers_js_browser` with model `onnx-community/Qwen3-0.6B-ONNX`) in browser contexts (with guided onboarding), and OpenRouter (`openrouter` with model `openrouter/free`) for headless CLI agent execution.
219
219
 
220
220
  **Provider Highlights:**
221
221
 
222
- - **In-Browser Inference Default:** Defaults to Prompt API (`prompt_api`) with guided onboarding and task API polyfills, enabling local, private, and zero-configuration browser execution.
222
+ - **In-Browser Inference Default:** Defaults to Transformers.js (`transformers_js_browser`) with model `onnx-community/Qwen3-0.6B-ONNX` and guided onboarding, enabling private, local, zero-configuration in-browser execution with WebGPU acceleration and transparent CPU/WASM fallback.
223
223
  - **OpenRouter Default for Headless CLI:** Headless execution via `shadow-claw agent` defaults out-of-the-box to `openrouter` with `openrouter/free`.
224
224
  - **Local Models & Hugging Face Hub:** Automatic on-demand downloading from Hugging Face Hub, disk caching under `assets/cache/transformers.js` (and `assets/cache/llamafile` for Llamafile/Agentfile binaries), interactive paginated and searchable model browsing during `agent init`, and pre-warming endpoints (`POST /transformers-js-proxy/prewarm`). Unified local model tool calling (`parseLocalModelToolCalls`) supports multi-tool calling, Gemma 4 syntax, streaming tool-call suppression, and defensive schema sanitization across in-process Node executors and server proxy routes using OpenAI function schemas formatted directly for tokenizer chat templates. The `LocalBinaryDriver` architecture supports `.llamafile` and `.agentfile` execution with built-in tool schema catalogs and proxy forwarding. See [Local Models Guide](docs/subsystems/local-models.md).
225
- - **Prompt API & Polyfill Fallbacks:** In the browser client, uses native `window.LanguageModel` when available, with automatic degradation to local Transformers.js via `prompt-api-polyfill` and `built-in-ai-task-apis-polyfills` when the native Prompt API is unavailable.
225
+ - **Prompt API & Polyfill Fallbacks:** When Prompt API (`prompt_api`) is manually selected in the browser client, uses native `window.LanguageModel` when available, with automatic degradation to local Transformers.js via `prompt-api-polyfill` and `built-in-ai-task-apis-polyfills` when the native Prompt API is unavailable.
226
226
  - **Hardware Feature Probing & Fallbacks:** Probes WebGPU adapter capabilities (`shader-f16`), retries during downloads, and dynamically falls back to WebAssembly CPU (`device: "wasm"`, `dtype: "q4"`) if WebGPU initialization fails or software emulation is detected.
227
227
  - **Streaming & Resilience:** Streaming responses across OpenAI and Anthropic formats; adaptive rate limiting with `retry-after` handling and 30-second auto-closing, ARIA-accessible countdown dialogs for fatal errors and throttling.
228
228
 
@@ -1 +1 @@
1
- export{t as runBuild}from"../chunk-DYq-orHK.js";
1
+ export{t as runBuild}from"../chunk-BgTv9w0K.js";
@@ -111,5 +111,5 @@ ${[...r].map(e=>` <url>\n <loc>${Lc(e)}</loc>\n </url>`).join(`
111
111
  `).map(e=>{let t=e.trim();if(!t)return e;if(t.startsWith(`http://`)||t.startsWith(`https://`))try{let e=new URL(t),r=new URL(n);return e.protocol=r.protocol,e.host=r.host,e.pathname=(r.pathname.endsWith(`/`)?r.pathname.slice(0,-1):r.pathname)+e.pathname,e.toString()}catch{return n}if(t.startsWith(`/`))try{return new URL(t,n).toString()}catch{return e}return e}).join(`
112
112
  `)}function $c(e,t,n){let r=e,i=t.site||{};if(i.title&&(r=r.replace(/<title>[^<]*<\/title>/iu,`<title>${Q(i.title)} - Not Found</title>`)),n){let e=n.endsWith(`/`)?n:n+`/`;r=r.replace(/l\.replace\(["']\/shadow-claw\/["']\)/gu,`l.replace("${Q(e)}")`)}return r}function el(e){let t=c.resolve(e),n=t.split(c.sep),r=n[n.length-1],i=n[n.length-2];return(r===`resources`||r===`deps`)&&i===`pages`?c.resolve(t,`../..`):r===`resources`||r===`deps`||r===`pages`?c.resolve(t,`..`):t}function tl(e){let t=c.resolve(e),n=c.basename(t);return n===`resources`||n===`deps`||n===`pages`?c.resolve(t,`..`):t}function nl(e,t,n){if(!e||typeof e!=`string`)return[];if(c.isAbsolute(e))return[e];let r=e.replace(/^(pages\/)?(resources\/|deps\/|main\/)?/,``),i=el(t);return[c.resolve(t,`resources`,r),c.resolve(t,`deps`,r),c.resolve(t,`main`,r),c.resolve(i,`pages`,`resources`,r),c.resolve(i,`pages`,`resources`,e),c.resolve(i,`pages`,`deps`,r),c.resolve(i,`pages`,`deps`,e),c.resolve(i,`resources`,r),c.resolve(i,`resources`,e),c.resolve(i,`deps`,r),c.resolve(i,`deps`,e),c.resolve(n,`pages`,`resources`,r),c.resolve(n,`pages`,`deps`,r),c.resolve(n,`resources`,r),c.resolve(n,`deps`,r),c.resolve(n,`pages`,e),c.resolve(n,`pages`,r),c.resolve(n,`pages`,`main`,r),c.resolve(i,`pages`,e),c.resolve(i,`pages`,r),c.resolve(i,`pages`,`main`,r),c.resolve(i,`pages`,`main`,e),c.resolve(t,e),c.resolve(t,r),c.resolve(n,e),c.resolve(n,r),c.resolve(i,e),c.resolve(i,r)]}async function rl(e,t,n){if(!n)return null;let r=await il([...Ba(e),...Ba(t),...Ba(el(e))]);if(!r)return null;let i=await Gc(r);return i?zc(i,n):null}async function il(e){for(let t of e)if(t)try{return await O(t),t}catch{}return null}async function al(e,t,n){let r=n?c.dirname(c.resolve(n)):m.cwd(),i=tl(r),a=el(r),o=[c.resolve(r,`resources`),c.resolve(r,`deps`),c.resolve(i,`resources`),c.resolve(i,`deps`),c.resolve(i,`pages`,`resources`),c.resolve(i,`pages`,`deps`),c.resolve(a,`resources`),c.resolve(a,`deps`),c.resolve(a,`pages`,`resources`),c.resolve(a,`pages`,`deps`)];for(let e of o)try{let n=await w(e,{withFileTypes:!0});for(let r of n){let n=c.join(e,r.name),i=c.join(t,r.name);r.isDirectory()?await b(n,i,{recursive:!0,force:!0}):r.isFile()&&(await S(c.dirname(i),{recursive:!0}),await y(n,i))}}catch{}let s=await il([...e.pages?.notFoundPath?nl(e.pages.notFoundPath,r,i):[],...e.branding?.notFoundPath?nl(e.branding.notFoundPath,r,i):[],...e.notFoundPath?nl(e.notFoundPath,r,i):[],...nl(`404.html`,r,i)]);if(s)try{await y(s,c.join(t,`404.html`)),console.log(` Copied custom 404.html: ${s}`)}catch(e){console.warn(` Warning: Could not copy custom 404.html: ${e.message}`)}let l=await il([...e.pwa?.manifestPath?nl(e.pwa.manifestPath,r,i):[],...e.manifestPath?nl(e.manifestPath,r,i):[],...nl(`manifest.json`,r,i)]);if(l)try{await y(l,c.join(t,`manifest.json`)),console.log(` Copied custom manifest.json: ${l}`)}catch(e){console.warn(` Warning: Could not copy custom manifest.json: ${e.message}`)}let u=!1;if(e.sitemapPath){let n=await il(nl(e.sitemapPath,r,i));if(n)try{let e=c.basename(n);await y(n,c.join(t,e)),console.log(` Copied custom sitemap: ${n} → ${e}`),u=!0}catch(e){console.warn(` Warning: Could not copy custom sitemap: ${e.message}`)}}if(!u){let e=await il(nl(`sitemap.xml`,r,i));if(e)try{await y(e,c.join(t,`sitemap.xml`)),console.log(` Copied custom sitemap.xml: ${e}`)}catch(e){console.warn(` Warning: Could not copy custom sitemap.xml: ${e.message}`)}let n=await il(nl(`sitemap.txt`,r,i));if(n)try{await y(n,c.join(t,`sitemap.txt`)),console.log(` Copied custom sitemap.txt: ${n}`)}catch(e){console.warn(` Warning: Could not copy custom sitemap.txt: ${e.message}`)}}let d=e.overwriteAssets===!0||e.branding?.overwriteAssets===!0,f=Array.isArray(e.assets)?e.assets:[e.assetsDir,e.assets].filter(Boolean),p=Array.from(new Set([...f.flatMap(e=>nl(e,r,i)),...nl(`assets`,r,i)].filter(e=>e&&typeof e==`string`))),h=c.join(t,`assets`);if(d)try{await D(h,{recursive:!0,force:!0}),await S(h,{recursive:!0}),console.log(` Cleared dist public assets for complete template asset overwrite.`)}catch{}let g=/* @__PURE__ */ new Set,_=[...p].reverse();for(let e of _)if(!g.has(e))try{let t=await O(e);if(g.add(e),t.isDirectory())await b(e,h,{recursive:!0,force:!0}),console.log(` Copied custom assets: ${e} → ${h}`);else if(t.isFile()){let t=c.basename(e);await S(h,{recursive:!0}),await y(e,c.join(h,t)),console.log(` Copied custom asset file: ${e} → ${h}`)}}catch{}}async function ol(e,t,n){let r=e.theme||{};if(!r.stylesheet)return;let i=n?c.dirname(c.resolve(n)):m.cwd(),a=tl(i),o=await il(nl(r.stylesheet,i,a));if(!o)return;let s=r.stylesheet.replace(/^(pages\/)?(resources\/|deps\/|main\/)?/,``),l=c.join(t,s);try{await S(c.dirname(l),{recursive:!0}),await y(o,l),console.log(` Copied theme stylesheet: ${o} → ${l}`)}catch(e){console.warn(` Warning: Could not copy theme stylesheet ${o}: ${e.message}`)}}async function sl(e,t,n){let r=(e.customElements&&typeof e.customElements==`object`&&!Array.isArray(e.customElements)?e.customElements?.scripts:void 0)||e.scripts||[];if(!Array.isArray(r)||r.length===0)return;let i=n?c.dirname(c.resolve(n)):m.cwd(),a=tl(i);for(let e of r){let n=typeof e==`string`?e:e?.src;if(!n||n.startsWith(`http://`)||n.startsWith(`https://`)||n.startsWith(`//`))continue;let r=await il(nl(n,i,a));if(r){let e=n.replace(/^(pages\/)?(resources\/|deps\/|main\/)?/,``),i=c.join(t,e);try{await S(c.dirname(i),{recursive:!0}),await y(r,i),console.log(` Copied custom script: ${r} → ${i}`)}catch(e){console.warn(` Warning: Could not copy custom script ${r}: ${e.message}`)}}}}async function cl(e,t,n){let r=e.branding||{},i=e.pwa||{},a=n?c.dirname(c.resolve(n)):m.cwd(),o=tl(a),s=[],l=await il(nl(i.manifestPath||e.manifestPath||`manifest.json`,a,o));if(l){let e=await Gc(l);e&&Array.isArray(e.icons)&&(s=e.icons.map(e=>e?.src).filter(Boolean))}let u=[r.faviconPath,r.appleTouchIconPath,`assets/icons/favicon.svg`,`assets/icons/favicon.ico`,`favicon.svg`,`favicon.ico`,`pages/resources/assets/icons/favicon.svg`,`pages/resources/assets/icons/favicon.ico`,`pages/resources/favicon.svg`,`pages/deps/favicon.svg`,`pages/main/favicon.svg`,...Array.isArray(i.icons)?i.icons.map(e=>e.src):[],...s].filter(e=>!!e&&typeof e==`string`&&!e.startsWith(`http://`)&&!e.startsWith(`https://`)&&!e.startsWith(`//`));if(u.length===0)return;let d=/* @__PURE__ */ new Set,f=/* @__PURE__ */ new Set;for(let e of u){if(d.has(e))continue;d.add(e);let n=await il(nl(e,a,o));if(n){let r=e.replace(/^(pages\/)?(resources\/|deps\/|main\/)?/,``),i=c.join(t,r);if(f.has(i))continue;f.add(i);try{await S(c.dirname(i),{recursive:!0}),await y(n,i),console.log(` Copied branding asset: ${n} → ${i}`)}catch(e){console.warn(` Warning: Could not copy branding asset ${n}: ${e.message}`)}}}}async function ll(e,t){let n=await Gc(t);if(!n)return console.log(`No site-config.json found — skipping site configuration.`),{applied:!1};console.log(`Applying site-config.json...`);let r=m.env.PAGES_ORIGIN||``,i=m.env.PAGES_BASE_PATH||``;await al(n,e,t);let a=t?c.dirname(c.resolve(t)):m.cwd(),o=tl(a),s;if(n.sidebar?.slotHtml)s=n.sidebar.slotHtml;else if(n.sidebar?.sections)s=Jc(n.sidebar.sections);else{let e=await il([n.sidebar?.slotPath,`pages/main/sidebar.html`,`pages/sidebar.html`,`sidebar.html`,`resources/sidebar.html`].filter(Boolean).flatMap(e=>nl(e,a,o)));e&&(s=await Kc(e)??void 0,console.log(` Found slotted sidebar: ${e}`))}let l=c.join(e,`index.html`),u=await Kc(l);u&&(await qc(l,Yc(u,n,s)),console.log(` Patched index.html`));let d=c.join(e,`manifest.json`),f=await Kc(d);f&&(await qc(d,Zc(f,n)),console.log(` Patched manifest.json`));let p=c.join(e,`sitemap.xml`),h=!!await Kc(c.join(e,`sitemap.txt`)),g=!1;if(!await Kc(p)&&!h){let e=await rl(a,o,r||n.branding?.siteUrl||``);e&&(await qc(p,e),g=!0,console.log(` Generated sitemap.xml from routes.json`))}let _=g?``:await Kc(p);_&&(await qc(p,Qc(_,r)),console.log(` Patched sitemap.xml`));let v=c.join(e,`sitemap.txt`),y=await Kc(v);y&&(await qc(v,Qc(y,r)),console.log(` Patched sitemap.txt`));let b=c.join(e,`404.html`),x=await Kc(b);return x&&(await qc(b,$c(x,n,i)),console.log(` Patched 404.html`)),await ol(n,e,t),await sl(n,e,t),await cl(n,e,t),console.log(`Site configuration applied successfully.`),{applied:!0}}async function ul(){let[e,t]=m.argv.slice(2);(!e||!t)&&(console.error(`Usage: node bin/site-config/apply.mjs <distPublicDir> <siteConfigPath>`),m.exit(1)),await ll(e,t)}m.argv[1]&&c.resolve(m.argv[1])===c.resolve(p(import.meta.url))&&ul().catch(e=>{console.error(`site-config/apply.ts failed:`,e),m.exit(1)});function dl(){return[`const shadowClawServiceWorkerTrustedTypesFactory = Reflect.get(self, "trustedTypes");`,`let shadowClawServiceWorkerTrustedTypesPolicy = null;`,`if (shadowClawServiceWorkerTrustedTypesFactory && typeof shadowClawServiceWorkerTrustedTypesFactory.createPolicy === "function") {`,` try {`,` if (typeof shadowClawServiceWorkerTrustedTypesFactory.getPolicy === "function") {`,` shadowClawServiceWorkerTrustedTypesPolicy =`,` shadowClawServiceWorkerTrustedTypesFactory.getPolicy("default") ||`,` shadowClawServiceWorkerTrustedTypesFactory.getPolicy("shadowclaw-sandbox") ||`,` null;`,` }`,``,` if (!shadowClawServiceWorkerTrustedTypesPolicy) {`,` shadowClawServiceWorkerTrustedTypesPolicy =`,` shadowClawServiceWorkerTrustedTypesFactory.createPolicy("default", {`,` createHTML: (input) => input,`,` createScriptURL: (input) => input,`,` });`,` }`,` } catch {`,` // Ignore policy creation failures and fall back to raw importScripts.`,` }`,`}`,``,`const shadowClawNativeImportScripts = typeof importScripts === "function" ? importScripts.bind(self) : null;`,``,`const shadowClawImportScripts = (...urls) => {`,` if (!shadowClawNativeImportScripts) {`,` return;`,` }`,``,` if (!shadowClawServiceWorkerTrustedTypesPolicy || typeof shadowClawServiceWorkerTrustedTypesPolicy.createScriptURL !== "function") {`,` shadowClawNativeImportScripts(...urls);`,``,` return;`,` }`,``,` shadowClawNativeImportScripts(...urls.map((url) => shadowClawServiceWorkerTrustedTypesPolicy.createScriptURL(url)));`,`};`].join(`
113
113
  `)}function fl(e){return e.includes(`shadowClawImportScripts`)||!e.includes(`if(!self.define){`)||!e.includes(`importScripts(`)?e:`${dl()}\n${e.replace(/importScripts\(/g,`shadowClawImportScripts(`)}`}const pl=d(m.cwd(),`dist/public/service-worker.js`);async function ml(e=pl,{readFileImpl:t=C,writeFileImpl:n=k,patchImpl:r=fl,logImpl:i=console.log}={}){let a=await t(e,`utf8`),o=r(a);o!==a&&(await n(e,o,`utf8`),i(`Patched Trusted Types imports in ${e}`))}async function hl(){await ml(m.argv[2]||pl)}m.argv[1]&&c.resolve(m.argv[1])===c.resolve(p(import.meta.url))&&hl().catch(e=>{console.error(e),m.exit(1)});async function gl(e,{writeFileImpl:t=k}={}){let r=e||l(n(import.meta.url),`dist`,`public`);await t(l(r,`.nojekyll`),``,`utf-8`)}m.argv[1]&&c.resolve(m.argv[1])===c.resolve(p(import.meta.url))&&await gl();const _l=n(import.meta.url);async function $(e){try{return await O(e),!0}catch{return!1}}async function vl(e={}){let t=e.quiet??(A.env.NODE_ENV===`test`&&!A.env.VERBOSE),n=e.stdio??(A.env.NODE_ENV===`test`&&!A.env.VERBOSE?`pipe`:`inherit`),r=(...e)=>{t||console.log(...e)};async function i(e,r={}){!t&&!r.quiet&&console.log(`> ${e}`);let i=r.stdio??n;v(e,{stdio:i,...r})}let a=d(e.contentRoot||g.SHADOWCLAW_CONTENT_ROOT||A.cwd()),o=d(e.toolchainRoot||_l),s=a===o,{isProduction:c,copyAllAssets:u,prerenderPages:f,prerenderMainMemory:p}=Ha({...g,...e.isProduction===void 0?{}:{NODE_ENV:e.isProduction?`production`:`development`},...e.copyAllAssets===void 0?{}:{COPY_ALL_ASSETS:String(e.copyAllAssets)},...e.prerenderPages===void 0?{}:{PRERENDER_PAGES:String(e.prerenderPages)},...e.prerenderMainMemory===void 0?{}:{PRERENDER_MAIN_MEMORY:String(e.prerenderMainMemory)}});if(s){if(h(_l),await Fa(`dist/public`),await S(`dist/public/assets`,{recursive:!0}),u)await b(`assets`,`dist/public`,{recursive:!0});else{await b(`assets/icons`,`dist/public/assets/icons`,{recursive:!0}),await b(`assets/screenshots`,`dist/public/assets/screenshots`,{recursive:!0});try{await b(`assets/fonts`,`dist/public/assets/fonts`,{recursive:!0})}catch{}}await Ia([`pages/resources`,`pages/deps`,`resources`,`deps`,`pages/assets`,`pages/main/assets`],`dist/public`);for(let e of za())await La(e.sources,e.dest,e.opts||{});try{await b(`e2e/README.md`,`dist/public/e2e/README.md`)}catch{}try{await b(`pages`,`dist/public/pages`,{recursive:!0})}catch{}try{await b(`pages/main`,`dist/public/files/main`,{recursive:!0})}catch{}try{await b(`pages/main`,`dist/public/static-main`,{recursive:!0})}catch{}try{await b(`.agents/skills`,`dist/public/.agents/skills`,{recursive:!0})}catch{}try{await b(`.agents/tools`,`dist/public/.agents/tools`,{recursive:!0})}catch{}try{await b(`.agents/scripts`,`dist/public/.agents/scripts`,{recursive:!0})}catch{}if(await $(`.agents/skills`))try{let{generateSkillsIndex:e}=await import(`./chunk-B10_-GxS.js`);await e(_l)}catch(e){console.warn(`Notice: Failed to auto-generate agent-skills index:`,e)}if(await $(`.well-known`))try{await b(`.well-known`,`dist/public/.well-known`,{recursive:!0,force:!0})}catch{}await i(`npm run -s rolldown`);let t=await Ra(Va())||`pages/site-config.json`;p?await Ac({indexPath:`dist/public/index.html`,sourcePath:`pages/main`,prerenderPages:f,siteConfigPath:t}):await Ac({indexPath:`dist/public/index.html`,noSeed:!0,siteConfigPath:t});try{await ll(`dist/public`,t)}catch{}try{let e=JSON.parse(await C(`package.json`,`utf8`));if(e.version){let t=`dist/public/index.html`,n=await C(t,`utf8`);await k(t,n.replace(/<meta\s+name="version"[^>]*>/,`<meta name="version" content="${e.version}" />`),`utf8`);for(let t of[`.well-known/mcp.json`,`.well-known/mcp/server-card.json`]){let n=l(`dist/public`,t);if(await $(n))try{let t=JSON.parse(await C(n,`utf8`));t.version!==e.version&&(t.version=e.version,await k(n,JSON.stringify(t,null,2)+`
114
- `,`utf8`))}catch{}}}}catch{}if(c){r(`Running production post-build steps...`);let t=e.pagesOrigin||g.PAGES_ORIGIN,n=e.basePath||(g.PAGES_BASE_PATH??`/shadow-claw/`);if(r(` PAGES_ORIGIN : ${t||`(relative ./)`}`),r(` PAGES_BASE_PATH: ${n}`),t)try{let e=`dist/public/manifest.json`,n=await C(e,`utf8`),r=JSON.parse(n);r.start_url&&(r.start_url=t,await k(e,JSON.stringify(r,null,2),`utf8`))}catch{}try{let e=`dist/public/index.html`,t=await C(e,`utf8`);t=t.replace(/<base\s+href="[^"]*"\s*\/?>/i,`<base href="${n}" />`),await k(e,t,`utf8`)}catch{}await gl(`dist/public`);let a=``;try{a=v(`npm run -s build:pkg:get:meta`,{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim()}catch{}a&&await i(`npm run -s build:pkg:meta "${a}"`)}await Fc({publicDir:`dist/public`,routesPath:await Ra(Ba())||`pages/routes.json`,sourcePath:`pages/main`,prerenderPages:f,siteConfigPath:t}),await i(`npm run -s build:service-worker`);let n=`dist/public/service-worker.js`;await $(n)&&await ml(n,{logImpl:()=>{}}),r(`Build completed successfully.`);return}let m=e.outDir||`dist/public`,_=d(a,m);await S(_,{recursive:!0}),await S(l(_,`assets`),{recursive:!0});let y=l(o,`dist/public`);await $(l(y,`index.js`))||(r(`Building ShadowClaw core toolchain...`),await Fa(l(o,`dist/public`)),await Fa(l(o,`dist-electron`)),await i(`npm run -s rolldown`,{cwd:o})),await b(y,_,{recursive:!0,filter:e=>!(e.includes(`/assets/cache/`)||e.includes(`\\assets\\cache\\`)||e.includes(`/.cache/`)||e.includes(`\\.cache\\`))}),a!==o&&(await Fa(l(_,`sitemap.xml`)),await Fa(l(_,`sitemap.txt`)));let x=l(a,`assets`);await $(x)&&(u?await b(x,_,{recursive:!0,force:!0}):(await $(l(x,`icons`))&&await b(l(x,`icons`),l(_,`assets/icons`),{recursive:!0,force:!0}),await $(l(x,`screenshots`))&&await b(l(x,`screenshots`),l(_,`assets/screenshots`),{recursive:!0,force:!0}),await $(l(x,`fonts`))&&await b(l(x,`fonts`),l(_,`assets/fonts`),{recursive:!0,force:!0}))),await Ia([`pages/resources`,`pages/deps`,`resources`,`deps`,`pages/assets`,`pages/main/assets`],_,{baseDir:a});let w=za({contentRoot:a,toolchainRoot:o,distPublicDir:_});for(let e of w)await La(e.sources,e.dest,e.opts||{});let T=l(a,`pages`);await $(T)&&await b(T,l(_,`pages`),{recursive:!0,force:!0});let E=l(a,`pages/main`);await $(E)&&(await b(E,l(_,`files/main`),{recursive:!0,force:!0}),await b(E,l(_,`static-main`),{recursive:!0,force:!0}));let D=l(a,`.agents/skills`);await $(D)&&await b(D,l(_,`.agents/skills`),{recursive:!0,force:!0});let O=l(o,`.agents/skills`);a!==o&&await $(O)&&await b(O,l(_,`.agents/skills`),{recursive:!0,force:!1,errorOnExist:!1});let j=l(a,`.agents/tools`);if(await $(j))await b(j,l(_,`.agents/tools`),{recursive:!0,force:!0});else{let e=l(o,`.agents/tools`);await $(e)&&await b(e,l(_,`.agents/tools`),{recursive:!0,force:!0})}let ee=l(a,`.agents/scripts`);if(await $(ee))await b(ee,l(_,`.agents/scripts`),{recursive:!0,force:!0});else{let e=l(o,`.agents/scripts`);await $(e)&&await b(e,l(_,`.agents/scripts`),{recursive:!0,force:!0})}let te=l(o,`.well-known`);await $(te)&&await b(te,l(_,`.well-known`),{recursive:!0,force:!0});let M=l(a,`.well-known`);if(a!==o&&await $(M)&&await b(M,l(_,`.well-known`),{recursive:!0,force:!0}),await $(l(_,`.agents/skills`)))try{let{generateSkillsIndex:e}=await import(`./chunk-B10_-GxS.js`);if(await e(_,{metadataRoot:a,outDir:`.well-known/agent-skills`,toolchainRoot:o,includeBundled:!0}),await $(D))try{await e(a,{toolchainRoot:o,includeBundled:!0})}catch{}}catch(e){console.warn(`Notice: Failed to auto-generate agent-skills index:`,e)}let N=await Ra(Va(a)),P=N||l(a,`pages/site-config.json`),ne=p;if(e.prerenderMainMemory===void 0&&N)try{JSON.parse(await C(N,`utf8`))?.settings?.overridePrerenderSkeleton===!1&&(ne=!1,r(` site-config: overridePrerenderSkeleton=false — skeleton overlay disabled.`))}catch{}let F=l(_,`index.html`);ne&&await $(E)?await Ac({indexPath:F,sourcePath:E,prerenderPages:f,siteConfigPath:P}):await Ac({indexPath:F,noSeed:!0,siteConfigPath:P});try{await ll(_,P)}catch{}let I=c?e.basePath||g.PAGES_BASE_PATH||`/`:e.basePath||`/`;try{let e=await C(F,`utf8`);e=e.replace(/<base\s+href="[^"]*"\s*\/?>/i,`<base href="${I}" />`);let t=``;try{let e=await Ra([l(a,`package.json`),l(o,`package.json`)]);e&&(t=JSON.parse(await C(e,`utf8`)).version||``)}catch{}if(t){e=e.replace(/<meta\s+name="version"[^>]*>/,`<meta name="version" content="${t}" />`);for(let e of[`.well-known/mcp.json`,`.well-known/mcp/server-card.json`]){let n=l(_,e);if(await $(n))try{let e=JSON.parse(await C(n,`utf8`));e.version!==t&&(e.version=t,await k(n,JSON.stringify(e,null,2)+`
114
+ `,`utf8`))}catch{}}}}catch{}if(c){r(`Running production post-build steps...`);let t=e.pagesOrigin||g.PAGES_ORIGIN,n=e.basePath||(g.PAGES_BASE_PATH??`/shadow-claw/`);if(r(` PAGES_ORIGIN : ${t||`(relative ./)`}`),r(` PAGES_BASE_PATH: ${n}`),t)try{let e=`dist/public/manifest.json`,n=await C(e,`utf8`),r=JSON.parse(n);r.start_url&&(r.start_url=t,await k(e,JSON.stringify(r,null,2),`utf8`))}catch{}try{let e=`dist/public/index.html`,t=await C(e,`utf8`);t=t.replace(/<base\s+href="[^"]*"\s*\/?>/i,`<base href="${n}" />`),await k(e,t,`utf8`)}catch{}await gl(`dist/public`);let a=``;try{a=v(`npm run -s build:pkg:get:meta`,{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim()}catch{}a&&await i(`npm run -s build:pkg:meta "${a}"`)}await Fc({publicDir:`dist/public`,routesPath:await Ra(Ba())||`pages/routes.json`,sourcePath:`pages/main`,prerenderPages:f,siteConfigPath:t}),await i(`npm run -s build:service-worker`);let n=`dist/public/service-worker.js`;await $(n)&&await ml(n,{logImpl:()=>{}}),r(`Build completed successfully.`);return}let m=e.outDir||`dist/public`,_=d(a,m);await S(_,{recursive:!0}),await S(l(_,`assets`),{recursive:!0});let y=l(o,`dist/public`);await $(l(y,`index.js`))||(r(`Building ShadowClaw core toolchain...`),await Fa(l(o,`dist/public`)),await Fa(l(o,`dist-electron`)),await i(`npm run -s rolldown`,{cwd:o})),await b(y,_,{recursive:!0,filter:e=>!(e.includes(`/assets/cache/`)||e.includes(`\\assets\\cache\\`)||e.includes(`/.cache/`)||e.includes(`\\.cache\\`)||e.includes(`/cache/`)||e.includes(`\\cache\\`)||e.endsWith(`/cache`)||e.endsWith(`\\cache`))}),a!==o&&(await Fa(l(_,`sitemap.xml`)),await Fa(l(_,`sitemap.txt`)));let x=l(a,`assets`);await $(x)&&(u?await b(x,_,{recursive:!0,force:!0}):(await $(l(x,`icons`))&&await b(l(x,`icons`),l(_,`assets/icons`),{recursive:!0,force:!0}),await $(l(x,`screenshots`))&&await b(l(x,`screenshots`),l(_,`assets/screenshots`),{recursive:!0,force:!0}),await $(l(x,`fonts`))&&await b(l(x,`fonts`),l(_,`assets/fonts`),{recursive:!0,force:!0}))),await Ia([`pages/resources`,`pages/deps`,`resources`,`deps`,`pages/assets`,`pages/main/assets`],_,{baseDir:a});let w=za({contentRoot:a,toolchainRoot:o,distPublicDir:_});for(let e of w)await La(e.sources,e.dest,e.opts||{});let T=l(a,`pages`);await $(T)&&await b(T,l(_,`pages`),{recursive:!0,force:!0});let E=l(a,`pages/main`);await $(E)&&(await b(E,l(_,`files/main`),{recursive:!0,force:!0}),await b(E,l(_,`static-main`),{recursive:!0,force:!0}));let D=l(a,`.agents/skills`);await $(D)&&await b(D,l(_,`.agents/skills`),{recursive:!0,force:!0});let O=l(o,`.agents/skills`);a!==o&&await $(O)&&await b(O,l(_,`.agents/skills`),{recursive:!0,force:!1,errorOnExist:!1});let j=l(a,`.agents/tools`);if(await $(j))await b(j,l(_,`.agents/tools`),{recursive:!0,force:!0});else{let e=l(o,`.agents/tools`);await $(e)&&await b(e,l(_,`.agents/tools`),{recursive:!0,force:!0})}let ee=l(a,`.agents/scripts`);if(await $(ee))await b(ee,l(_,`.agents/scripts`),{recursive:!0,force:!0});else{let e=l(o,`.agents/scripts`);await $(e)&&await b(e,l(_,`.agents/scripts`),{recursive:!0,force:!0})}let te=l(o,`.well-known`);await $(te)&&await b(te,l(_,`.well-known`),{recursive:!0,force:!0});let M=l(a,`.well-known`);if(a!==o&&await $(M)&&await b(M,l(_,`.well-known`),{recursive:!0,force:!0}),await $(l(_,`.agents/skills`)))try{let{generateSkillsIndex:e}=await import(`./chunk-B10_-GxS.js`);if(await e(_,{metadataRoot:a,outDir:`.well-known/agent-skills`,toolchainRoot:o,includeBundled:!0}),await $(D))try{await e(a,{toolchainRoot:o,includeBundled:!0})}catch{}}catch(e){console.warn(`Notice: Failed to auto-generate agent-skills index:`,e)}let N=await Ra(Va(a)),P=N||l(a,`pages/site-config.json`),ne=p;if(e.prerenderMainMemory===void 0&&N)try{JSON.parse(await C(N,`utf8`))?.settings?.overridePrerenderSkeleton===!1&&(ne=!1,r(` site-config: overridePrerenderSkeleton=false — skeleton overlay disabled.`))}catch{}let F=l(_,`index.html`);ne&&await $(E)?await Ac({indexPath:F,sourcePath:E,prerenderPages:f,siteConfigPath:P}):await Ac({indexPath:F,noSeed:!0,siteConfigPath:P});try{await ll(_,P)}catch{}let I=c?e.basePath||g.PAGES_BASE_PATH||`/`:e.basePath||`/`;try{let e=await C(F,`utf8`);e=e.replace(/<base\s+href="[^"]*"\s*\/?>/i,`<base href="${I}" />`);let t=``;try{let e=await Ra([l(a,`package.json`),l(o,`package.json`)]);e&&(t=JSON.parse(await C(e,`utf8`)).version||``)}catch{}if(t){e=e.replace(/<meta\s+name="version"[^>]*>/,`<meta name="version" content="${t}" />`);for(let e of[`.well-known/mcp.json`,`.well-known/mcp/server-card.json`]){let n=l(_,e);if(await $(n))try{let e=JSON.parse(await C(n,`utf8`));e.version!==t&&(e.version=t,await k(n,JSON.stringify(e,null,2)+`
115
115
  `,`utf8`))}catch{}}}await k(F,e,`utf8`)}catch{}if(c){r(`Running production post-build steps...`);let t=e.pagesOrigin||g.PAGES_ORIGIN;if(r(` PAGES_ORIGIN : ${t||`(relative ./)`}`),r(` PAGES_BASE_PATH: ${I}`),t)try{let e=l(_,`manifest.json`),n=await C(e,`utf8`),r=JSON.parse(n);r.start_url&&(r.start_url=t,await k(e,JSON.stringify(r,null,2),`utf8`))}catch{}await k(l(_,`.nojekyll`),``,`utf8`);let n=``;try{n=v(`git rev-parse HEAD`,{cwd:a,encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim()}catch{try{n=v(`git rev-parse HEAD`,{cwd:o,encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim()}catch{}}if(n){let e=await C(F,`utf8`);await k(F,e.replace(/<meta\s+name="revision"[^>]*>/,`<meta name="revision" content="${n}" />`),`utf8`)}}await Fc({publicDir:_,routesPath:await Ra(Ba(a))||l(a,`pages/routes.json`),sourcePath:await $(E)?E:l(o,`pages/main`),prerenderPages:f,siteConfigPath:P});let L=l(_,`service-worker.js`);await $(L)&&await ml(L,{logImpl:()=>{}}),r(`Build completed successfully.`)}A.argv[1]&&d(A.argv[1])===d(p(import.meta.url))&&vl().catch(e=>{console.error(e),_(1)});export{vl as t};
@@ -28,5 +28,5 @@ ${[...r].map(e=>` <url>\n <loc>${oo(e)}</loc>\n </url>`).join(`
28
28
  `));let s=t.theme||{};if(s.stylesheet){let e=mo(s.stylesheet),t=`<link rel="stylesheet" href="${Z(e)}" />`,r=Z(e).replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),a=e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),o=RegExp(`<link\\s+[^>]*href=["'](?:${a}|${r})["'][^>]*>`,`iu`),c=_(i),l=(c===-1?i:i.slice(0,c)).replace(/<script\b[\s\S]*?<\/script>/gi,``);o.test(l)||(i=/<link\s+rel="stylesheet"\s+href="index\.css"\s*\/?>/iu.test(i)?i.replace(/(<link\s+rel="stylesheet"\s+href="index\.css"\s*\/?>)/iu,`$1\n ${t}`):n(i,` ${t}`))}let{allowedDomains:c}=lo(t,s),l=fo(t,c),u=`<script id="shadow-claw-site-config" type="application/json">${JSON.stringify(l).replace(/</g,`\\u003c`).replace(/>/g,`\\u003e`).replace(/\//g,`\\u002f`)}<\/script>`;i=i.includes(`<script id="shadow-claw-site-config"`)?i.replace(/<script\s+id="shadow-claw-site-config"[\s\S]*?<\/script>/iu,()=>u):i.includes(`<script src="theme-init.js">`)?i.replace(`<script src="theme-init.js">`,`${u}\n <script src="theme-init.js">`):/<script\b[^>]*>\s*var\s+ShadowClawThemeInit\b/iu.test(i)?i.replace(/(<script\b[^>]*>\s*var\s+ShadowClawThemeInit\b)/iu,`${u}\n $1`):n(i,` ${u}`),i=i.replace(/\s*<meta\s+name="shadow-claw-override-prerender-skeleton"[^>]*>/giu,``),typeof t.settings?.overridePrerenderSkeleton==`boolean`&&(i=i.replace(`<script id="shadow-claw-site-config"`,`<meta name="shadow-claw-override-prerender-skeleton" content="${t.settings.overridePrerenderSkeleton}" />\n <script id="shadow-claw-site-config"`));let d=r||t.sidebar?.slotHtml||(t.sidebar?.sections?vo(t.sidebar.sections):``);if(d){let e=d.trim();/\bslot="sidebar(?:-nav|-content|-footer)?"/iu.test(e)||(e=`<div slot="sidebar" class="sidebar-custom-sections">\n${e}\n</div>`);let t=i.match(/<[^>]+?\bslot="sidebar(?:-nav|-content|-footer)?"[^>]*>[\s\S]*?<\/[^>]+>/iu);t&&(i=i.replace(t[0],``)),i.includes(`</shadow-claw>`)?i=i.replace(`</shadow-claw>`,` ${e}\n</shadow-claw>`):i.includes(`<shadow-claw></shadow-claw>`)&&(i=i.replace(`<shadow-claw></shadow-claw>`,`<shadow-claw>\n ${e}\n</shadow-claw>`))}return t.sidebar&&(i=h(i,t.sidebar)),i}function bo(e){let t=(e.src||``).replace(/^(pages\/)?(resources\/|deps\/|main\/)?/,``),n=e.type||(t.endsWith(`.svg`)?`image/svg+xml`:t.endsWith(`.png`)?`image/png`:`image/x-icon`),r=(e.purpose||`any`).trim();return n===`image/svg+xml`||t.endsWith(`.svg`)?[{...e,src:t,type:n,purpose:`any`}]:r.includes(`any`)&&r.includes(`maskable`)?[{...e,src:t,type:n,purpose:`any`},{...e,src:t,type:n,purpose:`maskable`}]:[{...e,src:t,type:n,purpose:r}]}function xo(e,t){let n=typeof e==`string`?JSON.parse(e):e,r=t.pwa||{},i=t.site||{},a=w.env.PAGES_ORIGIN;if((r.name||i.title)&&(n.name=r.name||i.title),(r.shortName||i.title)&&(n.short_name=r.shortName||i.title),i.description&&(n.description=i.description),r.backgroundColor&&(n.background_color=r.backgroundColor),(r.themeColor||i.themeColor)&&(n.theme_color=r.themeColor||i.themeColor),r.startUrl?n.start_url=r.startUrl:a?n.start_url=a:n.start_url||=`./`,r.icons&&Array.isArray(r.icons)){let e=r.icons.flatMap(bo),t=Array.isArray(n.icons)?n.icons.flatMap(bo):[],i=new Set(e.map(e=>e.src));n.icons=[...e,...t.filter(e=>!i.has(e.src))]}else Array.isArray(n.icons)&&(n.icons=n.icons.flatMap(bo));return r.screenshots&&Array.isArray(r.screenshots)&&(n.screenshots=r.screenshots.map(e=>{let t=(e.src||``).replace(/^(pages\/)?(resources\/|deps\/|main\/)?/,``);return{...e,src:t}})),JSON.stringify(n,null,2)}function So(e,t){if(!t)return e;let n=t.endsWith(`/`)?t:t+`/`;return/<loc>/i.test(e)?e.replace(/<loc>([^<]*)<\/loc>/giu,(e,t)=>{try{let e=new URL(t.trim()),r=new URL(n),i=r.pathname.replace(/\/$/,``);return`<loc>${Z(r.origin+i+e.pathname+e.search)}</loc>`}catch{return`<loc>${Z(n)}</loc>`}}):e.split(`
29
29
  `).map(e=>{let t=e.trim();if(!t)return e;if(t.startsWith(`http://`)||t.startsWith(`https://`))try{let e=new URL(t),r=new URL(n);return e.protocol=r.protocol,e.host=r.host,e.pathname=(r.pathname.endsWith(`/`)?r.pathname.slice(0,-1):r.pathname)+e.pathname,e.toString()}catch{return n}if(t.startsWith(`/`))try{return new URL(t,n).toString()}catch{return e}return e}).join(`
30
30
  `)}function Co(e,t,n){let r=e,i=t.site||{};if(i.title&&(r=r.replace(/<title>[^<]*<\/title>/iu,`<title>${Z(i.title)} - Not Found</title>`)),n){let e=n.endsWith(`/`)?n:n+`/`;r=r.replace(/l\.replace\(["']\/shadow-claw\/["']\)/gu,`l.replace("${Z(e)}")`)}return r}function wo(e){let t=b.resolve(e),n=t.split(b.sep),r=n[n.length-1],i=n[n.length-2];return(r===`resources`||r===`deps`)&&i===`pages`?b.resolve(t,`../..`):r===`resources`||r===`deps`||r===`pages`?b.resolve(t,`..`):t}function To(e){let t=b.resolve(e),n=b.basename(t);return n===`resources`||n===`deps`||n===`pages`?b.resolve(t,`..`):t}function Q(e,t,n){if(!e||typeof e!=`string`)return[];if(b.isAbsolute(e))return[e];let r=e.replace(/^(pages\/)?(resources\/|deps\/|main\/)?/,``),i=wo(t);return[b.resolve(t,`resources`,r),b.resolve(t,`deps`,r),b.resolve(t,`main`,r),b.resolve(i,`pages`,`resources`,r),b.resolve(i,`pages`,`resources`,e),b.resolve(i,`pages`,`deps`,r),b.resolve(i,`pages`,`deps`,e),b.resolve(i,`resources`,r),b.resolve(i,`resources`,e),b.resolve(i,`deps`,r),b.resolve(i,`deps`,e),b.resolve(n,`pages`,`resources`,r),b.resolve(n,`pages`,`deps`,r),b.resolve(n,`resources`,r),b.resolve(n,`deps`,r),b.resolve(n,`pages`,e),b.resolve(n,`pages`,r),b.resolve(n,`pages`,`main`,r),b.resolve(i,`pages`,e),b.resolve(i,`pages`,r),b.resolve(i,`pages`,`main`,r),b.resolve(i,`pages`,`main`,e),b.resolve(t,e),b.resolve(t,r),b.resolve(n,e),b.resolve(n,r),b.resolve(i,e),b.resolve(i,r)]}async function Eo(e,t,n){if(!n)return null;let r=await Do([...Qa(e),...Qa(t),...Qa(wo(e))]);if(!r)return null;let i=await ho(r);return i?co(i,n):null}async function Do(e){for(let t of e)if(t)try{return await pe(t),t}catch{}return null}async function Oo(e,t,n){let r=n?b.dirname(b.resolve(n)):w.cwd(),i=To(r),a=wo(r),o=[b.resolve(r,`resources`),b.resolve(r,`deps`),b.resolve(i,`resources`),b.resolve(i,`deps`),b.resolve(i,`pages`,`resources`),b.resolve(i,`pages`,`deps`),b.resolve(a,`resources`),b.resolve(a,`deps`),b.resolve(a,`pages`,`resources`),b.resolve(a,`pages`,`deps`)];for(let e of o)try{let n=await le(e,{withFileTypes:!0});for(let r of n){let n=b.join(e,r.name),i=b.join(t,r.name);r.isDirectory()?await E(n,i,{recursive:!0,force:!0}):r.isFile()&&(await O(b.dirname(i),{recursive:!0}),await T(n,i))}}catch{}let s=await Do([...e.pages?.notFoundPath?Q(e.pages.notFoundPath,r,i):[],...e.branding?.notFoundPath?Q(e.branding.notFoundPath,r,i):[],...e.notFoundPath?Q(e.notFoundPath,r,i):[],...Q(`404.html`,r,i)]);if(s)try{await T(s,b.join(t,`404.html`)),console.log(` Copied custom 404.html: ${s}`)}catch(e){console.warn(` Warning: Could not copy custom 404.html: ${e.message}`)}let c=await Do([...e.pwa?.manifestPath?Q(e.pwa.manifestPath,r,i):[],...e.manifestPath?Q(e.manifestPath,r,i):[],...Q(`manifest.json`,r,i)]);if(c)try{await T(c,b.join(t,`manifest.json`)),console.log(` Copied custom manifest.json: ${c}`)}catch(e){console.warn(` Warning: Could not copy custom manifest.json: ${e.message}`)}let l=!1;if(e.sitemapPath){let n=await Do(Q(e.sitemapPath,r,i));if(n)try{let e=b.basename(n);await T(n,b.join(t,e)),console.log(` Copied custom sitemap: ${n} → ${e}`),l=!0}catch(e){console.warn(` Warning: Could not copy custom sitemap: ${e.message}`)}}if(!l){let e=await Do(Q(`sitemap.xml`,r,i));if(e)try{await T(e,b.join(t,`sitemap.xml`)),console.log(` Copied custom sitemap.xml: ${e}`)}catch(e){console.warn(` Warning: Could not copy custom sitemap.xml: ${e.message}`)}let n=await Do(Q(`sitemap.txt`,r,i));if(n)try{await T(n,b.join(t,`sitemap.txt`)),console.log(` Copied custom sitemap.txt: ${n}`)}catch(e){console.warn(` Warning: Could not copy custom sitemap.txt: ${e.message}`)}}let u=e.overwriteAssets===!0||e.branding?.overwriteAssets===!0,d=Array.isArray(e.assets)?e.assets:[e.assetsDir,e.assets].filter(Boolean),f=Array.from(new Set([...d.flatMap(e=>Q(e,r,i)),...Q(`assets`,r,i)].filter(e=>e&&typeof e==`string`))),p=b.join(t,`assets`);if(u)try{await fe(p,{recursive:!0,force:!0}),await O(p,{recursive:!0}),console.log(` Cleared dist public assets for complete template asset overwrite.`)}catch{}let m=/* @__PURE__ */ new Set,ee=[...f].reverse();for(let e of ee)if(!m.has(e))try{let t=await pe(e);if(m.add(e),t.isDirectory())await E(e,p,{recursive:!0,force:!0}),console.log(` Copied custom assets: ${e} → ${p}`);else if(t.isFile()){let t=b.basename(e);await O(p,{recursive:!0}),await T(e,b.join(p,t)),console.log(` Copied custom asset file: ${e} → ${p}`)}}catch{}}async function ko(e,t,n){let r=e.theme||{};if(!r.stylesheet)return;let i=n?b.dirname(b.resolve(n)):w.cwd(),a=To(i),o=await Do(Q(r.stylesheet,i,a));if(!o)return;let s=r.stylesheet.replace(/^(pages\/)?(resources\/|deps\/|main\/)?/,``),c=b.join(t,s);try{await O(b.dirname(c),{recursive:!0}),await T(o,c),console.log(` Copied theme stylesheet: ${o} → ${c}`)}catch(e){console.warn(` Warning: Could not copy theme stylesheet ${o}: ${e.message}`)}}async function Ao(e,t,n){let r=(e.customElements&&typeof e.customElements==`object`&&!Array.isArray(e.customElements)?e.customElements?.scripts:void 0)||e.scripts||[];if(!Array.isArray(r)||r.length===0)return;let i=n?b.dirname(b.resolve(n)):w.cwd(),a=To(i);for(let e of r){let n=typeof e==`string`?e:e?.src;if(!n||n.startsWith(`http://`)||n.startsWith(`https://`)||n.startsWith(`//`))continue;let r=await Do(Q(n,i,a));if(r){let e=n.replace(/^(pages\/)?(resources\/|deps\/|main\/)?/,``),i=b.join(t,e);try{await O(b.dirname(i),{recursive:!0}),await T(r,i),console.log(` Copied custom script: ${r} → ${i}`)}catch(e){console.warn(` Warning: Could not copy custom script ${r}: ${e.message}`)}}}}async function jo(e,t,n){let r=e.branding||{},i=e.pwa||{},a=n?b.dirname(b.resolve(n)):w.cwd(),o=To(a),s=[],c=await Do(Q(i.manifestPath||e.manifestPath||`manifest.json`,a,o));if(c){let e=await ho(c);e&&Array.isArray(e.icons)&&(s=e.icons.map(e=>e?.src).filter(Boolean))}let l=[r.faviconPath,r.appleTouchIconPath,`assets/icons/favicon.svg`,`assets/icons/favicon.ico`,`favicon.svg`,`favicon.ico`,`pages/resources/assets/icons/favicon.svg`,`pages/resources/assets/icons/favicon.ico`,`pages/resources/favicon.svg`,`pages/deps/favicon.svg`,`pages/main/favicon.svg`,...Array.isArray(i.icons)?i.icons.map(e=>e.src):[],...s].filter(e=>!!e&&typeof e==`string`&&!e.startsWith(`http://`)&&!e.startsWith(`https://`)&&!e.startsWith(`//`));if(l.length===0)return;let u=/* @__PURE__ */ new Set,d=/* @__PURE__ */ new Set;for(let e of l){if(u.has(e))continue;u.add(e);let n=await Do(Q(e,a,o));if(n){let r=e.replace(/^(pages\/)?(resources\/|deps\/|main\/)?/,``),i=b.join(t,r);if(d.has(i))continue;d.add(i);try{await O(b.dirname(i),{recursive:!0}),await T(n,i),console.log(` Copied branding asset: ${n} → ${i}`)}catch(e){console.warn(` Warning: Could not copy branding asset ${n}: ${e.message}`)}}}}async function Mo(e,t){let n=await ho(t);if(!n)return console.log(`No site-config.json found — skipping site configuration.`),{applied:!1};console.log(`Applying site-config.json...`);let r=w.env.PAGES_ORIGIN||``,i=w.env.PAGES_BASE_PATH||``;await Oo(n,e,t);let a=t?b.dirname(b.resolve(t)):w.cwd(),o=To(a),s;if(n.sidebar?.slotHtml)s=n.sidebar.slotHtml;else if(n.sidebar?.sections)s=vo(n.sidebar.sections);else{let e=await Do([n.sidebar?.slotPath,`pages/main/sidebar.html`,`pages/sidebar.html`,`sidebar.html`,`resources/sidebar.html`].filter(Boolean).flatMap(e=>Q(e,a,o)));e&&(s=await go(e)??void 0,console.log(` Found slotted sidebar: ${e}`))}let c=b.join(e,`index.html`),l=await go(c);l&&(await _o(c,yo(l,n,s)),console.log(` Patched index.html`));let u=b.join(e,`manifest.json`),d=await go(u);d&&(await _o(u,xo(d,n)),console.log(` Patched manifest.json`));let f=b.join(e,`sitemap.xml`),p=!!await go(b.join(e,`sitemap.txt`)),m=!1;if(!await go(f)&&!p){let e=await Eo(a,o,r||n.branding?.siteUrl||``);e&&(await _o(f,e),m=!0,console.log(` Generated sitemap.xml from routes.json`))}let ee=m?``:await go(f);ee&&(await _o(f,So(ee,r)),console.log(` Patched sitemap.xml`));let h=b.join(e,`sitemap.txt`),g=await go(h);g&&(await _o(h,So(g,r)),console.log(` Patched sitemap.txt`));let _=b.join(e,`404.html`),v=await go(_);return v&&(await _o(_,Co(v,n,i)),console.log(` Patched 404.html`)),await ko(n,e,t),await Ao(n,e,t),await jo(n,e,t),console.log(`Site configuration applied successfully.`),{applied:!0}}async function No(){let[e,t]=w.argv.slice(2);(!e||!t)&&(console.error(`Usage: node bin/site-config/apply.mjs <distPublicDir> <siteConfigPath>`),w.exit(1)),await Mo(e,t)}w.argv[1]&&b.resolve(w.argv[1])===b.resolve(ie(import.meta.url))&&No().catch(e=>{console.error(`site-config/apply.ts failed:`,e),w.exit(1)});async function Po(t,{writeFileImpl:n=A}={}){let r=t||x(e(import.meta.url),`dist`,`public`);await n(x(r,`.nojekyll`),``,`utf-8`)}w.argv[1]&&b.resolve(w.argv[1])===b.resolve(ie(import.meta.url))&&await Po();const Fo=e(import.meta.url);async function $(e){try{return await pe(e),!0}catch{return!1}}async function Io(e={}){let t=e.quiet??(process.env.NODE_ENV===`test`&&!process.env.VERBOSE),n=e.stdio??(process.env.NODE_ENV===`test`&&!process.env.VERBOSE?`pipe`:`inherit`),r=(...e)=>{t||console.log(...e)};async function i(e,r={}){!t&&!r.quiet&&console.log(`> ${e}`);let i=r.stdio??n;ce(e,{stdio:i,...r})}let a=C(e.contentRoot||oe.SHADOWCLAW_CONTENT_ROOT||process.cwd()),o=C(e.toolchainRoot||Fo),s=a===o,{isProduction:l,copyAllAssets:u,prerenderPages:d,prerenderMainMemory:f}=eo({...oe,...e.isProduction===void 0?{}:{NODE_ENV:e.isProduction?`production`:`development`},...e.copyAllAssets===void 0?{}:{COPY_ALL_ASSETS:String(e.copyAllAssets)},...e.prerenderPages===void 0?{}:{PRERENDER_PAGES:String(e.prerenderPages)},...e.prerenderMainMemory===void 0?{}:{PRERENDER_MAIN_MEMORY:String(e.prerenderMainMemory)}});if(s){if(ae(Fo),await qa(`dist/public`),await O(`dist/public/assets`,{recursive:!0}),u)await E(`assets`,`dist/public`,{recursive:!0});else{await E(`assets/icons`,`dist/public/assets/icons`,{recursive:!0}),await E(`assets/screenshots`,`dist/public/assets/screenshots`,{recursive:!0});try{await E(`assets/fonts`,`dist/public/assets/fonts`,{recursive:!0})}catch{}}await Ja([`pages/resources`,`pages/deps`,`resources`,`deps`,`pages/assets`,`pages/main/assets`],`dist/public`);for(let e of Za())await Ya(e.sources,e.dest,e.opts||{});try{await E(`e2e/README.md`,`dist/public/e2e/README.md`)}catch{}try{await E(`pages`,`dist/public/pages`,{recursive:!0})}catch{}try{await E(`pages/main`,`dist/public/files/main`,{recursive:!0})}catch{}try{await E(`pages/main`,`dist/public/static-main`,{recursive:!0})}catch{}try{await E(`.agents/skills`,`dist/public/.agents/skills`,{recursive:!0})}catch{}try{await E(`.agents/tools`,`dist/public/.agents/tools`,{recursive:!0})}catch{}try{await E(`.agents/scripts`,`dist/public/.agents/scripts`,{recursive:!0})}catch{}if(await $(`.agents/skills`))try{let{generateSkillsIndex:e}=await import(`./chunk-DiQX43Hq.js`);await e(Fo)}catch(e){console.warn(`Notice: Failed to auto-generate agent-skills index:`,e)}if(await $(`.well-known`))try{await E(`.well-known`,`dist/public/.well-known`,{recursive:!0,force:!0})}catch{}await i(`npm run -s rolldown`);let t=await Xa($a())||`pages/site-config.json`;f?await c({indexPath:`dist/public/index.html`,sourcePath:`pages/main`,prerenderPages:d,siteConfigPath:t}):await c({indexPath:`dist/public/index.html`,noSeed:!0,siteConfigPath:t});try{await Mo(`dist/public`,t)}catch{}try{let e=JSON.parse(await k(`package.json`,`utf8`));if(e.version){let t=`dist/public/index.html`,n=await k(t,`utf8`);await A(t,n.replace(/<meta\s+name="version"[^>]*>/,`<meta name="version" content="${e.version}" />`),`utf8`);for(let t of[`.well-known/mcp.json`,`.well-known/mcp/server-card.json`]){let n=x(`dist/public`,t);if(await $(n))try{let t=JSON.parse(await k(n,`utf8`));t.version!==e.version&&(t.version=e.version,await A(n,JSON.stringify(t,null,2)+`
31
- `,`utf8`))}catch{}}}}catch{}if(l){r(`Running production post-build steps...`);let t=e.pagesOrigin||oe.PAGES_ORIGIN,n=e.basePath||(oe.PAGES_BASE_PATH??`/shadow-claw/`);if(r(` PAGES_ORIGIN : ${t||`(relative ./)`}`),r(` PAGES_BASE_PATH: ${n}`),t)try{let e=`dist/public/manifest.json`,n=await k(e,`utf8`),r=JSON.parse(n);r.start_url&&(r.start_url=t,await A(e,JSON.stringify(r,null,2),`utf8`))}catch{}try{let e=`dist/public/index.html`,t=await k(e,`utf8`);t=t.replace(/<base\s+href="[^"]*"\s*\/?>/i,`<base href="${n}" />`),await A(e,t,`utf8`)}catch{}await Po(`dist/public`);let a=``;try{a=ce(`npm run -s build:pkg:get:meta`,{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim()}catch{}a&&await i(`npm run -s build:pkg:meta "${a}"`)}await io({publicDir:`dist/public`,routesPath:await Xa(Qa())||`pages/routes.json`,sourcePath:`pages/main`,prerenderPages:d,siteConfigPath:t}),await i(`npm run -s build:service-worker`);let n=`dist/public/service-worker.js`;await $(n)&&await te(n,{logImpl:()=>{}}),r(`Build completed successfully.`);return}let p=e.outDir||`dist/public`,m=C(a,p);await O(m,{recursive:!0}),await O(x(m,`assets`),{recursive:!0});let ee=x(o,`dist/public`);await $(x(ee,`index.js`))||(r(`Building ShadowClaw core toolchain...`),await qa(x(o,`dist/public`)),await qa(x(o,`dist-electron`)),await i(`npm run -s rolldown`,{cwd:o})),await E(ee,m,{recursive:!0,filter:e=>!(e.includes(`/assets/cache/`)||e.includes(`\\assets\\cache\\`)||e.includes(`/.cache/`)||e.includes(`\\.cache\\`))}),a!==o&&(await qa(x(m,`sitemap.xml`)),await qa(x(m,`sitemap.txt`)));let h=x(a,`assets`);await $(h)&&(u?await E(h,m,{recursive:!0,force:!0}):(await $(x(h,`icons`))&&await E(x(h,`icons`),x(m,`assets/icons`),{recursive:!0,force:!0}),await $(x(h,`screenshots`))&&await E(x(h,`screenshots`),x(m,`assets/screenshots`),{recursive:!0,force:!0}),await $(x(h,`fonts`))&&await E(x(h,`fonts`),x(m,`assets/fonts`),{recursive:!0,force:!0}))),await Ja([`pages/resources`,`pages/deps`,`resources`,`deps`,`pages/assets`,`pages/main/assets`],m,{baseDir:a});let g=Za({contentRoot:a,toolchainRoot:o,distPublicDir:m});for(let e of g)await Ya(e.sources,e.dest,e.opts||{});let _=x(a,`pages`);await $(_)&&await E(_,x(m,`pages`),{recursive:!0,force:!0});let v=x(a,`pages/main`);await $(v)&&(await E(v,x(m,`files/main`),{recursive:!0,force:!0}),await E(v,x(m,`static-main`),{recursive:!0,force:!0}));let y=x(a,`.agents/skills`);await $(y)&&await E(y,x(m,`.agents/skills`),{recursive:!0,force:!0});let ne=x(o,`.agents/skills`);a!==o&&await $(ne)&&await E(ne,x(m,`.agents/skills`),{recursive:!0,force:!1,errorOnExist:!1});let b=x(a,`.agents/tools`);if(await $(b))await E(b,x(m,`.agents/tools`),{recursive:!0,force:!0});else{let e=x(o,`.agents/tools`);await $(e)&&await E(e,x(m,`.agents/tools`),{recursive:!0,force:!0})}let S=x(a,`.agents/scripts`);if(await $(S))await E(S,x(m,`.agents/scripts`),{recursive:!0,force:!0});else{let e=x(o,`.agents/scripts`);await $(e)&&await E(e,x(m,`.agents/scripts`),{recursive:!0,force:!0})}let re=x(o,`.well-known`);await $(re)&&await E(re,x(m,`.well-known`),{recursive:!0,force:!0});let ie=x(a,`.well-known`);if(a!==o&&await $(ie)&&await E(ie,x(m,`.well-known`),{recursive:!0,force:!0}),await $(x(m,`.agents/skills`)))try{let{generateSkillsIndex:e}=await import(`./chunk-DiQX43Hq.js`);if(await e(m,{metadataRoot:a,outDir:`.well-known/agent-skills`,toolchainRoot:o,includeBundled:!0}),await $(y))try{await e(a,{toolchainRoot:o,includeBundled:!0})}catch{}}catch(e){console.warn(`Notice: Failed to auto-generate agent-skills index:`,e)}let w=await Xa($a(a)),se=w||x(a,`pages/site-config.json`),T=f;if(e.prerenderMainMemory===void 0&&w)try{JSON.parse(await k(w,`utf8`))?.settings?.overridePrerenderSkeleton===!1&&(T=!1,r(` site-config: overridePrerenderSkeleton=false — skeleton overlay disabled.`))}catch{}let D=x(m,`index.html`);T&&await $(v)?await c({indexPath:D,sourcePath:v,prerenderPages:d,siteConfigPath:se}):await c({indexPath:D,noSeed:!0,siteConfigPath:se});try{await Mo(m,se)}catch{}let le=l?e.basePath||oe.PAGES_BASE_PATH||`/`:e.basePath||`/`;try{let e=await k(D,`utf8`);e=e.replace(/<base\s+href="[^"]*"\s*\/?>/i,`<base href="${le}" />`);let t=``;try{let e=await Xa([x(a,`package.json`),x(o,`package.json`)]);e&&(t=JSON.parse(await k(e,`utf8`)).version||``)}catch{}if(t){e=e.replace(/<meta\s+name="version"[^>]*>/,`<meta name="version" content="${t}" />`);for(let e of[`.well-known/mcp.json`,`.well-known/mcp/server-card.json`]){let n=x(m,e);if(await $(n))try{let e=JSON.parse(await k(n,`utf8`));e.version!==t&&(e.version=t,await A(n,JSON.stringify(e,null,2)+`
31
+ `,`utf8`))}catch{}}}}catch{}if(l){r(`Running production post-build steps...`);let t=e.pagesOrigin||oe.PAGES_ORIGIN,n=e.basePath||(oe.PAGES_BASE_PATH??`/shadow-claw/`);if(r(` PAGES_ORIGIN : ${t||`(relative ./)`}`),r(` PAGES_BASE_PATH: ${n}`),t)try{let e=`dist/public/manifest.json`,n=await k(e,`utf8`),r=JSON.parse(n);r.start_url&&(r.start_url=t,await A(e,JSON.stringify(r,null,2),`utf8`))}catch{}try{let e=`dist/public/index.html`,t=await k(e,`utf8`);t=t.replace(/<base\s+href="[^"]*"\s*\/?>/i,`<base href="${n}" />`),await A(e,t,`utf8`)}catch{}await Po(`dist/public`);let a=``;try{a=ce(`npm run -s build:pkg:get:meta`,{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim()}catch{}a&&await i(`npm run -s build:pkg:meta "${a}"`)}await io({publicDir:`dist/public`,routesPath:await Xa(Qa())||`pages/routes.json`,sourcePath:`pages/main`,prerenderPages:d,siteConfigPath:t}),await i(`npm run -s build:service-worker`);let n=`dist/public/service-worker.js`;await $(n)&&await te(n,{logImpl:()=>{}}),r(`Build completed successfully.`);return}let p=e.outDir||`dist/public`,m=C(a,p);await O(m,{recursive:!0}),await O(x(m,`assets`),{recursive:!0});let ee=x(o,`dist/public`);await $(x(ee,`index.js`))||(r(`Building ShadowClaw core toolchain...`),await qa(x(o,`dist/public`)),await qa(x(o,`dist-electron`)),await i(`npm run -s rolldown`,{cwd:o})),await E(ee,m,{recursive:!0,filter:e=>!(e.includes(`/assets/cache/`)||e.includes(`\\assets\\cache\\`)||e.includes(`/.cache/`)||e.includes(`\\.cache\\`)||e.includes(`/cache/`)||e.includes(`\\cache\\`)||e.endsWith(`/cache`)||e.endsWith(`\\cache`))}),a!==o&&(await qa(x(m,`sitemap.xml`)),await qa(x(m,`sitemap.txt`)));let h=x(a,`assets`);await $(h)&&(u?await E(h,m,{recursive:!0,force:!0}):(await $(x(h,`icons`))&&await E(x(h,`icons`),x(m,`assets/icons`),{recursive:!0,force:!0}),await $(x(h,`screenshots`))&&await E(x(h,`screenshots`),x(m,`assets/screenshots`),{recursive:!0,force:!0}),await $(x(h,`fonts`))&&await E(x(h,`fonts`),x(m,`assets/fonts`),{recursive:!0,force:!0}))),await Ja([`pages/resources`,`pages/deps`,`resources`,`deps`,`pages/assets`,`pages/main/assets`],m,{baseDir:a});let g=Za({contentRoot:a,toolchainRoot:o,distPublicDir:m});for(let e of g)await Ya(e.sources,e.dest,e.opts||{});let _=x(a,`pages`);await $(_)&&await E(_,x(m,`pages`),{recursive:!0,force:!0});let v=x(a,`pages/main`);await $(v)&&(await E(v,x(m,`files/main`),{recursive:!0,force:!0}),await E(v,x(m,`static-main`),{recursive:!0,force:!0}));let y=x(a,`.agents/skills`);await $(y)&&await E(y,x(m,`.agents/skills`),{recursive:!0,force:!0});let ne=x(o,`.agents/skills`);a!==o&&await $(ne)&&await E(ne,x(m,`.agents/skills`),{recursive:!0,force:!1,errorOnExist:!1});let b=x(a,`.agents/tools`);if(await $(b))await E(b,x(m,`.agents/tools`),{recursive:!0,force:!0});else{let e=x(o,`.agents/tools`);await $(e)&&await E(e,x(m,`.agents/tools`),{recursive:!0,force:!0})}let S=x(a,`.agents/scripts`);if(await $(S))await E(S,x(m,`.agents/scripts`),{recursive:!0,force:!0});else{let e=x(o,`.agents/scripts`);await $(e)&&await E(e,x(m,`.agents/scripts`),{recursive:!0,force:!0})}let re=x(o,`.well-known`);await $(re)&&await E(re,x(m,`.well-known`),{recursive:!0,force:!0});let ie=x(a,`.well-known`);if(a!==o&&await $(ie)&&await E(ie,x(m,`.well-known`),{recursive:!0,force:!0}),await $(x(m,`.agents/skills`)))try{let{generateSkillsIndex:e}=await import(`./chunk-DiQX43Hq.js`);if(await e(m,{metadataRoot:a,outDir:`.well-known/agent-skills`,toolchainRoot:o,includeBundled:!0}),await $(y))try{await e(a,{toolchainRoot:o,includeBundled:!0})}catch{}}catch(e){console.warn(`Notice: Failed to auto-generate agent-skills index:`,e)}let w=await Xa($a(a)),se=w||x(a,`pages/site-config.json`),T=f;if(e.prerenderMainMemory===void 0&&w)try{JSON.parse(await k(w,`utf8`))?.settings?.overridePrerenderSkeleton===!1&&(T=!1,r(` site-config: overridePrerenderSkeleton=false — skeleton overlay disabled.`))}catch{}let D=x(m,`index.html`);T&&await $(v)?await c({indexPath:D,sourcePath:v,prerenderPages:d,siteConfigPath:se}):await c({indexPath:D,noSeed:!0,siteConfigPath:se});try{await Mo(m,se)}catch{}let le=l?e.basePath||oe.PAGES_BASE_PATH||`/`:e.basePath||`/`;try{let e=await k(D,`utf8`);e=e.replace(/<base\s+href="[^"]*"\s*\/?>/i,`<base href="${le}" />`);let t=``;try{let e=await Xa([x(a,`package.json`),x(o,`package.json`)]);e&&(t=JSON.parse(await k(e,`utf8`)).version||``)}catch{}if(t){e=e.replace(/<meta\s+name="version"[^>]*>/,`<meta name="version" content="${t}" />`);for(let e of[`.well-known/mcp.json`,`.well-known/mcp/server-card.json`]){let n=x(m,e);if(await $(n))try{let e=JSON.parse(await k(n,`utf8`));e.version!==t&&(e.version=t,await A(n,JSON.stringify(e,null,2)+`
32
32
  `,`utf8`))}catch{}}}await A(D,e,`utf8`)}catch{}if(l){r(`Running production post-build steps...`);let t=e.pagesOrigin||oe.PAGES_ORIGIN;if(r(` PAGES_ORIGIN : ${t||`(relative ./)`}`),r(` PAGES_BASE_PATH: ${le}`),t)try{let e=x(m,`manifest.json`),n=await k(e,`utf8`),r=JSON.parse(n);r.start_url&&(r.start_url=t,await A(e,JSON.stringify(r,null,2),`utf8`))}catch{}await A(x(m,`.nojekyll`),``,`utf8`);let n=``;try{n=ce(`git rev-parse HEAD`,{cwd:a,encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim()}catch{try{n=ce(`git rev-parse HEAD`,{cwd:o,encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim()}catch{}}if(n){let e=await k(D,`utf8`);await A(D,e.replace(/<meta\s+name="revision"[^>]*>/,`<meta name="revision" content="${n}" />`),`utf8`)}}await io({publicDir:m,routesPath:await Xa(Qa(a))||x(a,`pages/routes.json`),sourcePath:await $(v)?v:x(o,`pages/main`),prerenderPages:d,siteConfigPath:se});let ue=x(m,`service-worker.js`);await $(ue)&&await te(ue,{logImpl:()=>{}}),r(`Build completed successfully.`)}process.argv[1]&&C(process.argv[1])===C(ie(import.meta.url))&&Io().catch(e=>{console.error(e),se(1)});export{Io as t};
package/dist/cli/cli.js CHANGED
@@ -1,4 +1,4 @@
1
- import{t as e}from"./chunk-uAI_Zi6n.js";import{f as t,p as n,r}from"./chunk-Dz5_hgvL.js";import{t as i}from"./chunk-DYq-orHK.js";import{c as a,i as o,o as s,s as c}from"./chunk-YrgA1KKk.js";import{t as l}from"./chunk-sC-eQ-Nh.js";import{t as u}from"./chunk-Cpdoq2Nw.js";import{n as d}from"./chunk-NC8XsSSA.js";import{t as f}from"./chunk-BiWLawPV.js";import{r as p}from"./chunk-BM1nUAbW.js";import m from"node:fs";import h from"node:path";import{fileURLToPath as g}from"node:url";import _ from"node:process";import{exec as v}from"node:child_process";import{mkdir as y,mkdtemp as b,readFile as x,stat as S,writeFile as C}from"node:fs/promises";import{Command as w}from"commander";import T from"process";import E from"node:http";import{tmpdir as D}from"node:os";import ee from"node:readline";async function O(e={}){let t=new l(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}`),T.exitCode=1}}async function te(e,t={}){if(!e||typeof e!=`string`||!e.trim()){console.error(`Error: Message cannot be empty.`),T.exitCode=1;return}let n=new l(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.`),T.exitCode=1;return}r=e[0].clientId,console.log(`Targeting client: ${e[0].deviceLabel||r} (${r})`)}let i=r||``,a=t.timeout?Number(t.timeout)*1e3:12e4,o;if(t.file?(console.log(`Sending message with file "${t.file}" to ${i}...`),o=await n.sendFile(i,t.file,{prompt:e.trim(),groupId:t.group,timeoutMs:a})):(console.log(`Sending message to ${i}...`),o=await n.sendCommand(i,`send-message`,{text:e.trim(),groupId:t.group},a)),o.success){if(console.log(`Message successfully dispatched.`),o.data?.reply||o.data?.text){let e=o.data.reply||o.data.text;console.log(``),console.log(`Response from ${i}:`),console.log(`----------------------------------------`),console.log(e),console.log(`----------------------------------------`)}else o.data&&(t.json,console.log(JSON.stringify(o.data,null,2)))}else console.error(`Error from client: ${o.error||`Unknown error`}`),T.exitCode=1}catch(e){console.error(`Error sending message: ${e.message}`),T.exitCode=1}}async function k(e,t={}){if(!e||typeof e!=`string`||!e.trim()){console.error(`Error: File path cannot be empty.`),T.exitCode=1;return}let n=h.resolve(e.trim());if(!m.existsSync(n)){console.error(`Error: File not found: ${e}`),T.exitCode=1;return}let r=m.statSync(n);if(r.isDirectory()){console.error(`Error: Cannot send directory: ${e}`),T.exitCode=1;return}let i=new l(t);try{let e=t.client;if(!e){let t=await i.listClients();if(!t||t.length===0){console.error(`Error: No clients are connected.`),T.exitCode=1;return}e=t[0].clientId,console.log(`Targeting client: ${t[0].deviceLabel||e} (${e})`)}let a=e||``,o=t.name||h.basename(n);console.log(`Sending "${o}" (${r.size} bytes) to ${a}...`);let s=t.timeout?Number(t.timeout)*1e3:12e4,c=await i.sendFile(a,n,{prompt:t.prompt,name:t.name,groupId:t.group,timeoutMs:s});if(c.success){if(console.log(`File "${o}" successfully transferred to ${a}.`),c.data?.path&&console.log(`Remote location: ${c.data.path}`),c.data?.reply||c.data?.text){let e=c.data.reply||c.data.text;console.log(``),console.log(`Response from ${a}:`),console.log(`----------------------------------------`),console.log(e),console.log(`----------------------------------------`)}else t.json&&c.data&&console.log(JSON.stringify(c.data,null,2))}else console.error(`Error from client: ${c.error||`Unknown error`}`),T.exitCode=1}catch(e){console.error(`Error sending file: ${e.message}`),T.exitCode=1}}async function A(e=`trigger`,t={}){let n=new l(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/1048576).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.`),T.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.`),T.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}`),T.exitCode=1)}catch(e){console.error(`Error executing backup command: ${e.message}`),T.exitCode=1}}async function j(e={}){let t=new l(e);try{let n=e.client;if(!n){let e=await t.listClients();if(!e||e.length===0){console.error(`Error: No clients connected.`),T.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}`),T.exitCode=1}catch(e){console.error(`Error executing tasks command: ${e.message}`),T.exitCode=1}}async function M(e=`get`,t={}){let n=t.cacheDir,r=o(n),i=!!(t.renew||e===`renew`||e===`generate`||e===`new`),l=t.set||(e===`set`&&t.id?t.id:null),u=``,d=!1;if(l)u=a(l,n),d=!0;else if(i)u=a(void 0,n),d=!0;else{let e=c(n);e?(u=e,d=!1):(u=s(void 0,n),d=!0)}return t.quiet?(console.log(u),{peerId:u,filePath:r,isRenewed:d}):t.json?(console.log(JSON.stringify({peerId:u,filePath:r,renewed:d},null,2)),{peerId:u,filePath:r,isRenewed:d}):(console.log(l?`WebRTC CLI Peer ID set to: ${u}`:d?`WebRTC CLI Peer ID created/renewed: ${u}`:`WebRTC CLI Peer ID: ${u}`),console.log(`Stored in: ${r}`),{peerId:u,filePath:r,isRenewed:d})}function N(e,t){return typeof e==`string`?t===`raw`?e.startsWith(`shadowclaw_client_`)?e.slice(18):e:e.startsWith(`shadowclaw_client_`)?e:`shadowclaw_client_${e}`:e}function P(e){return N(e,`raw`)}function F(e){return N(e,`exposed`)}const I=[{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 (idle, responding, etc.), active group ID, and capabilities from a connected client.`,inputSchema:{type:`object`,properties:{clientId:{type:`string`,description:`Target client ID (defaults to first available connected client).`}}}},{name:`shadowclaw_server_list_tasks`,description:`List scheduled background tasks configured on a connected client (optionally filtered by conversation group).`,inputSchema:{type:`object`,properties:{clientId:{type:`string`,description:`Target client ID (defaults to first available connected client).`},groupId:{type:`string`,description:`Optional conversation group ID filter.`}}}},{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 file backups for a connected client (trigger, list, or delete).`,inputSchema:{type:`object`,properties:{action:{type:`string`,enum:[`trigger`,`list`,`delete`],description:`Backup action to perform (default: 'trigger').`,default:`trigger`},clientId:{type:`string`,description:`Target client ID.`},backupId:{type:`string`,description:`Backup snapshot ID (required for 'delete').`},groupId:{type:`string`,description:`Optional workspace conversation group ID.`}}}},{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 L(e,t){try{let n=typeof e.getConnectedClients==`function`?e.getConnectedClients():typeof e.listClients==`function`?e.listClients():[];if(Array.isArray(n)&&n.length>0){if(typeof t==`string`&&t.trim()){let e=t.trim(),r=n.find(t=>(t.clientId||t.id)===e);if(r)return r.clientId||r.id||``;let i=parseInt(e,10);if(!isNaN(i)&&i>=0&&i<n.length)return n[i].clientId||n[i].id||``;let a=n.find(t=>(t.clientId||t.id||``).startsWith(e)||(t.clientId||t.id||``).replace(/^client-/,``).startsWith(e));if(a)return a.clientId||a.id||``;let o=n.find(t=>t.deviceLabel?.toLowerCase().includes(e.toLowerCase()));return o?o.clientId||o.id||``:e}if(typeof e.getActiveClientId==`function`){let t=e.getActiveClientId();if(t)return t}return n[0].clientId||n[0].id||``}}catch{}return typeof t==`string`?t.trim():``}const ne=h.dirname(g(import.meta.url));function re(){try{let e=h.resolve(ne,`../../../package.json`);if(m.existsSync(e)){let t=JSON.parse(m.readFileSync(e,`utf8`));if(t.version)return t.version}}catch{}return`1.27.1`}const R=`shadowclaw_local_`,ie=I;function z(e,t=R){let n=e.inputSchema||e.input_schema,r=n&&typeof n==`object`?{...n,type:n.type||`object`,properties:n.properties||{}}:{type:`object`,properties:{}};return{name:t?`${t}${e.name}`:e.name,description:e.description||`CLI agent tool: ${e.name}`,inputSchema:r,annotations:e.annotations}}function B(e,t,n){let r=!1,i=[];return Array.isArray(e)?i=e.map(e=>e&&typeof e==`object`?e.type===`image`?{type:`image`,data:e.data||``,mimeType:e.media_type||e.mimeType||`image/png`}:e.type===`text`?{type:`text`,text:String(e.text??``)}:{type:`text`,text:JSON.stringify(e,null,2)}:{type:`text`,text:String(e??``)}):typeof e==`string`?((e.toLowerCase().startsWith(`error`)||e.toLowerCase().startsWith(`tool error`)||e.includes(`SecurityError`)||e.startsWith(`Tool "`)&&e.includes(`is not allowed`)||e.startsWith(`Tool "`)&&e.includes(`is not available`))&&(r=!0),i=[{type:`text`,text:e}]):e&&typeof e==`object`?((e.error||e.success===!1)&&(r=!0),i=[{type:`text`,text:JSON.stringify(e,null,2)}]):i=[{type:`text`,text:String(e??``)}],{jsonrpc:`2.0`,id:n,result:{resultType:`complete`,isError:r,content:i,_meta:{"io.modelcontextprotocol/serverInfo":t}}}}function V(e={}){let n=e.client||new l(e),r=e.relayClientTools!==!1,i=e.targetClientId||e.clientTarget,a=i||``,o={name:`shadow-claw`,version:e.version||re()},s={tools:{listChanged:!0},extensions:{"io.modelcontextprotocol/tasks":{}}};async function c(e){let t=e||a||i;try{let e=await n.listClients();return L({getConnectedClients:()=>e},t)}catch{}return L(n,t)}let d=/* @__PURE__ */ new Map,p=/* @__PURE__ */ new Map,m=e.localTools!==!1,g=e.toolPrefix??`local`,_=g===`none`||g===``?``:g===`shadowclaw`?`shadowclaw_`:R,v=/* @__PURE__ */ new Map,x=null;async function S(){return x||=(async()=>{if(e.core&&e.db){let t;if(e.workspaceDir||e.workspace)t=e.workspaceDir||e.workspace;else{let e=h.join(D(),`shadow-claw`);await y(e,{recursive:!0}),t=await b(h.join(e,`workspace-`))}return{db:e.db,workspaceDir:t,core:e.core}}let n=e.core||await f(),r=e.workspaceDir||e.workspace,i=null,a=null,o=null;if(r)i=h.resolve(r),a=e.cacheDir?h.resolve(e.cacheDir):h.join(i,`.cache`),o=e.databaseDir?h.resolve(e.databaseDir):h.join(a,`database`);else try{let t=h.join(D(),`shadow-claw`);await y(t,{recursive:!0}),i=await b(h.join(t,`workspace-`)),a=e.cacheDir?h.resolve(e.cacheDir):await b(h.join(t,`cache-`)),o=e.databaseDir?h.resolve(e.databaseDir):h.join(a,`database`),await y(a,{recursive:!0}),await y(o,{recursive:!0})}catch(e){return console.error(`[ShadowClaw MCP] Warning: No --workspace provided and failed to initialize temporary fallback workspace (${e.message}). Local workspace tools are disabled.`),null}try{let r=await t({...e,workspace:i,cacheDir:a,databaseDir:o,yes:!0,quiet:!0,isTTY:!1,core:n});return{db:r.db,workspaceDir:r.workspaceDir,core:r.core}}catch(e){return console.error(`[ShadowClaw MCP] Warning: Failed to bootstrap headless agent context (${e.message}). Local workspace tools are disabled.`),null}})(),x}async function C(){if(!m)return[];let t;try{t=await S()}catch(e){return console.error(`[ShadowClaw MCP] Failed to initialize local agent context: ${e.message}`),[]}if(!t)return[];let{db:n,core:r}=t,i=e.group||r.DEFAULT_SERVER_GROUP_ID||`server:main`,a=null;if(e.toolsProfile||e.profile){let t=String(e.toolsProfile||e.profile).trim().toLowerCase(),i=r.DEFAULT_BUILTIN_PROFILE||null,o=[];if(typeof r.getConfig==`function`)try{let e=await r.getConfig(n,r.CONFIG_KEYS?.TOOL_PROFILES||`tool_profiles`);typeof e==`string`?o=JSON.parse(e):Array.isArray(e)&&(o=e)}catch{}let s=[i,...o].filter(Boolean).find(e=>e.id&&String(e.id).toLowerCase()===t||e.name&&String(e.name).toLowerCase()===t);s&&(a=new Set(s.enabledToolNames||[]))}let o=null;if(e.tools&&typeof e.tools==`string`&&e.tools.trim()){let t=e.tools.split(`,`).map(e=>e.trim()).filter(Boolean);o=new Set(t)}let s=[...r.TOOL_DEFINITIONS||[]];if(typeof r.loadDeclarativeTools==`function`)try{let e=await r.loadDeclarativeTools(n,i);if(e&&Array.isArray(e.tools))for(let t of e.tools)s.some(e=>e.name===t.name)||s.push(t)}catch{}let c=r.BROWSER_ONLY_TOOLS||u;v.clear();let l=[];for(let e of s){if(!e||!e.name||c&&c.has(e.name)||o&&!o.has(e.name)||a&&!a.has(e.name))continue;let t=z(e,_);v.set(e.name,e),v.set(`shadowclaw_local_${e.name}`,e),v.set(`shadowclaw_${e.name}`,e),l.push(t)}return l}async function w(t,n,r){try{let i=await S();if(!i)return{jsonrpc:`2.0`,id:r,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error: Local workspace tools are not initialized.`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}};let a=e.group||i.core.DEFAULT_SERVER_GROUP_ID||`server:main`,s;try{let{resolveAgentProvider:t}=await import(`./chunk-DtgZDsJA.js`),n=await t(i.db,i.core,i.workspaceDir,{...e,interactive:!1});s={db:i.db,provider:n.providerId,model:n.model,apiKey:n.apiKey}}catch{}return console.error(`[ShadowClaw MCP] Executing local tool '${t.name}' in workspace: ${i.workspaceDir}`),B(await i.core.executeTool(i.db,t.name,n,a,{invokeContext:s}),o,r)}catch(e){return{jsonrpc:`2.0`,id:r,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error executing local tool '${t.name}': ${e.message||String(e)}`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}}async function T(){if(!r)return[];let e=[];try{e=await n.listClients()}catch{}if(!Array.isArray(e)||e.length===0)return d.clear(),p.clear(),[];d.clear(),p.clear();for(let t of e){let e=t.clientId||t.id;if(e)try{let r=await n.sendCommand(e,`list-tools`,{});if(r&&r.success&&r.data?.tools&&Array.isArray(r.data.tools))for(let e of r.data.tools){let n=P(e.name);n===`send_notification`||n.startsWith(`shadowclaw_`)&&!n.startsWith(`shadowclaw_client_`)||(p.has(n)||(p.set(n,e),d.set(n,[])),d.get(n).push(t))}}catch{}}let t=await c(),i=[];for(let[n,r]of p.entries()){let a=d.get(n)||[],o=a.map(e=>e.clientId||e.id).filter(Boolean),s=a.find(e=>(e.clientId||e.id)===t)||a[0],c=s?.clientId||s?.id||``,l=s?.deviceLabel||`Client`,u=r.inputSchema&&typeof r.inputSchema==`object`?r.inputSchema:{type:`object`,properties:{}},f={...u.properties||{},clientId:{type:`string`,description:`Target ShadowClaw client ID (optional; defaults to ${c} [${l}]). Available on: ${a.map(e=>`${e.clientId||e.id} (${e.deviceLabel||`Client`})`).join(`, `)}`,enum:o}},p=e.length>1?a.length>1?` [Default: ${l} (${c.slice(0,14)}...)]`:` [Client: ${l} (${c.slice(0,14)}...)]`:``,m=F(n);i.push({name:m,description:(r.description||`Relayed tool '${n}' from connected client.`)+p,inputSchema:{...u,type:`object`,properties:f},annotations:r.annotations})}return i}async function E(e,t={}){let i=e.id===void 0||e.id===null,l=e.id??null;if(t[`mcp-method`]&&t[`mcp-method`]!==e.method)return{jsonrpc:`2.0`,id:l,error:{code:-32020,message:`Mcp-Method header '${t[`mcp-method`]}' does not match '${e.method}'`}};switch(e.method){case`server/discover`:return{jsonrpc:`2.0`,id:l,result:{protocolVersion:`2026-07-28`,supportedProtocolVersions:[`2026-07-28`,`2025-11-25`,`2024-11-05`],capabilities:s,serverInfo:o,_meta:{"io.modelcontextprotocol/serverInfo":o}}};case`initialize`:return{jsonrpc:`2.0`,id:l,result:{protocolVersion:e.params?.protocolVersion||`2024-11-05`,capabilities:s,serverInfo:o}};case`notifications/initialized`:return null;case`tools/list`:{let e=[];try{if(typeof n.listPushClients==`function`)e=await n.listPushClients();else if(typeof n.listPushSubscriptions==`function`){let t=await n.listPushSubscriptions();if(Array.isArray(t)){let n=/* @__PURE__ */ new Map;for(let e of t){let t=(e.client_id||``).trim()||(e.id?String(e.id):``);t&&!n.has(t)&&n.set(t,{clientId:t,deviceLabel:e.device_label||void 0})}e=Array.from(n.values())}}}catch{}let t=Array.isArray(e)?[...e].sort((e,t)=>(e.clientId||``).localeCompare(t.clientId||``)):[],r=t.map(e=>e.clientId).filter(Boolean),i=await T(),a=await C(),s=/* @__PURE__ */ new Map;for(let e of ie)s.set(e.name,e);for(let e of a)s.has(e.name)||s.set(e.name,e);for(let e of i)s.has(e.name)||s.set(e.name,e);if(r.length>0)for(let e of[`shadowclaw_server_send_notification`,`shadowclaw_send_notification`]){let n=s.get(e);n&&s.set(e,{...n,inputSchema:{...n.inputSchema,type:`object`,properties:{...n.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: ${t.map(e=>`${e.clientId} (${e.deviceLabel||`Client`})`).join(`, `)}`,enum:r}}}})}return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,ttlMs:5e3,cacheScope:`private`,tools:Array.from(s.values()).sort((e,t)=>e.name.localeCompare(t.name)),_meta:{"io.modelcontextprotocol/serverInfo":o}}}}case`tools/call`:{let t=e.params?.name,i=e.params?.arguments||{},s=e.params?.inputResponses;if(!t)return{jsonrpc:`2.0`,id:l,error:{code:-32602,message:`Missing required parameter 'name'`}};if(t===`shadowclaw_server_list_clients`||t===`shadowclaw_list_clients`)try{let e=await n.listClients();return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,content:[{type:`text`,text:JSON.stringify({clients:e},null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}catch(e){return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error listing clients: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}if(t===`shadowclaw_server_set_active_client`||t===`shadowclaw_set_active_client`){let e=await c(i.clientId);return e?(a=e,console.error(`[ShadowClaw MCP] Active default client set to: ${a}`),{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,content:[{type:`text`,text:`Active default client set to: ${a}`}],_meta:{activeClientId:a,"io.modelcontextprotocol/serverInfo":o}}}):{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error: Client '${i.clientId}' not found among connected clients.`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}if(t===`shadowclaw_server_send_message`||t===`shadowclaw_send_message`){let e=await c(i.clientId);if(!e)return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error: No connected client available.`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}};try{let t=await n.sendCommand(e,`send-message`,{text:i.text,groupId:i.groupId});return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!t.success,content:[{type:`text`,text:JSON.stringify(t.data||t,null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}catch(e){return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error sending message: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}}if(t===`shadowclaw_server_read_state`||t===`shadowclaw_read_state`){let e=await c(i.clientId);try{let t=await n.sendCommand(e,`read-state`,{});return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!t.success,content:[{type:`text`,text:JSON.stringify(t.data||t,null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}catch(e){return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error reading state: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}}if(t===`shadowclaw_server_list_tasks`||t===`shadowclaw_list_tasks`){let e=await c(i.clientId);try{let t=await n.sendCommand(e,`list-tasks`,{groupId:i.groupId});return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!t.success,content:[{type:`text`,text:JSON.stringify(t.data||t,null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}catch(e){return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error listing tasks: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}}if(t===`shadowclaw_server_manage_backup`||t===`shadowclaw_manage_backup`){let e=i.action||`trigger`,t=await c(i.clientId);try{if(e===`list`){let e=await n.listBackups(t);return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,content:[{type:`text`,text:JSON.stringify({backups:e},null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}if(e===`delete`){let e=await n.deleteBackup(i.backupId,t);return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,content:[{type:`text`,text:JSON.stringify(e,null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}let r=await n.sendCommand(t,`trigger-backup`,{groupId:i.groupId});return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!r.success,content:[{type:`text`,text:JSON.stringify(r.data||r,null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}catch(e){return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error managing backup: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}}if(t===`shadowclaw_server_status`||t===`shadowclaw_status`)try{let e=await n.listClients();return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,content:[{type:`text`,text:JSON.stringify({server:`ShadowClaw`,version:o.version,connectedClients:e.length,status:`healthy`},null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}catch(e){return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error querying server status: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}if(t===`shadowclaw_server_send_notification`||t===`shadowclaw_send_notification`||t===`send_notification`){let e=String(i.body||``).trim();if(!e)return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error: Notification 'body' parameter cannot be empty.`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}};let t=String(i.title||`ShadowClaw`).trim(),r=typeof i.clientId==`string`&&i.clientId.trim()?i.clientId.trim():void 0;try{let i=await n.broadcastNotification({title:t,body:e,...r?{clientId:r}:{}}),a=i?.sent??0,s=i?.failed??0,c;return c=i?.notFound?`Warning: No push subscriptions found for client '${r}'. Ensure push notifications were registered by this client in ShadowClaw Settings.`:i?.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.`:r?`Push notification sent to client '${r}': ${a} recipient(s) delivered, ${s} failed.`:`Push notification broadcast sent: ${a} recipient(s) delivered, ${s} failed.`,{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!1,content:[{type:`text`,text:c}],_meta:{...i,...r?{targetClientId:r}:{},"io.modelcontextprotocol/serverInfo":o}}}}catch(e){return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Failed to send push notification: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}}let u=P(t);if((u===`ask_user`||t===`ask_user`)&&s&&s.response)return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,content:[{type:`text`,text:String(s.response)}],_meta:{"io.modelcontextprotocol/serverInfo":o}}};m&&v.size===0&&await C();let f=t.startsWith(R),h=t.startsWith(`shadowclaw_client_`),_=v.get(t);if(!_&&f&&(_=v.get(t.slice(17))),!_&&t.startsWith(`shadowclaw_`)&&!h&&(_=v.get(t.slice(11))),f&&_){let e={...i};return delete e.clientId,await w(_,e,l)}r&&p.size===0&&await T();let y=(d.get(u)||d.get(t)||[]).map(e=>e.clientId||e.id).filter(Boolean),b=[];try{b=await n.listClients()}catch{}if(!h&&_&&(g===`none`&&!i.clientId||!r||!Array.isArray(b)||b.length===0)){let e={...i};return delete e.clientId,await w(_,e,l)}let x=``;if(i.clientId)x=await c(i.clientId);else{let e=await c();x=y.includes(e)?e:y.length>0?y[0]:e}if(!x)return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error: No connected client available.`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}};if(y.length>0&&!y.includes(x))return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error: Tool '${t}' is not enabled or available on client '${x}'. (Available on: ${y.join(`, `)})`}],_meta:{clientId:x,"io.modelcontextprotocol/serverInfo":o}}};try{console.error(`[ShadowClaw MCP] Executing '${u}' on client: ${x}`);let e={...i};delete e.clientId;let t=u===`ask_user`?await n.sendCommand(x,`invoke-tool`,{toolName:u,input:e},3e5):await n.sendCommand(x,`invoke-tool`,{toolName:u,input:e}),r=t.data?.result===void 0?t.data:t.data.result,a=typeof r==`string`?r:JSON.stringify(r,null,2),s=t.error||t.data&&t.data.error||`Unknown tool execution error`;return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!t.success,content:[{type:`text`,text:t.success?a||``:a&&a!==`null`&&a!==`{}`?`${a}\n${s}`:`Tool execution error: ${s}`}],_meta:{clientId:x,"io.modelcontextprotocol/serverInfo":o}}}}catch(e){return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Tool error: ${e.message}`}],_meta:{clientId:x,"io.modelcontextprotocol/serverInfo":o}}}}}case`tasks/get`:return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,task:{taskId:e.params?.taskId||`task-1`,status:`completed`},_meta:{"io.modelcontextprotocol/serverInfo":o}}};default:return i?null:{jsonrpc:`2.0`,id:l,error:{code:-32601,message:`Method not found: '${e.method}'`}}}}return{handleMessage:E,getActiveClientId:()=>a,setActiveClientId:e=>{a=e},close:async()=>{if(x)try{let e=await x;typeof e?.core?.closeSqliteDatabase==`function`&&e.core.closeSqliteDatabase()}catch{}}}}async function H(e={}){if((e.mcpTransport||(e.http?`http`:`stdio`))===`http`){let t=parseInt(String(e.port||T.env.MCP_PORT||`8888`),10),n=e.host||`127.0.0.1`,r=V(e);E.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),n=ee.createInterface({input:T.stdin,output:T.stdout,terminal:!1});n.on(`line`,async e=>{let n=e.trim();if(!n)return;let r;try{r=JSON.parse(n)}catch{T.stdout.write(JSON.stringify({jsonrpc:`2.0`,id:null,error:{code:-32700,message:`Parse error`}})+`
1
+ import{t as e}from"./chunk-uAI_Zi6n.js";import{f as t,p as n,r}from"./chunk-Dz5_hgvL.js";import{t as i}from"./chunk-BgTv9w0K.js";import{c as a,i as o,o as s,s as c}from"./chunk-YrgA1KKk.js";import{t as l}from"./chunk-sC-eQ-Nh.js";import{t as u}from"./chunk-Cpdoq2Nw.js";import{n as d}from"./chunk-NC8XsSSA.js";import{t as f}from"./chunk-BiWLawPV.js";import{r as p}from"./chunk-BM1nUAbW.js";import m from"node:fs";import h from"node:path";import{fileURLToPath as g}from"node:url";import _ from"node:process";import{exec as v}from"node:child_process";import{mkdir as y,mkdtemp as b,readFile as x,stat as S,writeFile as C}from"node:fs/promises";import{Command as w}from"commander";import T from"process";import E from"node:http";import{tmpdir as D}from"node:os";import ee from"node:readline";async function O(e={}){let t=new l(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}`),T.exitCode=1}}async function te(e,t={}){if(!e||typeof e!=`string`||!e.trim()){console.error(`Error: Message cannot be empty.`),T.exitCode=1;return}let n=new l(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.`),T.exitCode=1;return}r=e[0].clientId,console.log(`Targeting client: ${e[0].deviceLabel||r} (${r})`)}let i=r||``,a=t.timeout?Number(t.timeout)*1e3:12e4,o;if(t.file?(console.log(`Sending message with file "${t.file}" to ${i}...`),o=await n.sendFile(i,t.file,{prompt:e.trim(),groupId:t.group,timeoutMs:a})):(console.log(`Sending message to ${i}...`),o=await n.sendCommand(i,`send-message`,{text:e.trim(),groupId:t.group},a)),o.success){if(console.log(`Message successfully dispatched.`),o.data?.reply||o.data?.text){let e=o.data.reply||o.data.text;console.log(``),console.log(`Response from ${i}:`),console.log(`----------------------------------------`),console.log(e),console.log(`----------------------------------------`)}else o.data&&(t.json,console.log(JSON.stringify(o.data,null,2)))}else console.error(`Error from client: ${o.error||`Unknown error`}`),T.exitCode=1}catch(e){console.error(`Error sending message: ${e.message}`),T.exitCode=1}}async function k(e,t={}){if(!e||typeof e!=`string`||!e.trim()){console.error(`Error: File path cannot be empty.`),T.exitCode=1;return}let n=h.resolve(e.trim());if(!m.existsSync(n)){console.error(`Error: File not found: ${e}`),T.exitCode=1;return}let r=m.statSync(n);if(r.isDirectory()){console.error(`Error: Cannot send directory: ${e}`),T.exitCode=1;return}let i=new l(t);try{let e=t.client;if(!e){let t=await i.listClients();if(!t||t.length===0){console.error(`Error: No clients are connected.`),T.exitCode=1;return}e=t[0].clientId,console.log(`Targeting client: ${t[0].deviceLabel||e} (${e})`)}let a=e||``,o=t.name||h.basename(n);console.log(`Sending "${o}" (${r.size} bytes) to ${a}...`);let s=t.timeout?Number(t.timeout)*1e3:12e4,c=await i.sendFile(a,n,{prompt:t.prompt,name:t.name,groupId:t.group,timeoutMs:s});if(c.success){if(console.log(`File "${o}" successfully transferred to ${a}.`),c.data?.path&&console.log(`Remote location: ${c.data.path}`),c.data?.reply||c.data?.text){let e=c.data.reply||c.data.text;console.log(``),console.log(`Response from ${a}:`),console.log(`----------------------------------------`),console.log(e),console.log(`----------------------------------------`)}else t.json&&c.data&&console.log(JSON.stringify(c.data,null,2))}else console.error(`Error from client: ${c.error||`Unknown error`}`),T.exitCode=1}catch(e){console.error(`Error sending file: ${e.message}`),T.exitCode=1}}async function A(e=`trigger`,t={}){let n=new l(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/1048576).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.`),T.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.`),T.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}`),T.exitCode=1)}catch(e){console.error(`Error executing backup command: ${e.message}`),T.exitCode=1}}async function j(e={}){let t=new l(e);try{let n=e.client;if(!n){let e=await t.listClients();if(!e||e.length===0){console.error(`Error: No clients connected.`),T.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}`),T.exitCode=1}catch(e){console.error(`Error executing tasks command: ${e.message}`),T.exitCode=1}}async function M(e=`get`,t={}){let n=t.cacheDir,r=o(n),i=!!(t.renew||e===`renew`||e===`generate`||e===`new`),l=t.set||(e===`set`&&t.id?t.id:null),u=``,d=!1;if(l)u=a(l,n),d=!0;else if(i)u=a(void 0,n),d=!0;else{let e=c(n);e?(u=e,d=!1):(u=s(void 0,n),d=!0)}return t.quiet?(console.log(u),{peerId:u,filePath:r,isRenewed:d}):t.json?(console.log(JSON.stringify({peerId:u,filePath:r,renewed:d},null,2)),{peerId:u,filePath:r,isRenewed:d}):(console.log(l?`WebRTC CLI Peer ID set to: ${u}`:d?`WebRTC CLI Peer ID created/renewed: ${u}`:`WebRTC CLI Peer ID: ${u}`),console.log(`Stored in: ${r}`),{peerId:u,filePath:r,isRenewed:d})}function N(e,t){return typeof e==`string`?t===`raw`?e.startsWith(`shadowclaw_client_`)?e.slice(18):e:e.startsWith(`shadowclaw_client_`)?e:`shadowclaw_client_${e}`:e}function P(e){return N(e,`raw`)}function F(e){return N(e,`exposed`)}const I=[{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 (idle, responding, etc.), active group ID, and capabilities from a connected client.`,inputSchema:{type:`object`,properties:{clientId:{type:`string`,description:`Target client ID (defaults to first available connected client).`}}}},{name:`shadowclaw_server_list_tasks`,description:`List scheduled background tasks configured on a connected client (optionally filtered by conversation group).`,inputSchema:{type:`object`,properties:{clientId:{type:`string`,description:`Target client ID (defaults to first available connected client).`},groupId:{type:`string`,description:`Optional conversation group ID filter.`}}}},{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 file backups for a connected client (trigger, list, or delete).`,inputSchema:{type:`object`,properties:{action:{type:`string`,enum:[`trigger`,`list`,`delete`],description:`Backup action to perform (default: 'trigger').`,default:`trigger`},clientId:{type:`string`,description:`Target client ID.`},backupId:{type:`string`,description:`Backup snapshot ID (required for 'delete').`},groupId:{type:`string`,description:`Optional workspace conversation group ID.`}}}},{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 L(e,t){try{let n=typeof e.getConnectedClients==`function`?e.getConnectedClients():typeof e.listClients==`function`?e.listClients():[];if(Array.isArray(n)&&n.length>0){if(typeof t==`string`&&t.trim()){let e=t.trim(),r=n.find(t=>(t.clientId||t.id)===e);if(r)return r.clientId||r.id||``;let i=parseInt(e,10);if(!isNaN(i)&&i>=0&&i<n.length)return n[i].clientId||n[i].id||``;let a=n.find(t=>(t.clientId||t.id||``).startsWith(e)||(t.clientId||t.id||``).replace(/^client-/,``).startsWith(e));if(a)return a.clientId||a.id||``;let o=n.find(t=>t.deviceLabel?.toLowerCase().includes(e.toLowerCase()));return o?o.clientId||o.id||``:e}if(typeof e.getActiveClientId==`function`){let t=e.getActiveClientId();if(t)return t}return n[0].clientId||n[0].id||``}}catch{}return typeof t==`string`?t.trim():``}const ne=h.dirname(g(import.meta.url));function re(){try{let e=h.resolve(ne,`../../../package.json`);if(m.existsSync(e)){let t=JSON.parse(m.readFileSync(e,`utf8`));if(t.version)return t.version}}catch{}return`1.27.1`}const R=`shadowclaw_local_`,ie=I;function z(e,t=R){let n=e.inputSchema||e.input_schema,r=n&&typeof n==`object`?{...n,type:n.type||`object`,properties:n.properties||{}}:{type:`object`,properties:{}};return{name:t?`${t}${e.name}`:e.name,description:e.description||`CLI agent tool: ${e.name}`,inputSchema:r,annotations:e.annotations}}function B(e,t,n){let r=!1,i=[];return Array.isArray(e)?i=e.map(e=>e&&typeof e==`object`?e.type===`image`?{type:`image`,data:e.data||``,mimeType:e.media_type||e.mimeType||`image/png`}:e.type===`text`?{type:`text`,text:String(e.text??``)}:{type:`text`,text:JSON.stringify(e,null,2)}:{type:`text`,text:String(e??``)}):typeof e==`string`?((e.toLowerCase().startsWith(`error`)||e.toLowerCase().startsWith(`tool error`)||e.includes(`SecurityError`)||e.startsWith(`Tool "`)&&e.includes(`is not allowed`)||e.startsWith(`Tool "`)&&e.includes(`is not available`))&&(r=!0),i=[{type:`text`,text:e}]):e&&typeof e==`object`?((e.error||e.success===!1)&&(r=!0),i=[{type:`text`,text:JSON.stringify(e,null,2)}]):i=[{type:`text`,text:String(e??``)}],{jsonrpc:`2.0`,id:n,result:{resultType:`complete`,isError:r,content:i,_meta:{"io.modelcontextprotocol/serverInfo":t}}}}function V(e={}){let n=e.client||new l(e),r=e.relayClientTools!==!1,i=e.targetClientId||e.clientTarget,a=i||``,o={name:`shadow-claw`,version:e.version||re()},s={tools:{listChanged:!0},extensions:{"io.modelcontextprotocol/tasks":{}}};async function c(e){let t=e||a||i;try{let e=await n.listClients();return L({getConnectedClients:()=>e},t)}catch{}return L(n,t)}let d=/* @__PURE__ */ new Map,p=/* @__PURE__ */ new Map,m=e.localTools!==!1,g=e.toolPrefix??`local`,_=g===`none`||g===``?``:g===`shadowclaw`?`shadowclaw_`:R,v=/* @__PURE__ */ new Map,x=null;async function S(){return x||=(async()=>{if(e.core&&e.db){let t;if(e.workspaceDir||e.workspace)t=e.workspaceDir||e.workspace;else{let e=h.join(D(),`shadow-claw`);await y(e,{recursive:!0}),t=await b(h.join(e,`workspace-`))}return{db:e.db,workspaceDir:t,core:e.core}}let n=e.core||await f(),r=e.workspaceDir||e.workspace,i=null,a=null,o=null;if(r)i=h.resolve(r),a=e.cacheDir?h.resolve(e.cacheDir):h.join(i,`.cache`),o=e.databaseDir?h.resolve(e.databaseDir):h.join(a,`database`);else try{let t=h.join(D(),`shadow-claw`);await y(t,{recursive:!0}),i=await b(h.join(t,`workspace-`)),a=e.cacheDir?h.resolve(e.cacheDir):await b(h.join(t,`cache-`)),o=e.databaseDir?h.resolve(e.databaseDir):h.join(a,`database`),await y(a,{recursive:!0}),await y(o,{recursive:!0})}catch(e){return console.error(`[ShadowClaw MCP] Warning: No --workspace provided and failed to initialize temporary fallback workspace (${e.message}). Local workspace tools are disabled.`),null}try{let r=await t({...e,workspace:i,cacheDir:a,databaseDir:o,yes:!0,quiet:!0,isTTY:!1,core:n});return{db:r.db,workspaceDir:r.workspaceDir,core:r.core}}catch(e){return console.error(`[ShadowClaw MCP] Warning: Failed to bootstrap headless agent context (${e.message}). Local workspace tools are disabled.`),null}})(),x}async function C(){if(!m)return[];let t;try{t=await S()}catch(e){return console.error(`[ShadowClaw MCP] Failed to initialize local agent context: ${e.message}`),[]}if(!t)return[];let{db:n,core:r}=t,i=e.group||r.DEFAULT_SERVER_GROUP_ID||`server:main`,a=null;if(e.toolsProfile||e.profile){let t=String(e.toolsProfile||e.profile).trim().toLowerCase(),i=r.DEFAULT_BUILTIN_PROFILE||null,o=[];if(typeof r.getConfig==`function`)try{let e=await r.getConfig(n,r.CONFIG_KEYS?.TOOL_PROFILES||`tool_profiles`);typeof e==`string`?o=JSON.parse(e):Array.isArray(e)&&(o=e)}catch{}let s=[i,...o].filter(Boolean).find(e=>e.id&&String(e.id).toLowerCase()===t||e.name&&String(e.name).toLowerCase()===t);s&&(a=new Set(s.enabledToolNames||[]))}let o=null;if(e.tools&&typeof e.tools==`string`&&e.tools.trim()){let t=e.tools.split(`,`).map(e=>e.trim()).filter(Boolean);o=new Set(t)}let s=[...r.TOOL_DEFINITIONS||[]];if(typeof r.loadDeclarativeTools==`function`)try{let e=await r.loadDeclarativeTools(n,i);if(e&&Array.isArray(e.tools))for(let t of e.tools)s.some(e=>e.name===t.name)||s.push(t)}catch{}let c=r.BROWSER_ONLY_TOOLS||u;v.clear();let l=[];for(let e of s){if(!e||!e.name||c&&c.has(e.name)||o&&!o.has(e.name)||a&&!a.has(e.name))continue;let t=z(e,_);v.set(e.name,e),v.set(`shadowclaw_local_${e.name}`,e),v.set(`shadowclaw_${e.name}`,e),l.push(t)}return l}async function w(t,n,r){try{let i=await S();if(!i)return{jsonrpc:`2.0`,id:r,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error: Local workspace tools are not initialized.`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}};let a=e.group||i.core.DEFAULT_SERVER_GROUP_ID||`server:main`,s;try{let{resolveAgentProvider:t}=await import(`./chunk-DtgZDsJA.js`),n=await t(i.db,i.core,i.workspaceDir,{...e,interactive:!1});s={db:i.db,provider:n.providerId,model:n.model,apiKey:n.apiKey}}catch{}return console.error(`[ShadowClaw MCP] Executing local tool '${t.name}' in workspace: ${i.workspaceDir}`),B(await i.core.executeTool(i.db,t.name,n,a,{invokeContext:s}),o,r)}catch(e){return{jsonrpc:`2.0`,id:r,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error executing local tool '${t.name}': ${e.message||String(e)}`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}}async function T(){if(!r)return[];let e=[];try{e=await n.listClients()}catch{}if(!Array.isArray(e)||e.length===0)return d.clear(),p.clear(),[];d.clear(),p.clear();for(let t of e){let e=t.clientId||t.id;if(e)try{let r=await n.sendCommand(e,`list-tools`,{});if(r&&r.success&&r.data?.tools&&Array.isArray(r.data.tools))for(let e of r.data.tools){let n=P(e.name);n===`send_notification`||n.startsWith(`shadowclaw_`)&&!n.startsWith(`shadowclaw_client_`)||(p.has(n)||(p.set(n,e),d.set(n,[])),d.get(n).push(t))}}catch{}}let t=await c(),i=[];for(let[n,r]of p.entries()){let a=d.get(n)||[],o=a.map(e=>e.clientId||e.id).filter(Boolean),s=a.find(e=>(e.clientId||e.id)===t)||a[0],c=s?.clientId||s?.id||``,l=s?.deviceLabel||`Client`,u=r.inputSchema&&typeof r.inputSchema==`object`?r.inputSchema:{type:`object`,properties:{}},f={...u.properties||{},clientId:{type:`string`,description:`Target ShadowClaw client ID (optional; defaults to ${c} [${l}]). Available on: ${a.map(e=>`${e.clientId||e.id} (${e.deviceLabel||`Client`})`).join(`, `)}`,enum:o}},p=e.length>1?a.length>1?` [Default: ${l} (${c.slice(0,14)}...)]`:` [Client: ${l} (${c.slice(0,14)}...)]`:``,m=F(n);i.push({name:m,description:(r.description||`Relayed tool '${n}' from connected client.`)+p,inputSchema:{...u,type:`object`,properties:f},annotations:r.annotations})}return i}async function E(e,t={}){let i=e.id===void 0||e.id===null,l=e.id??null;if(t[`mcp-method`]&&t[`mcp-method`]!==e.method)return{jsonrpc:`2.0`,id:l,error:{code:-32020,message:`Mcp-Method header '${t[`mcp-method`]}' does not match '${e.method}'`}};switch(e.method){case`server/discover`:return{jsonrpc:`2.0`,id:l,result:{protocolVersion:`2026-07-28`,supportedProtocolVersions:[`2026-07-28`,`2025-11-25`,`2024-11-05`],capabilities:s,serverInfo:o,_meta:{"io.modelcontextprotocol/serverInfo":o}}};case`initialize`:return{jsonrpc:`2.0`,id:l,result:{protocolVersion:e.params?.protocolVersion||`2024-11-05`,capabilities:s,serverInfo:o}};case`notifications/initialized`:return null;case`tools/list`:{let e=[];try{if(typeof n.listPushClients==`function`)e=await n.listPushClients();else if(typeof n.listPushSubscriptions==`function`){let t=await n.listPushSubscriptions();if(Array.isArray(t)){let n=/* @__PURE__ */ new Map;for(let e of t){let t=(e.client_id||``).trim()||(e.id?String(e.id):``);t&&!n.has(t)&&n.set(t,{clientId:t,deviceLabel:e.device_label||void 0})}e=Array.from(n.values())}}}catch{}let t=Array.isArray(e)?[...e].sort((e,t)=>(e.clientId||``).localeCompare(t.clientId||``)):[],r=t.map(e=>e.clientId).filter(Boolean),i=await T(),a=await C(),s=/* @__PURE__ */ new Map;for(let e of ie)s.set(e.name,e);for(let e of a)s.has(e.name)||s.set(e.name,e);for(let e of i)s.has(e.name)||s.set(e.name,e);if(r.length>0)for(let e of[`shadowclaw_server_send_notification`,`shadowclaw_send_notification`]){let n=s.get(e);n&&s.set(e,{...n,inputSchema:{...n.inputSchema,type:`object`,properties:{...n.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: ${t.map(e=>`${e.clientId} (${e.deviceLabel||`Client`})`).join(`, `)}`,enum:r}}}})}return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,ttlMs:5e3,cacheScope:`private`,tools:Array.from(s.values()).sort((e,t)=>e.name.localeCompare(t.name)),_meta:{"io.modelcontextprotocol/serverInfo":o}}}}case`tools/call`:{let t=e.params?.name,i=e.params?.arguments||{},s=e.params?.inputResponses;if(!t)return{jsonrpc:`2.0`,id:l,error:{code:-32602,message:`Missing required parameter 'name'`}};if(t===`shadowclaw_server_list_clients`||t===`shadowclaw_list_clients`)try{let e=await n.listClients();return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,content:[{type:`text`,text:JSON.stringify({clients:e},null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}catch(e){return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error listing clients: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}if(t===`shadowclaw_server_set_active_client`||t===`shadowclaw_set_active_client`){let e=await c(i.clientId);return e?(a=e,console.error(`[ShadowClaw MCP] Active default client set to: ${a}`),{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,content:[{type:`text`,text:`Active default client set to: ${a}`}],_meta:{activeClientId:a,"io.modelcontextprotocol/serverInfo":o}}}):{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error: Client '${i.clientId}' not found among connected clients.`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}if(t===`shadowclaw_server_send_message`||t===`shadowclaw_send_message`){let e=await c(i.clientId);if(!e)return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error: No connected client available.`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}};try{let t=await n.sendCommand(e,`send-message`,{text:i.text,groupId:i.groupId});return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!t.success,content:[{type:`text`,text:JSON.stringify(t.data||t,null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}catch(e){return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error sending message: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}}if(t===`shadowclaw_server_read_state`||t===`shadowclaw_read_state`){let e=await c(i.clientId);try{let t=await n.sendCommand(e,`read-state`,{});return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!t.success,content:[{type:`text`,text:JSON.stringify(t.data||t,null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}catch(e){return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error reading state: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}}if(t===`shadowclaw_server_list_tasks`||t===`shadowclaw_list_tasks`){let e=await c(i.clientId);try{let t=await n.sendCommand(e,`list-tasks`,{groupId:i.groupId});return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!t.success,content:[{type:`text`,text:JSON.stringify(t.data||t,null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}catch(e){return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error listing tasks: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}}if(t===`shadowclaw_server_manage_backup`||t===`shadowclaw_manage_backup`){let e=i.action||`trigger`,t=await c(i.clientId);try{if(e===`list`){let e=await n.listBackups(t);return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,content:[{type:`text`,text:JSON.stringify({backups:e},null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}if(e===`delete`){let e=await n.deleteBackup(i.backupId,t);return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,content:[{type:`text`,text:JSON.stringify(e,null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}let r=await n.sendCommand(t,`trigger-backup`,{groupId:i.groupId});return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!r.success,content:[{type:`text`,text:JSON.stringify(r.data||r,null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}catch(e){return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error managing backup: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}}if(t===`shadowclaw_server_status`||t===`shadowclaw_status`)try{let e=await n.listClients();return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,content:[{type:`text`,text:JSON.stringify({server:`ShadowClaw`,version:o.version,connectedClients:e.length,status:`healthy`},null,2)}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}catch(e){return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error querying server status: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}if(t===`shadowclaw_server_send_notification`||t===`shadowclaw_send_notification`||t===`send_notification`){let e=String(i.body||``).trim();if(!e)return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error: Notification 'body' parameter cannot be empty.`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}};let t=String(i.title||`ShadowClaw`).trim(),r=typeof i.clientId==`string`&&i.clientId.trim()?i.clientId.trim():void 0;try{let i=await n.broadcastNotification({title:t,body:e,...r?{clientId:r}:{}}),a=i?.sent??0,s=i?.failed??0,c;return c=i?.notFound?`Warning: No push subscriptions found for client '${r}'. Ensure push notifications were registered by this client in ShadowClaw Settings.`:i?.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.`:r?`Push notification sent to client '${r}': ${a} recipient(s) delivered, ${s} failed.`:`Push notification broadcast sent: ${a} recipient(s) delivered, ${s} failed.`,{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!1,content:[{type:`text`,text:c}],_meta:{...i,...r?{targetClientId:r}:{},"io.modelcontextprotocol/serverInfo":o}}}}catch(e){return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Failed to send push notification: ${e.message}`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}}}}let u=P(t);if((u===`ask_user`||t===`ask_user`)&&s&&s.response)return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,content:[{type:`text`,text:String(s.response)}],_meta:{"io.modelcontextprotocol/serverInfo":o}}};m&&v.size===0&&await C();let f=t.startsWith(R),h=t.startsWith(`shadowclaw_client_`),_=v.get(t);if(!_&&f&&(_=v.get(t.slice(17))),!_&&t.startsWith(`shadowclaw_`)&&!h&&(_=v.get(t.slice(11))),f&&_){let e={...i};return delete e.clientId,await w(_,e,l)}r&&p.size===0&&await T();let y=(d.get(u)||d.get(t)||[]).map(e=>e.clientId||e.id).filter(Boolean),b=[];try{b=await n.listClients()}catch{}if(!h&&_&&(g===`none`&&!i.clientId||!r||!Array.isArray(b)||b.length===0)){let e={...i};return delete e.clientId,await w(_,e,l)}let x=``;if(i.clientId)x=await c(i.clientId);else{let e=await c();x=y.includes(e)?e:y.length>0?y[0]:e}if(!x)return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error: No connected client available.`}],_meta:{"io.modelcontextprotocol/serverInfo":o}}};if(y.length>0&&!y.includes(x))return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Error: Tool '${t}' is not enabled or available on client '${x}'. (Available on: ${y.join(`, `)})`}],_meta:{clientId:x,"io.modelcontextprotocol/serverInfo":o}}};try{console.error(`[ShadowClaw MCP] Executing '${u}' on client: ${x}`);let e={...i};delete e.clientId;let t=u===`ask_user`?await n.sendCommand(x,`invoke-tool`,{toolName:u,input:e},3e5):await n.sendCommand(x,`invoke-tool`,{toolName:u,input:e}),r=t.data?.result===void 0?t.data:t.data.result,a=typeof r==`string`?r:JSON.stringify(r,null,2),s=t.error||t.data&&t.data.error||`Unknown tool execution error`;return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!t.success,content:[{type:`text`,text:t.success?a||``:a&&a!==`null`&&a!==`{}`?`${a}\n${s}`:`Tool execution error: ${s}`}],_meta:{clientId:x,"io.modelcontextprotocol/serverInfo":o}}}}catch(e){return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,isError:!0,content:[{type:`text`,text:`Tool error: ${e.message}`}],_meta:{clientId:x,"io.modelcontextprotocol/serverInfo":o}}}}}case`tasks/get`:return{jsonrpc:`2.0`,id:l,result:{resultType:`complete`,task:{taskId:e.params?.taskId||`task-1`,status:`completed`},_meta:{"io.modelcontextprotocol/serverInfo":o}}};default:return i?null:{jsonrpc:`2.0`,id:l,error:{code:-32601,message:`Method not found: '${e.method}'`}}}}return{handleMessage:E,getActiveClientId:()=>a,setActiveClientId:e=>{a=e},close:async()=>{if(x)try{let e=await x;typeof e?.core?.closeSqliteDatabase==`function`&&e.core.closeSqliteDatabase()}catch{}}}}async function H(e={}){if((e.mcpTransport||(e.http?`http`:`stdio`))===`http`){let t=parseInt(String(e.port||T.env.MCP_PORT||`8888`),10),n=e.host||`127.0.0.1`,r=V(e);E.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),n=ee.createInterface({input:T.stdin,output:T.stdout,terminal:!1});n.on(`line`,async e=>{let n=e.trim();if(!n)return;let r;try{r=JSON.parse(n)}catch{T.stdout.write(JSON.stringify({jsonrpc:`2.0`,id:null,error:{code:-32700,message:`Parse error`}})+`
2
2
  `);return}try{let e=await t.handleMessage(r);e!==null&&T.stdout.write(JSON.stringify(e)+`
3
3
  `)}catch(e){let t={jsonrpc:`2.0`,id:r?.id??null,error:{code:-32603,message:e?.message||`Internal error`}};T.stdout.write(JSON.stringify(t)+`
4
4
  `)}}),n.on(`close`,async()=>{await t.close?.()}),console.error(`[ShadowClaw MCP] STDIO MCP server active (2026-07-28)`)}const U=e(import.meta.url),W=/* @__PURE__ */ new Set;function G(e){return typeof e==`function`?(W.add(e),()=>W.delete(e)):()=>!1}let K=!1;const q=(e,t)=>{K&&_.exit(t),K=!0;for(let t of W)try{t(e)}catch{}_.stderr.write(`\nProcess interrupted (${e}).\n`),_.exit(t)};_.on(`SIGINT`,()=>q(`SIGINT`,130)),_.on(`SIGTERM`,()=>q(`SIGTERM`,143)),_.on(`exit`,()=>{for(let e of W)try{e(`exit`)}catch{}});async function J(){try{let e=h.join(U,`package.json`),t=await x(e,`utf8`);return JSON.parse(t).version||`1.0.0`}catch{return`1.0.0`}}async function Y(e){try{return await S(e),!0}catch{return!1}}function X(e){return!!(e.a2a||[`1`,`true`,`yes`].includes((_.env.SHADOWCLAW_A2A||``).toLowerCase().trim()))}function Z(e){let t=_.platform===`darwin`?`open`:_.platform===`win32`?`start`:`xdg-open`;try{v(`${t} ${e}`)}catch{}}const ae=await J(),Q=new w;Q.name(`shadow-claw`).description(`Multi-runtime AI assistant and static site publisher`).version(ae,`-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`,_.cwd()).action(async e=>{try{let t=h.resolve(e.contentRoot||_.cwd()),n=!!(e.prod||e.production||_.env.NODE_ENV===`production`);console.log(`Building ShadowClaw site from ${t}...`),await i({contentRoot:t,toolchainRoot:U,outDir:e.outDir||`dist/public`,isProduction:n,pagesOrigin:e.origin||_.env.PAGES_ORIGIN,basePath:e.basePath||_.env.PAGES_BASE_PATH,prerenderPages:e.prerenderPages,copyAllAssets:e.copyAllAssets})}catch(e){console.error(`Build failed:`,e),_.exit(1)}});async function $(e,t){try{let r=h.resolve(t.contentRoot||_.cwd()),a=parseInt(e||t.port||_.env.PORT||`8888`,10),o=t.host||t.ip||_.env.SHADOWCLAW_DEV_IP||`127.0.0.1`,s=t.outDir||`dist/public`,c=h.resolve(r,s),l=await n({contentRoot:r,cacheDir:t.cacheDir,databaseDir:t.databaseDir,tmp:t.tmp||t.temp,yes:t.yes}),u=l.cacheDir,d=l.databaseDir;console.log(`Preparing ShadowClaw dev build for ${r}...`),await i({contentRoot:r,toolchainRoot:U,outDir:s,isProduction:!1,pagesOrigin:t.origin||_.env.PAGES_ORIGIN,basePath:t.basePath||_.env.PAGES_BASE_PATH,prerenderPages:t.prerenderPages||`auto`,copyAllAssets:t.copyAllAssets});let f=await Y(h.join(U,`dist/server.js`))?h.join(U,`dist/server.js`):h.join(U,`src/server/server.ts`);_.env.SHADOWCLAW_ROOT_PATH=c,_.env.SHADOWCLAW_CACHE_DIR=u,_.env.SHADOWCLAW_DATABASE_DIR=d,_.env.SHADOWCLAW_DEV_IP=o;let{startServer:p}=await import(f),m=new Set((t.corsAllowOrigin||_.env.SHADOWCLAW_CORS_ALLOWED_ORIGINS||`https://xt-ml.github.io`).split(`,`).map(e=>e.trim()).filter(Boolean)),g=!!(t.https||[`1`,`true`,`yes`].includes((_.env.SHADOWCLAW_HTTPS||``).toLowerCase().trim())),v=t.cert||(_.env.SHADOWCLAW_TLS_CERT||_.env.SHADOWCLAW_CERT||``).trim()||void 0,y=t.key||(_.env.SHADOWCLAW_TLS_KEY||_.env.SHADOWCLAW_KEY||``).trim()||void 0,b=h.resolve(r,t.sslDir||_.env.SHADOWCLAW_SSL_DIR||_.env.SHADOWCLAW_TLS_DIR||h.join(u,`tls`));await p({port:a,bindHost:o,corsMode:t.corsMode||`localhost`,allowedOrigins:m,verbose:!!t.verbose,peerjs:!!t.peerjs,a2aEnabled:X(t),rootPath:c,cacheDir:u,databaseDir:d,allowPrivateProxy:!!t.allowPrivateProxy,https:g,certPath:v,keyPath:y,sslDir:b});let x=`${g?`https`:`http`}://${o}:${a}`;t.open&&Z(x)}catch(e){console.error(`Dev server error:`,e),_.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`,_.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).option(`--a2a`,`Enable A2A v1.0 agent card, JSON-RPC, and SSE endpoints`,!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`,_.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).option(`--a2a`,`Enable A2A v1.0 agent card, JSON-RPC, and SSE endpoints`,!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 static files and start backend services (optional: --peerjs, --a2a)`).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`,_.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).option(`--a2a`,`Enable A2A v1.0 agent card, JSON-RPC, and SSE endpoints`,!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 r=h.resolve(t.contentRoot||_.cwd()),i=parseInt(e||t.port||_.env.PORT||`8888`,10),a=t.host||t.ip||_.env.SHADOWCLAW_DEV_IP||`127.0.0.1`,o=t.outDir||`dist/public`,s=h.resolve(r,o),c=await n({contentRoot:r,cacheDir:t.cacheDir,databaseDir:t.databaseDir,tmp:t.tmp||t.temp,yes:t.yes}),l=c.cacheDir,u=c.databaseDir,d=t.static!==!1;d&&!await Y(h.join(s,`index.html`))&&(console.error(`Error: No index.html found in ${s}. Run "shadow-claw build" first.`),_.exit(1));let f=await Y(h.join(U,`dist/server.js`))?h.join(U,`dist/server.js`):h.join(U,`src/server/server.ts`);_.env.SHADOWCLAW_ROOT_PATH=s,_.env.SHADOWCLAW_CACHE_DIR=l,_.env.SHADOWCLAW_DATABASE_DIR=u,_.env.SHADOWCLAW_DEV_IP=a;let{startServer:p}=await import(f),m=new Set((t.corsAllowOrigin||_.env.SHADOWCLAW_CORS_ALLOWED_ORIGINS||`https://xt-ml.github.io`).split(`,`).map(e=>e.trim()).filter(Boolean)),g=!!(t.https||[`1`,`true`,`yes`].includes((_.env.SHADOWCLAW_HTTPS||``).toLowerCase().trim())),v=t.cert||(_.env.SHADOWCLAW_TLS_CERT||_.env.SHADOWCLAW_CERT||``).trim()||void 0,y=t.key||(_.env.SHADOWCLAW_TLS_KEY||_.env.SHADOWCLAW_KEY||``).trim()||void 0,b=h.resolve(r,t.sslDir||_.env.SHADOWCLAW_SSL_DIR||_.env.SHADOWCLAW_TLS_DIR||h.join(l,`tls`));await p({port:i,bindHost:a,corsMode:t.corsMode||`localhost`,allowedOrigins:m,verbose:!!t.verbose,peerjs:!!t.peerjs,a2aEnabled:X(t),rootPath:s,cacheDir:l,databaseDir:u,allowPrivateProxy:!!t.allowPrivateProxy,https:g,certPath:v,keyPath:y,sslDir:b,serveStatic:d});let x=`${g?`https`:`http`}://${a}:${i}`;d&&t.open&&Z(x)}catch(e){console.error(`Serve error:`,e),_.exit(1)}});async function oe(e,t){try{let r=h.resolve(t.contentRoot||_.cwd()),i=parseInt(e||t.port||_.env.PORT||`8888`,10),a=t.host||t.ip||_.env.SHADOWCLAW_DEV_IP||`127.0.0.1`,o=await n({contentRoot:r,cacheDir:t.cacheDir,databaseDir:t.databaseDir,tmp:t.tmp||t.temp,yes:t.yes}),s=o.cacheDir,c=o.databaseDir,l=await Y(h.join(U,`dist/server.js`))?h.join(U,`dist/server.js`):h.join(U,`src/server/server.ts`);_.env.SHADOWCLAW_CACHE_DIR=s,_.env.SHADOWCLAW_DATABASE_DIR=c,_.env.SHADOWCLAW_DEV_IP=a,_.env.SHADOWCLAW_SERVE_STATIC=`false`;let{startServer:u}=await import(l),d=new Set((t.corsAllowOrigin||_.env.SHADOWCLAW_CORS_ALLOWED_ORIGINS||`https://xt-ml.github.io`).split(`,`).map(e=>e.trim()).filter(Boolean)),f=!!(t.https||[`1`,`true`,`yes`].includes((_.env.SHADOWCLAW_HTTPS||``).toLowerCase().trim())),p=t.cert||(_.env.SHADOWCLAW_TLS_CERT||_.env.SHADOWCLAW_CERT||``).trim()||void 0,m=t.key||(_.env.SHADOWCLAW_TLS_KEY||_.env.SHADOWCLAW_KEY||``).trim()||void 0,g=h.resolve(r,t.sslDir||_.env.SHADOWCLAW_SSL_DIR||_.env.SHADOWCLAW_TLS_DIR||h.join(s,`tls`));await u({port:i,bindHost:a,corsMode:t.corsMode||`localhost`,allowedOrigins:d,verbose:!!t.verbose,peerjs:!!t.peerjs,a2aEnabled:X(t),rootPath:``,cacheDir:s,databaseDir:c,controlToken:t.controlToken||_.env.SHADOWCLAW_CONTROL_TOKEN||void 0,allowPrivateProxy:!!t.allowPrivateProxy,https:f,certPath:p,keyPath:m,sslDir:g,serveStatic:!1})}catch(e){console.error(`Server error:`,e),_.exit(1)}}Q.command(`server [port]`).aliases([`services`,`api`]).description(`Start backend services (HTTP MCP, control plane, scheduler, and proxy) without serving static files (optional: --peerjs, --a2a; 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(`--a2a`,`Enable A2A v1.0 agent card, JSON-RPC, and SSE endpoints`,!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`,_.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(`Start the standalone MCP server only (does not start backend services, PeerJS, or A2A)`).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(`--local-tools`,`Expose headless CLI agent tools (read_file, write_file, bash, git_*, etc.)`,!0).option(`--no-local-tools`,`Disable exposing headless CLI agent tools`).option(`--tool-prefix <prefix>`,`Tool prefix style for local tools: local | none | shadowclaw (default: local)`,`local`).optionsGroup(`Workspace & Local Agent Tools Options:`).option(`--workspace <dir>`,`Workspace directory for local tools (default: current working directory)`).option(`--database-dir <dir>`,`Directory where SQLite databases are stored`).option(`--group <groupId>`,`Conversation group ID for local tools (default: server:main)`).option(`--tools <tools>`,`Comma-separated list of local agent tools to expose (default: all headless-safe tools)`).option(`--tools-profile <name>`,`Tools profile to activate for local tools`).option(`--allow-internet, --internet-access`,`Allow full internet access for local Bash and JavaScript tools`).action(async e=>{await H(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 O(e)}),Q.command(`send <message>`).description(`Send a message/prompt to a connected client or peer agent`).optionsGroup(`Target Options:`).option(`--client <id>`,`Target client ID (defaults to first available)`).option(`--group <groupId>`,`Target conversation group ID`).option(`-f, --file <path>`,`Attach a local file to send with the message`).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`).option(`--timeout <seconds>`,`Timeout in seconds to wait for response`,`120`).option(`--json`,`Output response payload as JSON`,!1).action(async(e,t)=>{await te(e,t)}),Q.command(`send-file <file>`).description(`Transfer a file to a connected peer or client over WebRTC or HTTP`).optionsGroup(`Target Options:`).option(`--client <id>`,`Target client ID (defaults to first available)`).option(`--prompt <prompt>`,`Accompanying prompt or instructions for the receiving agent`).option(`--name <fileName>`,`Override remote file name`).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`,`webrtc`).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`).option(`--timeout <seconds>`,`Transfer and execution timeout in seconds`,`120`).option(`--json`,`Output response payload as JSON`,!1).action(async(e,t)=>{await k(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 j(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 A(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)
@@ -13,7 +13,7 @@ import { t as ShadowClawFileViewer } from "../shadow-claw-file-viewer-BqChtTvM.j
13
13
  import { t as ShadowClawPdfViewer } from "../shadow-claw-pdf-viewer-DGLXTccC.js";
14
14
  import { t as ShadowClawTasks } from "../shadow-claw-tasks-DrSVUOsP.js";
15
15
  import { n as ShadowClawTerminal } from "../shadow-claw-terminal-B7HYLuce.js";
16
- import { t as ShadowClawPages } from "../shadow-claw-pages-kA2qa-4B.js";
16
+ import { t as ShadowClawPages } from "../shadow-claw-pages-CjHS50HN.js";
17
17
  import { t as ShadowClawSettings } from "../shadow-claw-settings-CkO6JjA4.js";
18
18
  import { t as ShadowClawPeerJs } from "../shadow-claw-peerjs-CvcH2DkA.js";
19
19
  import { t as ShadowClawChannelConfig } from "../shadow-claw-channel-config-F_EJ-uK2.js";
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawPages } from "../shadow-claw-pages-kA2qa-4B.js";
1
+ import { t as ShadowClawPages } from "../shadow-claw-pages-CjHS50HN.js";
2
2
 
3
3
  export { ShadowClawPages };
package/dist/lib/index.js CHANGED
@@ -28,7 +28,7 @@ import { t as ShadowClawFileViewer } from "./shadow-claw-file-viewer-BqChtTvM.js
28
28
  import { t as ShadowClawPdfViewer } from "./shadow-claw-pdf-viewer-DGLXTccC.js";
29
29
  import { t as ShadowClawTasks } from "./shadow-claw-tasks-DrSVUOsP.js";
30
30
  import { n as ShadowClawTerminal } from "./shadow-claw-terminal-B7HYLuce.js";
31
- import { t as ShadowClawPages } from "./shadow-claw-pages-kA2qa-4B.js";
31
+ import { t as ShadowClawPages } from "./shadow-claw-pages-CjHS50HN.js";
32
32
  import { t as ShadowClawSettings } from "./shadow-claw-settings-CkO6JjA4.js";
33
33
  import { t as ShadowClawPeerJs } from "./shadow-claw-peerjs-CvcH2DkA.js";
34
34
  import { t as ShadowClawChannelConfig } from "./shadow-claw-channel-config-F_EJ-uK2.js";
@@ -2389,7 +2389,7 @@ var ShadowClawPages = class extends ShadowClawElement {
2389
2389
  async reloadPreviewWithSearchParams(searchParams) {
2390
2390
  if (!this.selectedPage || !this.renderedContent) return;
2391
2391
  const root = this.shadowRoot;
2392
- const rendered = root?.querySelector("#rendered");
2392
+ const rendered = root?.querySelector("[data-pages-rendered]") || root?.querySelector("#rendered");
2393
2393
  if (!root || !rendered) return;
2394
2394
  const parsedFrontmatter = splitFrontmatter(this.renderedContent);
2395
2395
  const iframe = this.ensurePreviewIframe(root, rendered);
@@ -2402,4 +2402,4 @@ if (!customElements.get(elementName)) customElements.define(elementName, ShadowC
2402
2402
 
2403
2403
  //#endregion
2404
2404
  export { ShadowClawPages as t };
2405
- //# sourceMappingURL=shadow-claw-pages-kA2qa-4B.js.map
2405
+ //# sourceMappingURL=shadow-claw-pages-CjHS50HN.js.map