shadow-claw 1.26.0 → 1.27.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.
- package/.agents/skills/main/skill-creator/SKILL.md +39 -0
- package/.agents/skills/main/skill-creator/references/declarative-pipelines.md +44 -0
- package/.agents/skills/main/skill-creator/references/declarative-tools.md +35 -0
- package/.agents/skills/main/skill-creator/references/frontmatter-spec.md +50 -0
- package/.well-known/agent-skills/index.json +14 -0
- package/README.md +5 -3
- package/bin/build/build.mjs +148 -15
- package/bin/build/build.test.mjs +128 -0
- package/bin/cli.mjs +35 -0
- package/bin/commands/mcp.mjs +277 -55
- package/bin/commands/mcp.test.mjs +275 -1
- package/bin/commands/skills-index.mjs +447 -0
- package/bin/commands/skills-index.test.mjs +243 -0
- package/bin/site-config/utils/custom-elements/get-approved-custom-element-scripts.test.mjs +2 -0
- package/bin/site-config/utils/custom-elements/sanitize-embedded-custom-element-scripts.test.mjs +10 -1
- package/dist/lib/components/index.js +25 -25
- package/dist/lib/components/settings/shadow-claw-accounts.js +1 -1
- package/dist/lib/components/settings/shadow-claw-channel-config.js +1 -1
- package/dist/lib/components/settings/shadow-claw-control-plane.js +1 -1
- package/dist/lib/components/settings/shadow-claw-git.js +1 -1
- package/dist/lib/components/settings/shadow-claw-integrations.js +1 -1
- package/dist/lib/components/settings/shadow-claw-llm.js +1 -1
- package/dist/lib/components/settings/shadow-claw-mcp-remote.js +1 -1
- package/dist/lib/components/settings/shadow-claw-networking.js +1 -1
- package/dist/lib/components/settings/shadow-claw-peerjs.js +1 -1
- package/dist/lib/components/settings/shadow-claw-storage.js +1 -1
- package/dist/lib/components/settings/shadow-claw-task-server.js +1 -1
- package/dist/lib/components/settings/shadow-claw-webvm.js +1 -1
- package/dist/lib/components/shadow-claw-a2ui.js +1 -1
- package/dist/lib/components/shadow-claw-accounts.js +1 -1
- package/dist/lib/components/shadow-claw-channel-config.js +1 -1
- package/dist/lib/components/shadow-claw-channels.js +1 -1
- package/dist/lib/components/shadow-claw-chat.js +1 -1
- package/dist/lib/components/shadow-claw-control-plane.js +1 -1
- package/dist/lib/components/shadow-claw-conversations.js +1 -1
- package/dist/lib/components/shadow-claw-file-viewer.js +1 -1
- package/dist/lib/components/shadow-claw-files.js +1 -1
- package/dist/lib/components/shadow-claw-git.js +1 -1
- package/dist/lib/components/shadow-claw-integrations.js +1 -1
- package/dist/lib/components/shadow-claw-llm.js +1 -1
- package/dist/lib/components/shadow-claw-mcp-remote.js +1 -1
- package/dist/lib/components/shadow-claw-networking.js +1 -1
- package/dist/lib/components/shadow-claw-page-header.js +1 -1
- package/dist/lib/components/shadow-claw-pages.js +1 -1
- package/dist/lib/components/shadow-claw-peerjs.js +1 -1
- package/dist/lib/components/shadow-claw-settings.js +1 -1
- package/dist/lib/components/shadow-claw-storage.js +1 -1
- package/dist/lib/components/shadow-claw-task-server.js +1 -1
- package/dist/lib/components/shadow-claw-tasks.js +1 -1
- package/dist/lib/components/shadow-claw-terminal.js +1 -1
- package/dist/lib/components/shadow-claw-tools.js +1 -1
- package/dist/lib/components/shadow-claw-webvm.js +1 -1
- package/dist/lib/components/shadow-claw.js +1 -1
- package/dist/lib/{configurePeerJs-CrlGan0m.js → configurePeerJs-oODzltaC.js} +2 -2
- package/dist/lib/{configurePeerJs-CrlGan0m.js.map → configurePeerJs-oODzltaC.js.map} +1 -1
- package/dist/lib/core/control-plane-client.d.ts +1 -0
- package/dist/lib/{downloadGroupFile-DboUjmp2.js → downloadGroupFile-DmcBQU1n.js} +2 -2
- package/dist/lib/{downloadGroupFile-DboUjmp2.js.map → downloadGroupFile-DmcBQU1n.js.map} +1 -1
- package/dist/lib/{file-viewer-BrK2Wxgh.js → file-viewer-C3YKnq_-.js} +4 -3
- package/dist/lib/{file-viewer-BrK2Wxgh.js.map → file-viewer-C3YKnq_-.js.map} +1 -1
- package/dist/lib/index.js +26 -26
- package/dist/lib/{initControlPlane-CsO4UR6_.js → initControlPlane-C2zURVIS.js} +86 -13
- package/dist/lib/initControlPlane-C2zURVIS.js.map +1 -0
- package/dist/lib/{markdown-eeSTFnMA.js → markdown-C6EHl9zs.js} +3 -3
- package/dist/lib/{markdown-eeSTFnMA.js.map → markdown-C6EHl9zs.js.map} +1 -1
- package/dist/lib/{orchestrator-CJvoC2Uu.js → orchestrator-CACLa_Ro.js} +7 -6
- package/dist/lib/{orchestrator-CJvoC2Uu.js.map → orchestrator-CACLa_Ro.js.map} +1 -1
- package/dist/lib/{orchestrator-DCfomsn9.js → orchestrator-KRjx0eba.js} +6 -534
- package/dist/lib/{orchestrator-DCfomsn9.js.map → orchestrator-KRjx0eba.js.map} +1 -1
- package/dist/lib/parsePath-DwC_YZjw.js +16 -0
- package/dist/lib/parsePath-DwC_YZjw.js.map +1 -0
- package/dist/lib/{peerjs-Dp02bXcG.js → peerjs-DFWOBcXf.js} +4 -4
- package/dist/lib/{peerjs-Dp02bXcG.js.map → peerjs-DFWOBcXf.js.map} +1 -1
- package/dist/lib/{readGroupFileBytes-Bve-e5e_.js → readGroupFileBytes-C8oOe8Iu.js} +3 -16
- package/dist/lib/readGroupFileBytes-C8oOe8Iu.js.map +1 -0
- package/dist/lib/security/custom-element-security.d.ts +8 -0
- package/dist/lib/server/control-plane-types.d.ts +1 -1
- package/dist/lib/{shadow-claw-D8xINM3c.js → shadow-claw-6UHdiy4a.js} +5 -5
- package/dist/lib/{shadow-claw-D8xINM3c.js.map → shadow-claw-6UHdiy4a.js.map} +1 -1
- package/dist/lib/{shadow-claw-a2ui-7rJqG4Ke.js → shadow-claw-a2ui-CpZUTzlh.js} +5 -4
- package/dist/lib/{shadow-claw-a2ui-7rJqG4Ke.js.map → shadow-claw-a2ui-CpZUTzlh.js.map} +1 -1
- package/dist/lib/{shadow-claw-accounts-CdruwN8A.js → shadow-claw-accounts-03oJ__XC.js} +2 -2
- package/dist/lib/{shadow-claw-accounts-CdruwN8A.js.map → shadow-claw-accounts-03oJ__XC.js.map} +1 -1
- package/dist/lib/{shadow-claw-channel-config-Bj0-Nk3t.js → shadow-claw-channel-config-DmfwJc6G.js} +3 -3
- package/dist/lib/{shadow-claw-channel-config-Bj0-Nk3t.js.map → shadow-claw-channel-config-DmfwJc6G.js.map} +1 -1
- package/dist/lib/{shadow-claw-channels-C_jI4KhP.js → shadow-claw-channels-1N6Jl-By.js} +3 -3
- package/dist/lib/{shadow-claw-channels-C_jI4KhP.js.map → shadow-claw-channels-1N6Jl-By.js.map} +1 -1
- package/dist/lib/{shadow-claw-chat-B16MspoP.js → shadow-claw-chat-BMoqQJRK.js} +10 -10
- package/dist/lib/{shadow-claw-chat-B16MspoP.js.map → shadow-claw-chat-BMoqQJRK.js.map} +1 -1
- package/dist/lib/{shadow-claw-control-plane-x8Ldid_h.js → shadow-claw-control-plane-UG0o7pCz.js} +6 -6
- package/dist/lib/{shadow-claw-control-plane-x8Ldid_h.js.map → shadow-claw-control-plane-UG0o7pCz.js.map} +1 -1
- package/dist/lib/{shadow-claw-conversations-Ct1kAYdB.js → shadow-claw-conversations-BwXep3iu.js} +4 -3
- package/dist/lib/{shadow-claw-conversations-Ct1kAYdB.js.map → shadow-claw-conversations-BwXep3iu.js.map} +1 -1
- package/dist/lib/{shadow-claw-file-viewer-BfDHHgpA.js → shadow-claw-file-viewer-DUxzVxDT.js} +14 -10
- package/dist/lib/shadow-claw-file-viewer-DUxzVxDT.js.map +1 -0
- package/dist/lib/{shadow-claw-files-EYhOPYIH.js → shadow-claw-files-DIREEnT2.js} +7 -7
- package/dist/lib/{shadow-claw-files-EYhOPYIH.js.map → shadow-claw-files-DIREEnT2.js.map} +1 -1
- package/dist/lib/{shadow-claw-git-tcSpT-P0.js → shadow-claw-git-Bg1SWgsF.js} +4 -4
- package/dist/lib/{shadow-claw-git-tcSpT-P0.js.map → shadow-claw-git-Bg1SWgsF.js.map} +1 -1
- package/dist/lib/{shadow-claw-integrations-NbcCx_ZI.js → shadow-claw-integrations-Ds-CLPhj.js} +2 -2
- package/dist/lib/{shadow-claw-integrations-NbcCx_ZI.js.map → shadow-claw-integrations-Ds-CLPhj.js.map} +1 -1
- package/dist/lib/{shadow-claw-llm-BazJdD5f.js → shadow-claw-llm-CazBrVpM.js} +3 -3
- package/dist/lib/{shadow-claw-llm-BazJdD5f.js.map → shadow-claw-llm-CazBrVpM.js.map} +1 -1
- package/dist/lib/{shadow-claw-mcp-remote-CYmhpg7a.js → shadow-claw-mcp-remote-CT5Q-54E.js} +2 -2
- package/dist/lib/{shadow-claw-mcp-remote-CYmhpg7a.js.map → shadow-claw-mcp-remote-CT5Q-54E.js.map} +1 -1
- package/dist/lib/{shadow-claw-networking-DImPxe0H.js → shadow-claw-networking-Df85tCbO.js} +2 -2
- package/dist/lib/{shadow-claw-networking-DImPxe0H.js.map → shadow-claw-networking-Df85tCbO.js.map} +1 -1
- package/dist/lib/{shadow-claw-page-header-CcHUfFUx.js → shadow-claw-page-header-Cti2fzf-.js} +2 -2
- package/dist/lib/{shadow-claw-page-header-CcHUfFUx.js.map → shadow-claw-page-header-Cti2fzf-.js.map} +1 -1
- package/dist/lib/{shadow-claw-pages-D54jF1Qq.js → shadow-claw-pages-BgPyIEZO.js} +15 -11
- package/dist/lib/shadow-claw-pages-BgPyIEZO.js.map +1 -0
- package/dist/lib/{shadow-claw-peerjs-B9-T8Nlx.js → shadow-claw-peerjs-xkBXILed.js} +3 -3
- package/dist/lib/{shadow-claw-peerjs-B9-T8Nlx.js.map → shadow-claw-peerjs-xkBXILed.js.map} +1 -1
- package/dist/lib/{shadow-claw-settings-Bt1VAe-1.js → shadow-claw-settings-CN89xRVU.js} +4 -4
- package/dist/lib/{shadow-claw-settings-Bt1VAe-1.js.map → shadow-claw-settings-CN89xRVU.js.map} +1 -1
- package/dist/lib/{shadow-claw-storage-CFOjGf1d.js → shadow-claw-storage-VnhcObCe.js} +3 -3
- package/dist/lib/{shadow-claw-storage-CFOjGf1d.js.map → shadow-claw-storage-VnhcObCe.js.map} +1 -1
- package/dist/lib/{shadow-claw-task-server-BiKa2GOm.js → shadow-claw-task-server-jgEC2hHB.js} +2 -2
- package/dist/lib/{shadow-claw-task-server-BiKa2GOm.js.map → shadow-claw-task-server-jgEC2hHB.js.map} +1 -1
- package/dist/lib/{shadow-claw-tasks-DDHd8W4d.js → shadow-claw-tasks-i_evIufy.js} +6 -6
- package/dist/lib/{shadow-claw-tasks-DDHd8W4d.js.map → shadow-claw-tasks-i_evIufy.js.map} +1 -1
- package/dist/lib/{shadow-claw-terminal-kB6_tWKz.js → shadow-claw-terminal-CwScROlu.js} +2 -2
- package/dist/lib/{shadow-claw-terminal-kB6_tWKz.js.map → shadow-claw-terminal-CwScROlu.js.map} +1 -1
- package/dist/lib/{shadow-claw-tools-DxXIm0ku.js → shadow-claw-tools-DD3fyXP4.js} +5 -4
- package/dist/lib/{shadow-claw-tools-DxXIm0ku.js.map → shadow-claw-tools-DD3fyXP4.js.map} +1 -1
- package/dist/lib/{shadow-claw-webvm-Dc8oo7ao.js → shadow-claw-webvm-DbJq4I3-.js} +2 -2
- package/dist/lib/{shadow-claw-webvm-Dc8oo7ao.js.map → shadow-claw-webvm-DbJq4I3-.js.map} +1 -1
- package/dist/lib/{syncWebMcpRegistration-jyRGbC9w.js → syncWebMcpRegistration-DNLnQ-jz.js} +3 -2
- package/dist/lib/{syncWebMcpRegistration-jyRGbC9w.js.map → syncWebMcpRegistration-DNLnQ-jz.js.map} +1 -1
- package/dist/lib/tools-DwwB9RBa.js +546 -0
- package/dist/lib/tools-DwwB9RBa.js.map +1 -0
- package/dist/lib/{trusted-types-CkLDpLiZ.js → trusted-types-Dx0RZlrd.js} +19 -8
- package/dist/lib/trusted-types-Dx0RZlrd.js.map +1 -0
- package/dist/lib/utils/index.js +1 -1
- package/dist/lib/utils/utils.js +1 -1
- package/dist/public/.well-known/agent-skills/index.json +14 -0
- package/dist/public/AGENTS.md +5 -3
- package/dist/public/README.md +5 -3
- package/dist/public/agent.worker.js +1 -1
- package/dist/public/{configurePeerJs-COcwE0E7.js → configurePeerJs-BqgeBjP7.js} +1 -1
- package/dist/public/custom-element-security-FU04Cq05.js +1 -0
- package/dist/public/dist-B9m1QM9v.js +58 -0
- package/dist/public/docs/README.md +31 -31
- package/dist/public/docs/example/article/index.html +1 -1
- package/dist/public/docs/publishing/index.html +1 -1
- package/dist/public/docs/skill-creator/index.html +1 -1
- package/dist/public/docs/subsystems/a2ui.md +11 -1
- package/dist/public/docs/subsystems/cli.md +32 -0
- package/dist/public/docs/subsystems/control-plane.md +8 -2
- package/dist/public/docs/subsystems/custom-element-security.md +19 -9
- package/dist/public/docs/subsystems/mcp-server.md +39 -15
- package/dist/public/docs/subsystems/skills.md +30 -0
- package/dist/public/docs/subsystems/webmcp.md +9 -0
- package/dist/public/downloadGroupFile-D8KRJGGL.js +1 -0
- package/dist/public/e2e/README.md +7 -4
- package/dist/public/{e2e-bridge-CHARpbpW.js → e2e-bridge-Ceqr5kGc.js} +1 -1
- package/dist/public/effect-BJCrpFdp.js +1 -0
- package/dist/public/file-viewer-C-6Jc_tb.js +1 -0
- package/dist/public/index.html +1 -1
- package/dist/public/index.js +1 -1
- package/dist/public/initControlPlane-BN9cWyO0.js +1 -0
- package/dist/public/main/index.html +1 -1
- package/dist/public/main/memory/index.html +1 -1
- package/dist/public/{markdown-1I3O6Mmd.js → markdown-C3M4OW_A.js} +1 -1
- package/dist/public/{orchestrator-Cl95w2vb.js → orchestrator-CMbCTjBf.js} +7 -7
- package/dist/public/{orchestrator-D-xlXG92.js → orchestrator-DHjdLtqa.js} +663 -663
- package/dist/public/peerjs-DUCKH-m9.js +1 -0
- package/dist/public/service-worker.js +1 -1
- package/dist/public/{shadow-claw-CaoKmIIB.js → shadow-claw-EAt2ml5Y.js} +3 -3
- package/dist/public/{shadow-claw-accounts-CJvYC4li.js → shadow-claw-accounts-xUOLBsQZ.js} +1 -1
- package/dist/public/{shadow-claw-channels-3K62sU5f.js → shadow-claw-channels-XsfuWFF8.js} +4 -4
- package/dist/public/{shadow-claw-chat-Cu2keU2I.js → shadow-claw-chat-CbSaOZ4q.js} +7 -7
- package/dist/public/{shadow-claw-control-plane-D1OwlQI_.js → shadow-claw-control-plane-DHvN3Ukg.js} +2 -2
- package/dist/public/{shadow-claw-conversations-DDtg3BEZ.js → shadow-claw-conversations-BWs5VVfs.js} +2 -2
- package/dist/public/{shadow-claw-file-viewer-BR__1z9S.js → shadow-claw-file-viewer-BWsoW5QS.js} +5 -4
- package/dist/public/{shadow-claw-files-BJSyZ-Bl.js → shadow-claw-files-CG7MqWiV.js} +8 -8
- package/dist/public/{shadow-claw-git-MAjhXRLc.js → shadow-claw-git-DBRPZNav.js} +6 -6
- package/dist/public/{shadow-claw-integrations-82UoFuDR.js → shadow-claw-integrations-BBVnO0Fc.js} +8 -8
- package/dist/public/{shadow-claw-llm-R8j0lwPP.js → shadow-claw-llm-DMvLgKXo.js} +2 -2
- package/dist/public/{shadow-claw-mcp-remote-BzZoz4LX.js → shadow-claw-mcp-remote-Bkx0gsmF.js} +2 -2
- package/dist/public/{shadow-claw-networking-DLEd9cNm.js → shadow-claw-networking-Dd8Rw31D.js} +2 -2
- package/dist/public/{shadow-claw-notifications-1vwR7TbT.js → shadow-claw-notifications-Dbevj-lq.js} +2 -2
- package/dist/public/{shadow-claw-page-header-DMKbkv3s.js → shadow-claw-page-header-BccSHItx.js} +1 -1
- package/dist/public/{shadow-claw-pages-CjyeIV__.js → shadow-claw-pages-3_lQAv0t.js} +4 -3
- package/dist/public/{shadow-claw-settings-BfbT4dBU.js → shadow-claw-settings-t8TIlgrM.js} +5 -5
- package/dist/public/{shadow-claw-storage-C-mWQQML.js → shadow-claw-storage-CfEXoSIE.js} +2 -2
- package/dist/public/{shadow-claw-task-server-D3lHp0Nc.js → shadow-claw-task-server-DxQSsgRZ.js} +2 -2
- package/dist/public/{shadow-claw-tasks-DVVWEm-c.js → shadow-claw-tasks-DNpicQwz.js} +14 -14
- package/dist/public/{shadow-claw-terminal-BwuTRp-O.js → shadow-claw-terminal-DpY6zU_r.js} +1 -1
- package/dist/public/{shadow-claw-toast-ClCwgzFG.js → shadow-claw-toast-BkrQIP-3.js} +1 -1
- package/dist/public/{shadow-claw-tools-zFLk2nbV.js → shadow-claw-tools-WSwWohnk.js} +2 -2
- package/dist/public/{shadow-claw-webvm-qR9X7fg7.js → shadow-claw-webvm-CP6oFjg5.js} +2 -2
- package/dist/public/syncWebMcpRegistration-DOn9gLnD.js +1 -0
- package/dist/public/toast-BXgUfbyh.js +1 -0
- package/dist/public/tools-DvckJZG2.js +1 -0
- package/dist/server.js +188 -188
- package/package.json +3 -1
- package/src/components/shadow-claw-a2ui/shadow-claw-a2ui.stories.ts +1380 -93
- package/src/components/shadow-claw-a2ui/shadow-claw-a2ui.ts +11 -6
- package/src/components/shadow-claw-file-viewer/shadow-claw-file-viewer.test.ts +8 -1
- package/src/components/shadow-claw-file-viewer/shadow-claw-file-viewer.ts +13 -5
- package/src/components/shadow-claw-pages/utils/buildHtmlPageSrcdoc.ts +13 -5
- package/src/core/control-plane-client.ts +15 -0
- package/src/core/utils/initControlPlane.test.ts +187 -0
- package/src/core/utils/initControlPlane.ts +194 -20
- package/src/security/custom-element-security.test.ts +51 -0
- package/src/security/custom-element-security.ts +33 -15
- package/src/server/control-plane-types.ts +1 -0
- package/src/server/control-plane.test.ts +69 -0
- package/src/server/control-plane.ts +45 -3
- package/src/server/mcp/tools/built-in-tools.ts +80 -5
- package/src/server/mcp/tools/client-tool-relay.ts +183 -26
- package/src/server/mcp/tools/mcp-tools.test.ts +140 -0
- package/src/server/middleware/static-files.test.ts +142 -0
- package/src/server/middleware/static-files.ts +66 -8
- package/src/testing/jest-setup.ts +14 -0
- package/src/worker/utils/handleMessage.ts +4 -1
- package/dist/lib/initControlPlane-CsO4UR6_.js.map +0 -1
- package/dist/lib/readGroupFileBytes-Bve-e5e_.js.map +0 -1
- package/dist/lib/shadow-claw-file-viewer-BfDHHgpA.js.map +0 -1
- package/dist/lib/shadow-claw-pages-D54jF1Qq.js.map +0 -1
- package/dist/lib/trusted-types-CkLDpLiZ.js.map +0 -1
- package/dist/public/custom-element-security-NCqQ5lmC.js +0 -1
- package/dist/public/downloadGroupFile-G0BZQgQg.js +0 -1
- package/dist/public/effect-rHYr4nfu.js +0 -1
- package/dist/public/file-viewer-8PdCURDD.js +0 -1
- package/dist/public/initControlPlane-CcGXax0A.js +0 -1
- package/dist/public/peerjs-BZdxWQFv.js +0 -1
- package/dist/public/syncWebMcpRegistration-DD42YsYV.js +0 -1
- package/dist/public/toast-HAq8XWFj.js +0 -58
package/bin/cli.mjs
CHANGED
|
@@ -15,6 +15,7 @@ import { runTasksCommand } from "./commands/tasks.mjs";
|
|
|
15
15
|
import { runPeerIdCommand } from "./commands/peer-id.mjs";
|
|
16
16
|
import { runWebRtcListenCommand } from "./commands/webrtc-listen.mjs";
|
|
17
17
|
import { runMcpCommand } from "./commands/mcp.mjs";
|
|
18
|
+
import { runSkillsIndexCommand } from "./commands/skills-index.mjs";
|
|
18
19
|
import { resolveCacheDir } from "./utils/resolve-cache-dir.mjs";
|
|
19
20
|
|
|
20
21
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -962,4 +963,38 @@ program
|
|
|
962
963
|
await runMcpCommand(options);
|
|
963
964
|
});
|
|
964
965
|
|
|
966
|
+
// ---------------------------------------------------------------------------
|
|
967
|
+
// AGENT SKILLS INDEX COMMAND
|
|
968
|
+
// ---------------------------------------------------------------------------
|
|
969
|
+
program
|
|
970
|
+
.command("skills:index [dir]")
|
|
971
|
+
.alias("agent-skills")
|
|
972
|
+
.description(
|
|
973
|
+
"Generate or update .well-known/agent-skills/index.json per the Agent Skills Discovery RFC",
|
|
974
|
+
)
|
|
975
|
+
.option(
|
|
976
|
+
"--out-dir <dir>",
|
|
977
|
+
"Output directory relative to content root (default: .well-known/agent-skills)",
|
|
978
|
+
)
|
|
979
|
+
.option("--out-file <file>", "Explicit destination path for index.json")
|
|
980
|
+
.option(
|
|
981
|
+
"--metadata-root <dir>",
|
|
982
|
+
"Directory to read site metadata from (default: content root)",
|
|
983
|
+
)
|
|
984
|
+
.option(
|
|
985
|
+
"--config <file>",
|
|
986
|
+
"Explicit path to shadow-claw.config.json or site-config.json",
|
|
987
|
+
)
|
|
988
|
+
.option("--no-bundled", "Exclude bundled ShadowClaw skills from index")
|
|
989
|
+
.option("--stdout", "Print generated index.json to stdout", false)
|
|
990
|
+
.option("--no-write", "Skip writing file to disk")
|
|
991
|
+
.action(async (dir, options) => {
|
|
992
|
+
try {
|
|
993
|
+
await runSkillsIndexCommand(dir, options);
|
|
994
|
+
} catch (err) {
|
|
995
|
+
console.error("Failed to generate skills index:", err);
|
|
996
|
+
process.exit(1);
|
|
997
|
+
}
|
|
998
|
+
});
|
|
999
|
+
|
|
965
1000
|
program.parse(process.argv);
|
package/bin/commands/mcp.mjs
CHANGED
|
@@ -71,6 +71,22 @@ export const CLI_BUILTIN_TOOLS = [
|
|
|
71
71
|
},
|
|
72
72
|
},
|
|
73
73
|
},
|
|
74
|
+
{
|
|
75
|
+
name: "shadowclaw_set_active_client",
|
|
76
|
+
description:
|
|
77
|
+
"Set the active default connected client used when no clientId is explicitly provided in tool calls.",
|
|
78
|
+
inputSchema: {
|
|
79
|
+
type: "object",
|
|
80
|
+
properties: {
|
|
81
|
+
clientId: {
|
|
82
|
+
type: "string",
|
|
83
|
+
description:
|
|
84
|
+
"Target client ID (or index '0', '1', prefix, or device label) to make active.",
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
required: ["clientId"],
|
|
88
|
+
},
|
|
89
|
+
},
|
|
74
90
|
{
|
|
75
91
|
name: "shadowclaw_manage_backup",
|
|
76
92
|
description:
|
|
@@ -95,6 +111,7 @@ export function createCliMcpEngine(options = {}) {
|
|
|
95
111
|
const client = options.client || new CliControlClient(options);
|
|
96
112
|
const relayClientTools = options.relayClientTools !== false;
|
|
97
113
|
const targetClientId = options.targetClientId || options.clientTarget;
|
|
114
|
+
let activeClientId = targetClientId || "";
|
|
98
115
|
|
|
99
116
|
const serverInfo = {
|
|
100
117
|
name: "shadow-claw",
|
|
@@ -107,47 +124,138 @@ export function createCliMcpEngine(options = {}) {
|
|
|
107
124
|
};
|
|
108
125
|
|
|
109
126
|
async function resolveTargetId(requestedId) {
|
|
110
|
-
|
|
111
|
-
return requestedId.trim();
|
|
112
|
-
}
|
|
113
|
-
if (targetClientId) {
|
|
114
|
-
return targetClientId;
|
|
115
|
-
}
|
|
127
|
+
const candidate = requestedId || activeClientId || targetClientId;
|
|
116
128
|
try {
|
|
117
129
|
const clients = await client.listClients();
|
|
118
130
|
if (Array.isArray(clients) && clients.length > 0) {
|
|
131
|
+
if (candidate && typeof candidate === "string" && candidate.trim()) {
|
|
132
|
+
const trimmed = candidate.trim();
|
|
133
|
+
const exact = clients.find((c) => (c.clientId || c.id) === trimmed);
|
|
134
|
+
if (exact) return exact.clientId || exact.id;
|
|
135
|
+
|
|
136
|
+
const idx = parseInt(trimmed, 10);
|
|
137
|
+
if (!isNaN(idx) && idx >= 0 && idx < clients.length) {
|
|
138
|
+
return clients[idx].clientId || clients[idx].id;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const prefix = clients.find(
|
|
142
|
+
(c) =>
|
|
143
|
+
(c.clientId || c.id || "").startsWith(trimmed) ||
|
|
144
|
+
(c.clientId || "").replace(/^client-/, "").startsWith(trimmed),
|
|
145
|
+
);
|
|
146
|
+
if (prefix) return prefix.clientId || prefix.id;
|
|
147
|
+
|
|
148
|
+
const byLabel = clients.find((c) =>
|
|
149
|
+
c.deviceLabel?.toLowerCase().includes(trimmed.toLowerCase()),
|
|
150
|
+
);
|
|
151
|
+
if (byLabel) return byLabel.clientId || byLabel.id;
|
|
152
|
+
|
|
153
|
+
return trimmed;
|
|
154
|
+
}
|
|
155
|
+
|
|
119
156
|
return clients[0].clientId || clients[0].id || "";
|
|
120
157
|
}
|
|
121
158
|
} catch (_) {}
|
|
122
|
-
return "";
|
|
159
|
+
return typeof candidate === "string" ? candidate.trim() : "";
|
|
123
160
|
}
|
|
124
161
|
|
|
162
|
+
const toolSupportingClientsMap = new Map();
|
|
163
|
+
const toolDefMap = new Map();
|
|
164
|
+
|
|
125
165
|
async function getRelayedTools() {
|
|
126
166
|
if (!relayClientTools) {
|
|
127
167
|
return [];
|
|
128
168
|
}
|
|
129
|
-
|
|
130
|
-
if (!clientId) {
|
|
131
|
-
return [];
|
|
132
|
-
}
|
|
169
|
+
let clients = [];
|
|
133
170
|
try {
|
|
134
|
-
|
|
135
|
-
if (
|
|
136
|
-
res &&
|
|
137
|
-
res.success &&
|
|
138
|
-
res.data?.tools &&
|
|
139
|
-
Array.isArray(res.data.tools)
|
|
140
|
-
) {
|
|
141
|
-
return res.data.tools.map((t) => ({
|
|
142
|
-
name: t.name,
|
|
143
|
-
description:
|
|
144
|
-
t.description || `Relayed tool '${t.name}' from connected client.`,
|
|
145
|
-
inputSchema: t.inputSchema || { type: "object", properties: {} },
|
|
146
|
-
annotations: t.annotations,
|
|
147
|
-
}));
|
|
148
|
-
}
|
|
171
|
+
clients = await client.listClients();
|
|
149
172
|
} catch (_) {}
|
|
150
|
-
|
|
173
|
+
|
|
174
|
+
if (!Array.isArray(clients) || clients.length === 0) {
|
|
175
|
+
toolSupportingClientsMap.clear();
|
|
176
|
+
toolDefMap.clear();
|
|
177
|
+
return [];
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
toolSupportingClientsMap.clear();
|
|
181
|
+
toolDefMap.clear();
|
|
182
|
+
|
|
183
|
+
for (const c of clients) {
|
|
184
|
+
const cid = c.clientId || c.id;
|
|
185
|
+
if (!cid) continue;
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
const res = await client.sendCommand(cid, "list-tools", {});
|
|
189
|
+
if (
|
|
190
|
+
res &&
|
|
191
|
+
res.success &&
|
|
192
|
+
res.data?.tools &&
|
|
193
|
+
Array.isArray(res.data.tools)
|
|
194
|
+
) {
|
|
195
|
+
for (const t of res.data.tools) {
|
|
196
|
+
if (!toolDefMap.has(t.name)) {
|
|
197
|
+
toolDefMap.set(t.name, t);
|
|
198
|
+
toolSupportingClientsMap.set(t.name, []);
|
|
199
|
+
}
|
|
200
|
+
toolSupportingClientsMap.get(t.name).push(c);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
} catch (_) {}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const activeTargetId = await resolveTargetId();
|
|
207
|
+
const relayedTools = [];
|
|
208
|
+
|
|
209
|
+
for (const [toolName, t] of toolDefMap.entries()) {
|
|
210
|
+
const supportingClients = toolSupportingClientsMap.get(toolName) || [];
|
|
211
|
+
const supportingClientIds = supportingClients
|
|
212
|
+
.map((cl) => cl.clientId || cl.id)
|
|
213
|
+
.filter(Boolean);
|
|
214
|
+
|
|
215
|
+
const preferredClient =
|
|
216
|
+
supportingClients.find(
|
|
217
|
+
(cl) => (cl.clientId || cl.id) === activeTargetId,
|
|
218
|
+
) || supportingClients[0];
|
|
219
|
+
const toolDefaultId =
|
|
220
|
+
preferredClient?.clientId || preferredClient?.id || "";
|
|
221
|
+
const toolDefaultLabel = preferredClient?.deviceLabel || "Client";
|
|
222
|
+
|
|
223
|
+
const existingSchema =
|
|
224
|
+
t.inputSchema && typeof t.inputSchema === "object"
|
|
225
|
+
? t.inputSchema
|
|
226
|
+
: { type: "object", properties: {} };
|
|
227
|
+
|
|
228
|
+
const properties = {
|
|
229
|
+
...(existingSchema.properties || {}),
|
|
230
|
+
clientId: {
|
|
231
|
+
type: "string",
|
|
232
|
+
description: `Target ShadowClaw client ID (optional; defaults to ${toolDefaultId} [${toolDefaultLabel}]). Available on: ${supportingClients.map((cl) => `${cl.clientId || cl.id} (${cl.deviceLabel || "Client"})`).join(", ")}`,
|
|
233
|
+
enum: supportingClientIds,
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
const clientNote =
|
|
238
|
+
clients.length > 1
|
|
239
|
+
? supportingClients.length > 1
|
|
240
|
+
? ` [Default: ${toolDefaultLabel} (${toolDefaultId.slice(0, 14)}...)]`
|
|
241
|
+
: ` [Client: ${toolDefaultLabel} (${toolDefaultId.slice(0, 14)}...)]`
|
|
242
|
+
: "";
|
|
243
|
+
|
|
244
|
+
relayedTools.push({
|
|
245
|
+
name: t.name,
|
|
246
|
+
description:
|
|
247
|
+
(t.description || `Relayed tool '${t.name}' from connected client.`) +
|
|
248
|
+
clientNote,
|
|
249
|
+
inputSchema: {
|
|
250
|
+
...existingSchema,
|
|
251
|
+
type: "object",
|
|
252
|
+
properties,
|
|
253
|
+
},
|
|
254
|
+
annotations: t.annotations,
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return relayedTools;
|
|
151
259
|
}
|
|
152
260
|
|
|
153
261
|
async function handleMessage(request, headers = {}) {
|
|
@@ -260,6 +368,48 @@ export function createCliMcpEngine(options = {}) {
|
|
|
260
368
|
};
|
|
261
369
|
}
|
|
262
370
|
|
|
371
|
+
if (toolName === "shadowclaw_set_active_client") {
|
|
372
|
+
const targetId = await resolveTargetId(args.clientId);
|
|
373
|
+
if (!targetId) {
|
|
374
|
+
return {
|
|
375
|
+
jsonrpc: "2.0",
|
|
376
|
+
id: reqId,
|
|
377
|
+
result: {
|
|
378
|
+
resultType: "complete",
|
|
379
|
+
isError: true,
|
|
380
|
+
content: [
|
|
381
|
+
{
|
|
382
|
+
type: "text",
|
|
383
|
+
text: `Error: Client '${args.clientId}' not found among connected clients.`,
|
|
384
|
+
},
|
|
385
|
+
],
|
|
386
|
+
_meta: { "io.modelcontextprotocol/serverInfo": serverInfo },
|
|
387
|
+
},
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
activeClientId = targetId;
|
|
391
|
+
console.error(
|
|
392
|
+
`[ShadowClaw MCP] Active default client set to: ${activeClientId}`,
|
|
393
|
+
);
|
|
394
|
+
return {
|
|
395
|
+
jsonrpc: "2.0",
|
|
396
|
+
id: reqId,
|
|
397
|
+
result: {
|
|
398
|
+
resultType: "complete",
|
|
399
|
+
content: [
|
|
400
|
+
{
|
|
401
|
+
type: "text",
|
|
402
|
+
text: `Active default client set to: ${activeClientId}`,
|
|
403
|
+
},
|
|
404
|
+
],
|
|
405
|
+
_meta: {
|
|
406
|
+
activeClientId,
|
|
407
|
+
"io.modelcontextprotocol/serverInfo": serverInfo,
|
|
408
|
+
},
|
|
409
|
+
},
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
|
|
263
413
|
if (toolName === "shadowclaw_send_message") {
|
|
264
414
|
const targetId = await resolveTargetId(args.clientId);
|
|
265
415
|
if (!targetId) {
|
|
@@ -391,26 +541,12 @@ export function createCliMcpEngine(options = {}) {
|
|
|
391
541
|
};
|
|
392
542
|
}
|
|
393
543
|
|
|
394
|
-
// Relayed interactive ask_user tool
|
|
395
|
-
if (
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
result: {
|
|
401
|
-
resultType: "input_required",
|
|
402
|
-
inputRequests: [
|
|
403
|
-
{
|
|
404
|
-
id: "response",
|
|
405
|
-
type: "prompt",
|
|
406
|
-
message:
|
|
407
|
-
args.question || args.prompt || "User input requested",
|
|
408
|
-
},
|
|
409
|
-
],
|
|
410
|
-
_meta: { "io.modelcontextprotocol/serverInfo": serverInfo },
|
|
411
|
-
},
|
|
412
|
-
};
|
|
413
|
-
}
|
|
544
|
+
// Relayed interactive ask_user tool with MRTR response fulfillment if provided
|
|
545
|
+
if (
|
|
546
|
+
toolName === "ask_user" &&
|
|
547
|
+
inputResponses &&
|
|
548
|
+
inputResponses["response"]
|
|
549
|
+
) {
|
|
414
550
|
return {
|
|
415
551
|
jsonrpc: "2.0",
|
|
416
552
|
id: reqId,
|
|
@@ -425,7 +561,29 @@ export function createCliMcpEngine(options = {}) {
|
|
|
425
561
|
}
|
|
426
562
|
|
|
427
563
|
// Relayed client tools (invoke-tool)
|
|
428
|
-
|
|
564
|
+
if (toolDefMap.size === 0) {
|
|
565
|
+
await getRelayedTools();
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
const supportingClients = toolSupportingClientsMap.get(toolName) || [];
|
|
569
|
+
const supportingClientIds = supportingClients
|
|
570
|
+
.map((cl) => cl.clientId || cl.id)
|
|
571
|
+
.filter(Boolean);
|
|
572
|
+
|
|
573
|
+
let targetId = "";
|
|
574
|
+
if (args.clientId) {
|
|
575
|
+
targetId = await resolveTargetId(args.clientId);
|
|
576
|
+
} else {
|
|
577
|
+
const activeSessionId = await resolveTargetId();
|
|
578
|
+
if (supportingClientIds.includes(activeSessionId)) {
|
|
579
|
+
targetId = activeSessionId;
|
|
580
|
+
} else if (supportingClientIds.length > 0) {
|
|
581
|
+
targetId = supportingClientIds[0];
|
|
582
|
+
} else {
|
|
583
|
+
targetId = activeSessionId;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
429
587
|
if (!targetId) {
|
|
430
588
|
return {
|
|
431
589
|
jsonrpc: "2.0",
|
|
@@ -441,11 +599,51 @@ export function createCliMcpEngine(options = {}) {
|
|
|
441
599
|
};
|
|
442
600
|
}
|
|
443
601
|
|
|
602
|
+
if (
|
|
603
|
+
supportingClientIds.length > 0 &&
|
|
604
|
+
!supportingClientIds.includes(targetId)
|
|
605
|
+
) {
|
|
606
|
+
return {
|
|
607
|
+
jsonrpc: "2.0",
|
|
608
|
+
id: reqId,
|
|
609
|
+
result: {
|
|
610
|
+
resultType: "complete",
|
|
611
|
+
isError: true,
|
|
612
|
+
content: [
|
|
613
|
+
{
|
|
614
|
+
type: "text",
|
|
615
|
+
text: `Error: Tool '${toolName}' is not enabled or available on client '${targetId}'. (Available on: ${supportingClientIds.join(", ")})`,
|
|
616
|
+
},
|
|
617
|
+
],
|
|
618
|
+
_meta: {
|
|
619
|
+
clientId: targetId,
|
|
620
|
+
"io.modelcontextprotocol/serverInfo": serverInfo,
|
|
621
|
+
},
|
|
622
|
+
},
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
|
|
444
626
|
try {
|
|
445
|
-
|
|
446
|
-
toolName
|
|
447
|
-
|
|
448
|
-
}
|
|
627
|
+
console.error(
|
|
628
|
+
`[ShadowClaw MCP] Executing '${toolName}' on client: ${targetId}`,
|
|
629
|
+
);
|
|
630
|
+
const toolArgs = { ...args };
|
|
631
|
+
delete toolArgs.clientId;
|
|
632
|
+
const isInteractive = toolName === "ask_user";
|
|
633
|
+
const res = isInteractive
|
|
634
|
+
? await client.sendCommand(
|
|
635
|
+
targetId,
|
|
636
|
+
"invoke-tool",
|
|
637
|
+
{
|
|
638
|
+
toolName,
|
|
639
|
+
input: toolArgs,
|
|
640
|
+
},
|
|
641
|
+
300000,
|
|
642
|
+
)
|
|
643
|
+
: await client.sendCommand(targetId, "invoke-tool", {
|
|
644
|
+
toolName,
|
|
645
|
+
input: toolArgs,
|
|
646
|
+
});
|
|
449
647
|
|
|
450
648
|
const rawResult =
|
|
451
649
|
res.data?.result !== undefined ? res.data.result : res.data;
|
|
@@ -454,14 +652,31 @@ export function createCliMcpEngine(options = {}) {
|
|
|
454
652
|
? rawResult
|
|
455
653
|
: JSON.stringify(rawResult, null, 2);
|
|
456
654
|
|
|
655
|
+
const errorMessage =
|
|
656
|
+
res.error ||
|
|
657
|
+
(res.data && res.data.error) ||
|
|
658
|
+
"Unknown tool execution error";
|
|
659
|
+
|
|
457
660
|
return {
|
|
458
661
|
jsonrpc: "2.0",
|
|
459
662
|
id: reqId,
|
|
460
663
|
result: {
|
|
461
664
|
resultType: "complete",
|
|
462
665
|
isError: !res.success,
|
|
463
|
-
content: [
|
|
464
|
-
|
|
666
|
+
content: [
|
|
667
|
+
{
|
|
668
|
+
type: "text",
|
|
669
|
+
text: res.success
|
|
670
|
+
? textOutput || ""
|
|
671
|
+
: textOutput && textOutput !== "null" && textOutput !== "{}"
|
|
672
|
+
? `${textOutput}\n${errorMessage}`
|
|
673
|
+
: `Tool execution error: ${errorMessage}`,
|
|
674
|
+
},
|
|
675
|
+
],
|
|
676
|
+
_meta: {
|
|
677
|
+
clientId: targetId,
|
|
678
|
+
"io.modelcontextprotocol/serverInfo": serverInfo,
|
|
679
|
+
},
|
|
465
680
|
},
|
|
466
681
|
};
|
|
467
682
|
} catch (err) {
|
|
@@ -472,7 +687,10 @@ export function createCliMcpEngine(options = {}) {
|
|
|
472
687
|
resultType: "complete",
|
|
473
688
|
isError: true,
|
|
474
689
|
content: [{ type: "text", text: `Tool error: ${err.message}` }],
|
|
475
|
-
_meta: {
|
|
690
|
+
_meta: {
|
|
691
|
+
clientId: targetId,
|
|
692
|
+
"io.modelcontextprotocol/serverInfo": serverInfo,
|
|
693
|
+
},
|
|
476
694
|
},
|
|
477
695
|
};
|
|
478
696
|
}
|
|
@@ -511,6 +729,10 @@ export function createCliMcpEngine(options = {}) {
|
|
|
511
729
|
|
|
512
730
|
return {
|
|
513
731
|
handleMessage,
|
|
732
|
+
getActiveClientId: () => activeClientId,
|
|
733
|
+
setActiveClientId: (id) => {
|
|
734
|
+
activeClientId = id;
|
|
735
|
+
},
|
|
514
736
|
};
|
|
515
737
|
}
|
|
516
738
|
|