shadow-claw 1.27.1 → 1.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.well-known/ai-catalog.json +11 -0
- package/.well-known/mcp/index.html +19 -0
- package/.well-known/mcp/server-card.json +52 -0
- package/.well-known/mcp/servers.json +15 -0
- package/.well-known/mcp.json +52 -0
- package/.well-known/oauth-protected-resource +10 -0
- package/.well-known/oauth-protected-resource.json +10 -0
- package/bin/assert-version-bump.mjs +61 -3
- package/bin/assert-version-bump.test.mjs +77 -1
- package/bin/build/build.mjs +99 -34
- package/bin/build/build.test.mjs +32 -0
- package/bin/cli.mjs +290 -237
- package/bin/cli.test.mjs +27 -0
- package/bin/commands/mcp.mjs +132 -2
- package/bin/commands/mcp.test.mjs +166 -0
- package/bin/utils/control-client.mjs +17 -0
- package/bin/utils/control-client.test.mjs +46 -0
- package/bin/version.mjs +208 -0
- package/bin/version.test.mjs +138 -0
- package/dist/electron/main.cjs +195 -185
- package/dist/lib/components/index.js +21 -21
- 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-llm.js +1 -1
- package/dist/lib/components/settings/shadow-claw-networking.js +1 -1
- package/dist/lib/components/settings/shadow-claw-notifications.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/shadow-claw.d.ts +1 -0
- package/dist/lib/components/shadow-claw/utils/setupAppLifecycle.d.ts +23 -0
- 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-llm.js +1 -1
- package/dist/lib/components/shadow-claw-networking.js +1 -1
- package/dist/lib/components/shadow-claw-notifications.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-oODzltaC.js → configurePeerJs-D8Ph0-A9.js} +2 -2
- package/dist/lib/{configurePeerJs-oODzltaC.js.map → configurePeerJs-D8Ph0-A9.js.map} +1 -1
- package/dist/lib/core/control-plane-client.d.ts +2 -0
- package/dist/lib/core/orchestrator/orchestrator.d.ts +10 -0
- package/dist/lib/core/orchestrator/utils/operations/channel.d.ts +2 -2
- package/dist/lib/core/utils/initControlPlane.d.ts +6 -0
- package/dist/lib/index.js +21 -21
- package/dist/lib/{initControlPlane-C2zURVIS.js → initControlPlane-BIrWmpzc.js} +76 -9
- package/dist/lib/initControlPlane-BIrWmpzc.js.map +1 -0
- package/dist/lib/{markdown-C6EHl9zs.js → markdown-DEUoM1c6.js} +2 -2
- package/dist/lib/{markdown-C6EHl9zs.js.map → markdown-DEUoM1c6.js.map} +1 -1
- package/dist/lib/{orchestrator-KRjx0eba.js → orchestrator-BtVj9bBB.js} +11 -10
- package/dist/lib/{orchestrator-KRjx0eba.js.map → orchestrator-BtVj9bBB.js.map} +1 -1
- package/dist/lib/{orchestrator-CACLa_Ro.js → orchestrator-CFCW-l1O.js} +52 -4
- package/dist/lib/orchestrator-CFCW-l1O.js.map +1 -0
- package/dist/lib/{peerjs-DFWOBcXf.js → peerjs-BoBkx9DJ.js} +23 -3
- package/dist/lib/peerjs-BoBkx9DJ.js.map +1 -0
- package/dist/lib/{push-client-_tiWQsCT.js → push-client-D6hbzDNV.js} +10 -4
- package/dist/lib/push-client-D6hbzDNV.js.map +1 -0
- package/dist/lib/{shadow-claw-6UHdiy4a.js → shadow-claw-Cuf2O5bZ.js} +71 -4
- package/dist/lib/shadow-claw-Cuf2O5bZ.js.map +1 -0
- package/dist/lib/{shadow-claw-channel-config-DmfwJc6G.js → shadow-claw-channel-config-BDPKt6Bd.js} +3 -3
- package/dist/lib/{shadow-claw-channel-config-DmfwJc6G.js.map → shadow-claw-channel-config-BDPKt6Bd.js.map} +1 -1
- package/dist/lib/{shadow-claw-channels-1N6Jl-By.js → shadow-claw-channels-BsP5JABM.js} +2 -2
- package/dist/lib/{shadow-claw-channels-1N6Jl-By.js.map → shadow-claw-channels-BsP5JABM.js.map} +1 -1
- package/dist/lib/{shadow-claw-chat-BMoqQJRK.js → shadow-claw-chat-Cam2lX4k.js} +4 -4
- package/dist/lib/{shadow-claw-chat-BMoqQJRK.js.map → shadow-claw-chat-Cam2lX4k.js.map} +1 -1
- package/dist/lib/{shadow-claw-control-plane-UG0o7pCz.js → shadow-claw-control-plane-DB2qcCFs.js} +20 -10
- package/dist/lib/shadow-claw-control-plane-DB2qcCFs.js.map +1 -0
- package/dist/lib/{shadow-claw-conversations-BwXep3iu.js → shadow-claw-conversations-C9Vf4XGx.js} +2 -2
- package/dist/lib/{shadow-claw-conversations-BwXep3iu.js.map → shadow-claw-conversations-C9Vf4XGx.js.map} +1 -1
- package/dist/lib/{shadow-claw-file-viewer-DUxzVxDT.js → shadow-claw-file-viewer-B4HYiI0v.js} +3 -3
- package/dist/lib/{shadow-claw-file-viewer-DUxzVxDT.js.map → shadow-claw-file-viewer-B4HYiI0v.js.map} +1 -1
- package/dist/lib/{shadow-claw-files-DIREEnT2.js → shadow-claw-files-DVROUESO.js} +2 -2
- package/dist/lib/{shadow-claw-files-DIREEnT2.js.map → shadow-claw-files-DVROUESO.js.map} +1 -1
- package/dist/lib/{shadow-claw-git-Bg1SWgsF.js → shadow-claw-git-BqrO7cHJ.js} +3 -3
- package/dist/lib/{shadow-claw-git-Bg1SWgsF.js.map → shadow-claw-git-BqrO7cHJ.js.map} +1 -1
- package/dist/lib/{shadow-claw-llm-CazBrVpM.js → shadow-claw-llm-BexUQdYo.js} +2 -2
- package/dist/lib/{shadow-claw-llm-CazBrVpM.js.map → shadow-claw-llm-BexUQdYo.js.map} +1 -1
- package/dist/lib/{shadow-claw-networking-Df85tCbO.js → shadow-claw-networking-CfXRGpUD.js} +2 -2
- package/dist/lib/{shadow-claw-networking-Df85tCbO.js.map → shadow-claw-networking-CfXRGpUD.js.map} +1 -1
- package/dist/lib/{shadow-claw-notifications-v62FryTc.js → shadow-claw-notifications-C9KPMgx_.js} +2 -2
- package/dist/lib/{shadow-claw-notifications-v62FryTc.js.map → shadow-claw-notifications-C9KPMgx_.js.map} +1 -1
- package/dist/lib/{shadow-claw-pages-BgPyIEZO.js → shadow-claw-pages-CGzGXmrI.js} +3 -3
- package/dist/lib/{shadow-claw-pages-BgPyIEZO.js.map → shadow-claw-pages-CGzGXmrI.js.map} +1 -1
- package/dist/lib/{shadow-claw-peerjs-xkBXILed.js → shadow-claw-peerjs-B0ZB7yhB.js} +3 -3
- package/dist/lib/{shadow-claw-peerjs-xkBXILed.js.map → shadow-claw-peerjs-B0ZB7yhB.js.map} +1 -1
- package/dist/lib/{shadow-claw-settings-CN89xRVU.js → shadow-claw-settings-DBfMZdDS.js} +2 -2
- package/dist/lib/{shadow-claw-settings-CN89xRVU.js.map → shadow-claw-settings-DBfMZdDS.js.map} +1 -1
- package/dist/lib/{shadow-claw-storage-VnhcObCe.js → shadow-claw-storage-CM-w6mgG.js} +2 -2
- package/dist/lib/{shadow-claw-storage-VnhcObCe.js.map → shadow-claw-storage-CM-w6mgG.js.map} +1 -1
- package/dist/lib/{shadow-claw-task-server-jgEC2hHB.js → shadow-claw-task-server-DV4b1g2-.js} +4 -2
- package/dist/lib/{shadow-claw-task-server-jgEC2hHB.js.map → shadow-claw-task-server-DV4b1g2-.js.map} +1 -1
- package/dist/lib/{shadow-claw-tasks-i_evIufy.js → shadow-claw-tasks-K-foOHSE.js} +3 -3
- package/dist/lib/{shadow-claw-tasks-i_evIufy.js.map → shadow-claw-tasks-K-foOHSE.js.map} +1 -1
- package/dist/lib/{shadow-claw-terminal-CwScROlu.js → shadow-claw-terminal-CpAknKyA.js} +2 -2
- package/dist/lib/{shadow-claw-terminal-CwScROlu.js.map → shadow-claw-terminal-CpAknKyA.js.map} +1 -1
- package/dist/lib/{shadow-claw-tools-DD3fyXP4.js → shadow-claw-tools-D98XZ0Ep.js} +3 -3
- package/dist/lib/{shadow-claw-tools-DD3fyXP4.js.map → shadow-claw-tools-D98XZ0Ep.js.map} +1 -1
- package/dist/lib/{shadow-claw-webvm-DbJq4I3-.js → shadow-claw-webvm-DLOb8dMI.js} +2 -2
- package/dist/lib/{shadow-claw-webvm-DbJq4I3-.js.map → shadow-claw-webvm-DLOb8dMI.js.map} +1 -1
- package/dist/lib/subsystems/channels/imessage.d.ts +1 -0
- package/dist/lib/subsystems/channels/peerjs.d.ts +1 -0
- package/dist/lib/subsystems/channels/telegram.d.ts +1 -0
- package/dist/lib/subsystems/channels/types.d.ts +2 -0
- package/dist/lib/subsystems/notifications/push-client.d.ts +1 -1
- package/dist/lib/{syncWebMcpRegistration-DNLnQ-jz.js → syncWebMcpRegistration-NspKefOI.js} +2 -2
- package/dist/lib/{syncWebMcpRegistration-DNLnQ-jz.js.map → syncWebMcpRegistration-NspKefOI.js.map} +1 -1
- package/dist/public/.well-known/ai-catalog.json +11 -0
- package/dist/public/.well-known/mcp/index.html +19 -0
- package/dist/public/.well-known/mcp/server-card.json +52 -0
- package/dist/public/.well-known/mcp/servers.json +15 -0
- package/dist/public/.well-known/mcp.json +52 -0
- package/dist/public/.well-known/oauth-protected-resource +10 -0
- package/dist/public/.well-known/oauth-protected-resource.json +10 -0
- package/dist/public/404.html +28 -1
- package/dist/public/agent.worker.js +1 -1
- package/dist/public/{configurePeerJs-BqgeBjP7.js → configurePeerJs-BhBokQlC.js} +1 -1
- package/dist/public/docs/example/article/index.html +3 -3
- package/dist/public/docs/publishing/index.html +3 -3
- package/dist/public/docs/skill-creator/index.html +3 -3
- package/dist/public/docs/subsystems/mcp-server.md +1 -0
- package/dist/public/docs/subsystems/notifications.md +10 -0
- package/dist/public/{e2e-bridge-Ceqr5kGc.js → e2e-bridge-DcBoeFvd.js} +1 -1
- package/dist/public/{file-viewer-C-6Jc_tb.js → file-viewer-CKtVC9Ix.js} +1 -1
- package/dist/public/index.css +1 -1
- package/dist/public/index.html +3 -3
- package/dist/public/index.js +1 -1
- package/dist/public/initControlPlane-Bi8ouFEb.js +1 -0
- package/dist/public/llms.txt +36 -1
- package/dist/public/main/index.html +3 -3
- package/dist/public/main/memory/index.html +3 -3
- package/dist/public/{markdown-C3M4OW_A.js → markdown-C-hCVJtc.js} +1 -1
- package/dist/public/orchestrator-8qNGfw8r.js +15 -0
- package/dist/public/{orchestrator-DHjdLtqa.js → orchestrator-BT3Ks5ip.js} +2 -2
- package/dist/public/peerjs-DfhwEiiq.js +1 -0
- package/dist/public/push-client-BVLrE9pK.js +1 -0
- package/dist/public/service-worker/fetch-proxy.js +1 -1
- package/dist/public/service-worker.js +1 -1
- package/dist/public/{shadow-claw-EAt2ml5Y.js → shadow-claw-DCjxNDCX.js} +3 -3
- package/dist/public/{shadow-claw-channels-XsfuWFF8.js → shadow-claw-channels-CITDrqMl.js} +1 -1
- package/dist/public/{shadow-claw-chat-CbSaOZ4q.js → shadow-claw-chat-BQrSgSKF.js} +1 -1
- package/dist/public/{shadow-claw-control-plane-DHvN3Ukg.js → shadow-claw-control-plane-Cp001OY0.js} +2 -2
- package/dist/public/{shadow-claw-conversations-BWs5VVfs.js → shadow-claw-conversations-EhX4RvIj.js} +1 -1
- package/dist/public/{shadow-claw-file-viewer-BWsoW5QS.js → shadow-claw-file-viewer-DiQXIjZD.js} +1 -1
- package/dist/public/{shadow-claw-files-CG7MqWiV.js → shadow-claw-files-lkTnSJsn.js} +1 -1
- package/dist/public/{shadow-claw-git-DBRPZNav.js → shadow-claw-git-BlcA_z8x.js} +2 -2
- package/dist/public/{shadow-claw-llm-DMvLgKXo.js → shadow-claw-llm-CW16X9Rg.js} +1 -1
- package/dist/public/{shadow-claw-networking-Dd8Rw31D.js → shadow-claw-networking-ySsMBY_i.js} +1 -1
- package/dist/public/{shadow-claw-notifications-Dbevj-lq.js → shadow-claw-notifications-CyV2zCQ8.js} +1 -1
- package/dist/public/{shadow-claw-pages-3_lQAv0t.js → shadow-claw-pages-Cx7cF9ah.js} +1 -1
- package/dist/public/{shadow-claw-settings-t8TIlgrM.js → shadow-claw-settings-zm4PHHGi.js} +2 -2
- package/dist/public/{shadow-claw-storage-CfEXoSIE.js → shadow-claw-storage-dy9JAEGd.js} +1 -1
- package/dist/public/{shadow-claw-task-server-DxQSsgRZ.js → shadow-claw-task-server-Bleww48s.js} +2 -2
- package/dist/public/{shadow-claw-tasks-DNpicQwz.js → shadow-claw-tasks-CTI5oaLN.js} +1 -1
- package/dist/public/{shadow-claw-terminal-DpY6zU_r.js → shadow-claw-terminal-mZ3i4HaQ.js} +1 -1
- package/dist/public/{shadow-claw-tools-WSwWohnk.js → shadow-claw-tools-B_nuk8Zl.js} +1 -1
- package/dist/public/{shadow-claw-webvm-CP6oFjg5.js → shadow-claw-webvm-Vl_jH5YL.js} +1 -1
- package/dist/public/{syncWebMcpRegistration-DOn9gLnD.js → syncWebMcpRegistration-n2vAMJ4w.js} +1 -1
- package/dist/server.js +197 -187
- package/package.json +2 -1
- package/src/components/settings/shadow-claw-control-plane/shadow-claw-control-plane.test.ts +6 -0
- package/src/components/settings/shadow-claw-control-plane/shadow-claw-control-plane.ts +19 -9
- package/src/components/settings/shadow-claw-task-server/shadow-claw-task-server.test.ts +14 -0
- package/src/components/settings/shadow-claw-task-server/shadow-claw-task-server.ts +12 -0
- package/src/components/shadow-claw/shadow-claw.ts +6 -0
- package/src/components/shadow-claw/utils/bindEventListeners.test.ts +57 -0
- package/src/components/shadow-claw/utils/bindEventListeners.ts +14 -0
- package/src/components/shadow-claw/utils/setupAppLifecycle.test.ts +201 -0
- package/src/components/shadow-claw/utils/setupAppLifecycle.ts +101 -0
- package/src/core/control-plane-client.test.ts +82 -1
- package/src/core/control-plane-client.ts +35 -1
- package/src/core/orchestrator/orchestrator.test.ts +49 -0
- package/src/core/orchestrator/orchestrator.ts +43 -0
- package/src/core/orchestrator/utils/operations/channel.test.ts +17 -0
- package/src/core/orchestrator/utils/operations/channel.ts +11 -5
- package/src/core/orchestrator/utils/operations/task.test.ts +26 -0
- package/src/core/orchestrator/utils/operations/task.ts +8 -1
- package/src/core/utils/initControlPlane.test.ts +138 -0
- package/src/core/utils/initControlPlane.ts +82 -0
- package/src/core/utils/initializeApp.test.ts +27 -1
- package/src/core/utils/initializeApp.ts +6 -13
- package/src/server/mcp/mcp-server.test.ts +6 -0
- package/src/server/mcp/mcp-server.ts +2 -1
- package/src/server/mcp/tools/built-in-tools.ts +88 -1
- package/src/server/mcp/tools/client-tool-relay.ts +6 -0
- package/src/server/mcp/tools/mcp-tools.test.ts +128 -0
- package/src/server/openapi/openapi-coverage.test.ts +2 -1
- package/src/server/openapi/openapi-spec.ts +2 -1
- package/src/server/openapi/paths/mcp.ts +104 -0
- package/src/server/openapi/paths/push.ts +3 -0
- package/src/server/routes/mcp.test.ts +92 -0
- package/src/server/routes/mcp.ts +138 -2
- package/src/server/utils/packageVersion.test.ts +10 -0
- package/src/server/utils/packageVersion.ts +32 -0
- package/src/service-worker/fetch-proxy-rules.test.ts +73 -0
- package/src/service-worker/fetch-proxy-rules.ts +44 -0
- package/src/service-worker/fetch-proxy.ts +1 -1
- package/src/subsystems/channels/imessage.test.ts +36 -0
- package/src/subsystems/channels/imessage.ts +11 -0
- package/src/subsystems/channels/peerjs.test.ts +56 -0
- package/src/subsystems/channels/peerjs.ts +29 -0
- package/src/subsystems/channels/telegram.test.ts +38 -0
- package/src/subsystems/channels/telegram.ts +13 -0
- package/src/subsystems/channels/types.ts +2 -0
- package/src/subsystems/notifications/push-client.test.ts +70 -0
- package/src/subsystems/notifications/push-client.ts +28 -3
- package/src/subsystems/notifications/push-routes.test.ts +82 -0
- package/src/subsystems/notifications/push-routes.ts +70 -16
- package/src/subsystems/notifications/push-store.test.ts +59 -0
- package/src/subsystems/notifications/push-store.ts +113 -19
- package/src/testing/jest-setup.ts +2 -0
- package/dist/lib/initControlPlane-C2zURVIS.js.map +0 -1
- package/dist/lib/orchestrator-CACLa_Ro.js.map +0 -1
- package/dist/lib/peerjs-DFWOBcXf.js.map +0 -1
- package/dist/lib/push-client-_tiWQsCT.js.map +0 -1
- package/dist/lib/shadow-claw-6UHdiy4a.js.map +0 -1
- package/dist/lib/shadow-claw-control-plane-UG0o7pCz.js.map +0 -1
- package/dist/public/initControlPlane-BN9cWyO0.js +0 -1
- package/dist/public/orchestrator-CMbCTjBf.js +0 -15
- package/dist/public/peerjs-DUCKH-m9.js +0 -1
- package/dist/public/push-client-D0lkwrK0.js +0 -1
package/bin/cli.mjs
CHANGED
|
@@ -62,17 +62,34 @@ program
|
|
|
62
62
|
.description("Browser-native personal AI assistant and static site publisher")
|
|
63
63
|
.version(version, "-v, --version", "Output the current version");
|
|
64
64
|
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// DEVELOPMENT COMMANDS
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
program.commandsGroup("Development:");
|
|
69
|
+
|
|
65
70
|
// ---------------------------------------------------------------------------
|
|
66
71
|
// BUILD COMMAND
|
|
67
72
|
// ---------------------------------------------------------------------------
|
|
68
73
|
program
|
|
69
74
|
.command("build")
|
|
70
75
|
.description("Build the static site bundle for production or staging")
|
|
76
|
+
.optionsGroup("Build Mode Options:")
|
|
71
77
|
.option(
|
|
72
78
|
"--prod, --production",
|
|
73
79
|
"Build in production mode with minification and optimizations",
|
|
74
80
|
false,
|
|
75
81
|
)
|
|
82
|
+
.option(
|
|
83
|
+
"--prerender-pages <mode>",
|
|
84
|
+
"Prerender page mode (all, auto, none)",
|
|
85
|
+
"auto",
|
|
86
|
+
)
|
|
87
|
+
.option(
|
|
88
|
+
"--copy-all-assets",
|
|
89
|
+
"Copy entire assets/ directory into output",
|
|
90
|
+
false,
|
|
91
|
+
)
|
|
92
|
+
.optionsGroup("Path & Routing Options:")
|
|
76
93
|
.option(
|
|
77
94
|
"--origin <url>",
|
|
78
95
|
"Canonical origin URL (e.g. https://user.github.io/repo/)",
|
|
@@ -84,16 +101,6 @@ program
|
|
|
84
101
|
"dist/public",
|
|
85
102
|
)
|
|
86
103
|
.option("--content-root <dir>", "Content root directory", process.cwd())
|
|
87
|
-
.option(
|
|
88
|
-
"--prerender-pages <mode>",
|
|
89
|
-
"Prerender page mode (all, auto, none)",
|
|
90
|
-
"auto",
|
|
91
|
-
)
|
|
92
|
-
.option(
|
|
93
|
-
"--copy-all-assets",
|
|
94
|
-
"Copy entire assets/ directory into output",
|
|
95
|
-
false,
|
|
96
|
-
)
|
|
97
104
|
.action(async (options) => {
|
|
98
105
|
try {
|
|
99
106
|
const contentRoot = path.resolve(options.contentRoot || process.cwd());
|
|
@@ -243,26 +250,32 @@ async function handleDev(portArg, options) {
|
|
|
243
250
|
program
|
|
244
251
|
.command("dev [port]")
|
|
245
252
|
.description("Build and launch the development server")
|
|
253
|
+
.optionsGroup("Server & Network Options:")
|
|
246
254
|
.option("-p, --port <port>", "Port to listen on (default: 8888)")
|
|
247
255
|
.option("--host <host>", "Bind host/IP", "127.0.0.1")
|
|
248
256
|
.option("--ip <host>", "Bind host/IP (alias)")
|
|
257
|
+
.option("--open", "Automatically open default browser", false)
|
|
258
|
+
.option("-v, --verbose", "Enable verbose request/proxy logging", false)
|
|
259
|
+
.optionsGroup("Site & Build Options:")
|
|
249
260
|
.option("--content-root <dir>", "Content root directory", process.cwd())
|
|
250
261
|
.option(
|
|
251
262
|
"--out-dir <dir>",
|
|
252
263
|
"Output directory relative to content root",
|
|
253
264
|
"dist/public",
|
|
254
265
|
)
|
|
266
|
+
.optionsGroup("Security & Proxy Options:")
|
|
255
267
|
.option(
|
|
256
268
|
"--cors-mode <mode>",
|
|
257
269
|
"CORS policy: localhost | private | all",
|
|
258
270
|
"localhost",
|
|
259
271
|
)
|
|
260
|
-
.option("--peerjs", "Enable built-in PeerJS signaling server", false)
|
|
261
272
|
.option(
|
|
262
273
|
"--allow-private-proxy",
|
|
263
274
|
"Allow proxy to reach private/loopback addresses",
|
|
264
275
|
false,
|
|
265
276
|
)
|
|
277
|
+
.option("--peerjs", "Enable built-in PeerJS signaling server", false)
|
|
278
|
+
.optionsGroup("TLS / HTTPS Options:")
|
|
266
279
|
.option("--https", "Enable HTTPS dev server", false)
|
|
267
280
|
.option("--cert <path>", "Path to existing TLS certificate file")
|
|
268
281
|
.option("--key <path>", "Path to existing TLS private key file")
|
|
@@ -270,6 +283,7 @@ program
|
|
|
270
283
|
"--ssl-dir <path>",
|
|
271
284
|
"Directory for TLS certificate generation/storage",
|
|
272
285
|
)
|
|
286
|
+
.optionsGroup("Storage & Database Options:")
|
|
273
287
|
.option("--database-dir <dir>", "Directory where SQLite databases are stored")
|
|
274
288
|
.option(
|
|
275
289
|
"--cache-dir <dir>",
|
|
@@ -285,33 +299,37 @@ program
|
|
|
285
299
|
"Skip interactive cache directory prompt and use default .cache",
|
|
286
300
|
false,
|
|
287
301
|
)
|
|
288
|
-
.option("-v, --verbose", "Enable verbose request/proxy logging", false)
|
|
289
|
-
.option("--open", "Automatically open default browser", false)
|
|
290
302
|
.action(handleDev);
|
|
291
303
|
|
|
292
304
|
program
|
|
293
305
|
.command("run [port]")
|
|
294
306
|
.description("Alias for dev: build and launch the development server")
|
|
307
|
+
.optionsGroup("Server & Network Options:")
|
|
295
308
|
.option("-p, --port <port>", "Port to listen on (default: 8888)")
|
|
296
309
|
.option("--host <host>", "Bind host/IP", "127.0.0.1")
|
|
297
310
|
.option("--ip <host>", "Bind host/IP (alias)")
|
|
311
|
+
.option("--open", "Automatically open default browser", false)
|
|
312
|
+
.option("-v, --verbose", "Enable verbose request/proxy logging", false)
|
|
313
|
+
.optionsGroup("Site & Build Options:")
|
|
298
314
|
.option("--content-root <dir>", "Content root directory", process.cwd())
|
|
299
315
|
.option(
|
|
300
316
|
"--out-dir <dir>",
|
|
301
317
|
"Output directory relative to content root",
|
|
302
318
|
"dist/public",
|
|
303
319
|
)
|
|
320
|
+
.optionsGroup("Security & Proxy Options:")
|
|
304
321
|
.option(
|
|
305
322
|
"--cors-mode <mode>",
|
|
306
323
|
"CORS policy: localhost | private | all",
|
|
307
324
|
"localhost",
|
|
308
325
|
)
|
|
309
|
-
.option("--peerjs", "Enable built-in PeerJS signaling server", false)
|
|
310
326
|
.option(
|
|
311
327
|
"--allow-private-proxy",
|
|
312
328
|
"Allow proxy to reach private/loopback addresses",
|
|
313
329
|
false,
|
|
314
330
|
)
|
|
331
|
+
.option("--peerjs", "Enable built-in PeerJS signaling server", false)
|
|
332
|
+
.optionsGroup("TLS / HTTPS Options:")
|
|
315
333
|
.option("--https", "Enable HTTPS dev server", false)
|
|
316
334
|
.option("--cert <path>", "Path to existing TLS certificate file")
|
|
317
335
|
.option("--key <path>", "Path to existing TLS private key file")
|
|
@@ -319,6 +337,7 @@ program
|
|
|
319
337
|
"--ssl-dir <path>",
|
|
320
338
|
"Directory for TLS certificate generation/storage",
|
|
321
339
|
)
|
|
340
|
+
.optionsGroup("Storage & Database Options:")
|
|
322
341
|
.option("--database-dir <dir>", "Directory where SQLite databases are stored")
|
|
323
342
|
.option(
|
|
324
343
|
"--cache-dir <dir>",
|
|
@@ -334,10 +353,13 @@ program
|
|
|
334
353
|
"Skip interactive cache directory prompt and use default .cache",
|
|
335
354
|
false,
|
|
336
355
|
)
|
|
337
|
-
.option("-v, --verbose", "Enable verbose request/proxy logging", false)
|
|
338
|
-
.option("--open", "Automatically open default browser", false)
|
|
339
356
|
.action(handleDev);
|
|
340
357
|
|
|
358
|
+
// ---------------------------------------------------------------------------
|
|
359
|
+
// SERVER COMMANDS
|
|
360
|
+
// ---------------------------------------------------------------------------
|
|
361
|
+
program.commandsGroup("Server:");
|
|
362
|
+
|
|
341
363
|
// ---------------------------------------------------------------------------
|
|
342
364
|
// SERVE COMMAND
|
|
343
365
|
// ---------------------------------------------------------------------------
|
|
@@ -346,25 +368,35 @@ program
|
|
|
346
368
|
.description(
|
|
347
369
|
"Serve an existing static site build and start the backend proxy",
|
|
348
370
|
)
|
|
371
|
+
.optionsGroup("Server & Network Options:")
|
|
349
372
|
.option("-p, --port <port>", "Port to listen on (default: 8888)")
|
|
350
373
|
.option("--host <host>", "Bind host/IP", "127.0.0.1")
|
|
374
|
+
.option(
|
|
375
|
+
"--no-static",
|
|
376
|
+
"Disable static file and UI serving (services-only mode)",
|
|
377
|
+
)
|
|
378
|
+
.option("--open", "Automatically open default browser", false)
|
|
379
|
+
.option("-v, --verbose", "Enable verbose request/proxy logging", false)
|
|
380
|
+
.optionsGroup("Site Options:")
|
|
351
381
|
.option("--content-root <dir>", "Content root directory", process.cwd())
|
|
352
382
|
.option(
|
|
353
383
|
"--out-dir <dir>",
|
|
354
384
|
"Output directory relative to content root",
|
|
355
385
|
"dist/public",
|
|
356
386
|
)
|
|
387
|
+
.optionsGroup("Security & Proxy Options:")
|
|
357
388
|
.option(
|
|
358
389
|
"--cors-mode <mode>",
|
|
359
390
|
"CORS policy: localhost | private | all",
|
|
360
391
|
"localhost",
|
|
361
392
|
)
|
|
362
|
-
.option("--peerjs", "Enable built-in PeerJS signaling server", false)
|
|
363
393
|
.option(
|
|
364
394
|
"--allow-private-proxy",
|
|
365
395
|
"Allow proxy to reach private/loopback addresses",
|
|
366
396
|
false,
|
|
367
397
|
)
|
|
398
|
+
.option("--peerjs", "Enable built-in PeerJS signaling server", false)
|
|
399
|
+
.optionsGroup("TLS / HTTPS Options:")
|
|
368
400
|
.option("--https", "Enable HTTPS dev server", false)
|
|
369
401
|
.option("--cert <path>", "Path to existing TLS certificate file")
|
|
370
402
|
.option("--key <path>", "Path to existing TLS private key file")
|
|
@@ -372,6 +404,7 @@ program
|
|
|
372
404
|
"--ssl-dir <path>",
|
|
373
405
|
"Directory for TLS certificate generation/storage",
|
|
374
406
|
)
|
|
407
|
+
.optionsGroup("Storage & Database Options:")
|
|
375
408
|
.option("--database-dir <dir>", "Directory where SQLite databases are stored")
|
|
376
409
|
.option(
|
|
377
410
|
"--cache-dir <dir>",
|
|
@@ -387,12 +420,6 @@ program
|
|
|
387
420
|
"Skip interactive cache directory prompt and use default .cache",
|
|
388
421
|
false,
|
|
389
422
|
)
|
|
390
|
-
.option(
|
|
391
|
-
"--no-static",
|
|
392
|
-
"Disable static file and UI serving (services-only mode)",
|
|
393
|
-
)
|
|
394
|
-
.option("-v, --verbose", "Enable verbose request/proxy logging", false)
|
|
395
|
-
.option("--open", "Automatically open default browser", false)
|
|
396
423
|
.action(async (portArg, options) => {
|
|
397
424
|
try {
|
|
398
425
|
const contentRoot = path.resolve(options.contentRoot || process.cwd());
|
|
@@ -623,25 +650,12 @@ program
|
|
|
623
650
|
.description(
|
|
624
651
|
"Start backend services (Express, MCP, control plane) without building or serving the UI (aliases: services, api)",
|
|
625
652
|
)
|
|
653
|
+
.optionsGroup("Server & Network Options:")
|
|
626
654
|
.option("-p, --port <port>", "Port to listen on (default: 8888)")
|
|
627
655
|
.option("--host <host>", "Bind host/IP", "127.0.0.1")
|
|
628
656
|
.option("--ip <host>", "Bind host/IP (alias)")
|
|
629
|
-
.option("
|
|
630
|
-
.
|
|
631
|
-
.option(
|
|
632
|
-
"--cache-dir <dir>",
|
|
633
|
-
"Custom cache directory for databases, tokens, and logs",
|
|
634
|
-
)
|
|
635
|
-
.option(
|
|
636
|
-
"--tmp, --temp",
|
|
637
|
-
"Store cache and databases in system temporary directory",
|
|
638
|
-
false,
|
|
639
|
-
)
|
|
640
|
-
.option(
|
|
641
|
-
"-y, --yes",
|
|
642
|
-
"Skip interactive cache directory prompt and use default .cache",
|
|
643
|
-
false,
|
|
644
|
-
)
|
|
657
|
+
.option("-v, --verbose", "Enable verbose request/proxy logging", false)
|
|
658
|
+
.optionsGroup("Security & Proxy Options:")
|
|
645
659
|
.option(
|
|
646
660
|
"--cors-mode <mode>",
|
|
647
661
|
"CORS policy: localhost | private | all",
|
|
@@ -661,6 +675,7 @@ program
|
|
|
661
675
|
"Allow proxy to reach private/loopback addresses",
|
|
662
676
|
false,
|
|
663
677
|
)
|
|
678
|
+
.optionsGroup("TLS / HTTPS Options:")
|
|
664
679
|
.option("--https", "Enable HTTPS server", false)
|
|
665
680
|
.option("--cert <path>", "Path to existing TLS certificate file")
|
|
666
681
|
.option("--key <path>", "Path to existing TLS private key file")
|
|
@@ -668,184 +683,75 @@ program
|
|
|
668
683
|
"--ssl-dir <path>",
|
|
669
684
|
"Directory for TLS certificate generation/storage",
|
|
670
685
|
)
|
|
671
|
-
.
|
|
672
|
-
.
|
|
673
|
-
|
|
674
|
-
// ---------------------------------------------------------------------------
|
|
675
|
-
// INIT COMMAND
|
|
676
|
-
// ---------------------------------------------------------------------------
|
|
677
|
-
program
|
|
678
|
-
.command("init [dir]")
|
|
679
|
-
.description(
|
|
680
|
-
"Initialize a new ShadowClaw content template in the specified directory",
|
|
681
|
-
)
|
|
682
|
-
.action(async (dirArg) => {
|
|
683
|
-
try {
|
|
684
|
-
const targetDir = path.resolve(dirArg || process.cwd());
|
|
685
|
-
await mkdir(path.join(targetDir, "pages/main"), { recursive: true });
|
|
686
|
-
|
|
687
|
-
const configPath = path.join(targetDir, "shadow-claw-config.json");
|
|
688
|
-
const legacyConfigPath1 = path.join(targetDir, "shadow-claw.config.json");
|
|
689
|
-
const legacyConfigPath2 = path.join(targetDir, "site-config.json");
|
|
690
|
-
if (
|
|
691
|
-
!(await pathExists(configPath)) &&
|
|
692
|
-
!(await pathExists(legacyConfigPath1)) &&
|
|
693
|
-
!(await pathExists(legacyConfigPath2))
|
|
694
|
-
) {
|
|
695
|
-
const defaultSiteConfig = {
|
|
696
|
-
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
697
|
-
site: {
|
|
698
|
-
title: "My ShadowClaw Site",
|
|
699
|
-
description:
|
|
700
|
-
"Personal AI assistant and knowledge hub powered by ShadowClaw.",
|
|
701
|
-
},
|
|
702
|
-
branding: {
|
|
703
|
-
titleText: "My ShadowClaw Site",
|
|
704
|
-
},
|
|
705
|
-
pages: {
|
|
706
|
-
sortOrder: "asc",
|
|
707
|
-
defaultPinnedPage: "/pages/main/index.html",
|
|
708
|
-
},
|
|
709
|
-
};
|
|
710
|
-
await writeFile(
|
|
711
|
-
configPath,
|
|
712
|
-
JSON.stringify(defaultSiteConfig, null, 2) + "\n",
|
|
713
|
-
"utf8",
|
|
714
|
-
);
|
|
715
|
-
console.log(`Created ${configPath}`);
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
const indexPath = path.join(targetDir, "pages/main/index.html");
|
|
719
|
-
if (!(await pathExists(indexPath))) {
|
|
720
|
-
const defaultIndexHtml = `---
|
|
721
|
-
title: "Welcome to ShadowClaw"
|
|
722
|
-
created: "${new Date().toISOString()}"
|
|
723
|
-
updated: "${new Date().toISOString()}"
|
|
724
|
-
slug: "home"
|
|
725
|
-
---
|
|
726
|
-
|
|
727
|
-
<article>
|
|
728
|
-
<h1>Welcome to ShadowClaw</h1>
|
|
729
|
-
<p>Your browser-native personal AI assistant and static site publisher.</p>
|
|
730
|
-
</article>
|
|
731
|
-
`;
|
|
732
|
-
await writeFile(indexPath, defaultIndexHtml, "utf8");
|
|
733
|
-
console.log(`Created ${indexPath}`);
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
const gitignorePath = path.join(targetDir, ".gitignore");
|
|
737
|
-
if (!(await pathExists(gitignorePath))) {
|
|
738
|
-
await writeFile(
|
|
739
|
-
gitignorePath,
|
|
740
|
-
"dist/\n.cache/\nnode_modules/\n",
|
|
741
|
-
"utf8",
|
|
742
|
-
);
|
|
743
|
-
console.log(`Created ${gitignorePath}`);
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
console.log(
|
|
747
|
-
`\nShadowClaw template successfully initialized in ${targetDir}`,
|
|
748
|
-
);
|
|
749
|
-
console.log(`To start developing, run:`);
|
|
750
|
-
console.log(` npx shadow-claw dev\n`);
|
|
751
|
-
} catch (err) {
|
|
752
|
-
console.error("Init failed:", err);
|
|
753
|
-
process.exit(1);
|
|
754
|
-
}
|
|
755
|
-
});
|
|
756
|
-
|
|
757
|
-
// ---------------------------------------------------------------------------
|
|
758
|
-
// PEER-ID / WEBRTC COMMAND
|
|
759
|
-
// ---------------------------------------------------------------------------
|
|
760
|
-
program
|
|
761
|
-
.command("peer-id [action] [customId]")
|
|
762
|
-
.alias("webrtc-peer-id")
|
|
763
|
-
.description(
|
|
764
|
-
"Get, generate, or renew the WebRTC CLI peer ID stored in .cache/cli-peer-id",
|
|
765
|
-
)
|
|
766
|
-
.option(
|
|
767
|
-
"-r, --renew",
|
|
768
|
-
"Force renewal / generation of a new WebRTC CLI peer ID",
|
|
769
|
-
)
|
|
770
|
-
.option("--set <id>", "Set a specific custom WebRTC CLI peer ID")
|
|
771
|
-
.option("--cache-dir <dir>", "Custom cache directory (defaults to .cache)")
|
|
772
|
-
.option("-q, --quiet", "Output only the peer ID string")
|
|
773
|
-
.option("--json", "Output peer ID and file path as JSON")
|
|
774
|
-
.action(async (action, customId, options) => {
|
|
775
|
-
const opts = { ...options };
|
|
776
|
-
if (customId && !opts.set) {
|
|
777
|
-
opts.set = customId;
|
|
778
|
-
}
|
|
779
|
-
await runPeerIdCommand(action, opts);
|
|
780
|
-
});
|
|
781
|
-
|
|
782
|
-
program
|
|
783
|
-
.command("webrtc [action] [customId]")
|
|
784
|
-
.description(
|
|
785
|
-
"Manage WebRTC CLI configuration and peer identity (.cache/cli-peer-id)\n\n" +
|
|
786
|
-
" Actions:\n" +
|
|
787
|
-
" (default) Show or generate the CLI peer ID\n" +
|
|
788
|
-
" listen Register as a live PeerJS peer — browser tabs can then\n" +
|
|
789
|
-
" connect directly without a control-plane connection",
|
|
790
|
-
)
|
|
686
|
+
.optionsGroup("Storage & Database Options:")
|
|
687
|
+
.option("--content-root <dir>", "Content root directory", process.cwd())
|
|
688
|
+
.option("--database-dir <dir>", "Directory where SQLite databases are stored")
|
|
791
689
|
.option(
|
|
792
|
-
"-
|
|
793
|
-
"
|
|
690
|
+
"--cache-dir <dir>",
|
|
691
|
+
"Custom cache directory for databases, tokens, and logs",
|
|
794
692
|
)
|
|
795
|
-
.option("--set <id>", "Set a specific custom WebRTC CLI peer ID")
|
|
796
|
-
.option("--cache-dir <dir>", "Custom cache directory (defaults to .cache)")
|
|
797
|
-
.option("-q, --quiet", "Output only the peer ID string")
|
|
798
|
-
.option("--json", "Output peer ID and file path as JSON")
|
|
799
|
-
// listen-specific options
|
|
800
|
-
.option("--host <host>", "PeerJS signaling server host (for listen)")
|
|
801
|
-
.option("--port <port>", "PeerJS signaling server port (for listen)", "8888")
|
|
802
|
-
.option("--path <path>", "PeerJS signaling server path (for listen)", "/")
|
|
803
693
|
.option(
|
|
804
|
-
"--
|
|
805
|
-
"
|
|
694
|
+
"--tmp, --temp",
|
|
695
|
+
"Store cache and databases in system temporary directory",
|
|
806
696
|
false,
|
|
807
697
|
)
|
|
808
698
|
.option(
|
|
809
|
-
"--
|
|
810
|
-
"
|
|
699
|
+
"-y, --yes",
|
|
700
|
+
"Skip interactive cache directory prompt and use default .cache",
|
|
811
701
|
false,
|
|
812
702
|
)
|
|
813
|
-
.
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
703
|
+
.action(handleServer);
|
|
704
|
+
|
|
705
|
+
// ---------------------------------------------------------------------------
|
|
706
|
+
// MCP COMMAND
|
|
707
|
+
// ---------------------------------------------------------------------------
|
|
708
|
+
program
|
|
709
|
+
.command("mcp")
|
|
710
|
+
.description(
|
|
711
|
+
"Run the official Stateless Model Context Protocol (MCP 2026-07-28) server",
|
|
818
712
|
)
|
|
819
|
-
.
|
|
820
|
-
.option("--
|
|
713
|
+
.optionsGroup("MCP Protocol Options:")
|
|
714
|
+
.option("--mcp-transport <transport>", "MCP transport: stdio | http", "stdio")
|
|
821
715
|
.option(
|
|
822
|
-
"-
|
|
823
|
-
"
|
|
716
|
+
"--relay-client-tools",
|
|
717
|
+
"Discover and relay tools from connected browser clients",
|
|
824
718
|
true,
|
|
825
719
|
)
|
|
826
|
-
.
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
720
|
+
.option("--no-relay-client-tools", "Disable relaying browser client tools")
|
|
721
|
+
.optionsGroup("Target Client Options:")
|
|
722
|
+
.option("--client <id>", "Target client ID (defaults to first active client)")
|
|
723
|
+
.optionsGroup("Control Plane Connection Options:")
|
|
724
|
+
.option("--host <host>", "Control plane host")
|
|
725
|
+
.option("--port <port>", "Control plane port or HTTP MCP port")
|
|
726
|
+
.option("--token <token>", "Control token")
|
|
727
|
+
.option("--https", "Connect to server via HTTPS", false)
|
|
728
|
+
.option("-k, --insecure", "Allow self-signed TLS certificates", true)
|
|
729
|
+
.optionsGroup("Transport & Peer Options:")
|
|
730
|
+
.option(
|
|
731
|
+
"--transport <transport>",
|
|
732
|
+
"Control plane client transport: http | webrtc",
|
|
733
|
+
"http",
|
|
734
|
+
)
|
|
735
|
+
.option("--peer-id <id>", "Custom WebRTC CLI peer ID")
|
|
736
|
+
.action(async (options) => {
|
|
737
|
+
await runMcpCommand(options);
|
|
836
738
|
});
|
|
837
739
|
|
|
838
740
|
// ---------------------------------------------------------------------------
|
|
839
|
-
//
|
|
741
|
+
// CONTROL PLANE & CLIENT BRIDGE COMMANDS
|
|
840
742
|
// ---------------------------------------------------------------------------
|
|
743
|
+
program.commandsGroup("Control Plane & Client Bridge:");
|
|
744
|
+
|
|
841
745
|
program
|
|
842
746
|
.command("clients")
|
|
843
747
|
.description("List connected / registered browser and Electron clients")
|
|
748
|
+
.optionsGroup("Control Plane Connection Options:")
|
|
844
749
|
.option("--host <host>", "Control plane host")
|
|
845
750
|
.option("--port <port>", "Control plane port")
|
|
846
751
|
.option("--token <token>", "Control token")
|
|
847
752
|
.option("--https", "Connect to server via HTTPS", false)
|
|
848
753
|
.option("-k, --insecure", "Allow self-signed TLS certificates", true)
|
|
754
|
+
.optionsGroup("Transport & Peer Options:")
|
|
849
755
|
.option("--transport <transport>", "Transport to use: http | webrtc", "http")
|
|
850
756
|
.option("--peer-id <id>", "Custom WebRTC CLI peer ID")
|
|
851
757
|
.option(
|
|
@@ -858,19 +764,19 @@ program
|
|
|
858
764
|
await runClientsCommand(options);
|
|
859
765
|
});
|
|
860
766
|
|
|
861
|
-
// ---------------------------------------------------------------------------
|
|
862
|
-
// SEND COMMAND
|
|
863
|
-
// ---------------------------------------------------------------------------
|
|
864
767
|
program
|
|
865
768
|
.command("send <message>")
|
|
866
769
|
.description("Send a message/prompt to a connected client")
|
|
770
|
+
.optionsGroup("Target Options:")
|
|
867
771
|
.option("--client <id>", "Target client ID (defaults to first available)")
|
|
868
772
|
.option("--group <groupId>", "Target conversation group ID")
|
|
773
|
+
.optionsGroup("Control Plane Connection Options:")
|
|
869
774
|
.option("--host <host>", "Control plane host")
|
|
870
775
|
.option("--port <port>", "Control plane port")
|
|
871
776
|
.option("--token <token>", "Control token")
|
|
872
777
|
.option("--https", "Connect to server via HTTPS", false)
|
|
873
778
|
.option("-k, --insecure", "Allow self-signed TLS certificates", true)
|
|
779
|
+
.optionsGroup("Transport & Peer Options:")
|
|
874
780
|
.option("--transport <transport>", "Transport to use: http | webrtc", "http")
|
|
875
781
|
.option("--peer-id <id>", "Custom WebRTC CLI peer ID")
|
|
876
782
|
.option("--renew-peer-id", "Renew WebRTC CLI peer ID before sending", false)
|
|
@@ -879,22 +785,19 @@ program
|
|
|
879
785
|
await runSendCommand(message, options);
|
|
880
786
|
});
|
|
881
787
|
|
|
882
|
-
// ---------------------------------------------------------------------------
|
|
883
|
-
// BACKUP COMMAND
|
|
884
|
-
// ---------------------------------------------------------------------------
|
|
885
788
|
program
|
|
886
|
-
.command("
|
|
887
|
-
.description(
|
|
888
|
-
|
|
889
|
-
)
|
|
890
|
-
.option("--
|
|
891
|
-
.
|
|
892
|
-
.option("--group <groupId>", "Specific workspace group ID")
|
|
789
|
+
.command("tasks")
|
|
790
|
+
.description("List scheduled tasks on a connected client")
|
|
791
|
+
.optionsGroup("Target Options:")
|
|
792
|
+
.option("--client <id>", "Target client ID")
|
|
793
|
+
.option("--group <groupId>", "Filter tasks by conversation group ID")
|
|
794
|
+
.optionsGroup("Control Plane Connection Options:")
|
|
893
795
|
.option("--host <host>", "Control plane host")
|
|
894
796
|
.option("--port <port>", "Control plane port")
|
|
895
797
|
.option("--token <token>", "Control token")
|
|
896
798
|
.option("--https", "Connect to server via HTTPS", false)
|
|
897
799
|
.option("-k, --insecure", "Allow self-signed TLS certificates", true)
|
|
800
|
+
.optionsGroup("Transport & Peer Options:")
|
|
898
801
|
.option("--transport <transport>", "Transport to use: http | webrtc", "http")
|
|
899
802
|
.option("--peer-id <id>", "Custom WebRTC CLI peer ID")
|
|
900
803
|
.option(
|
|
@@ -903,23 +806,26 @@ program
|
|
|
903
806
|
false,
|
|
904
807
|
)
|
|
905
808
|
.option("--cache-dir <dir>", "Custom cache directory")
|
|
906
|
-
.action(async (
|
|
907
|
-
await
|
|
809
|
+
.action(async (options) => {
|
|
810
|
+
await runTasksCommand(options);
|
|
908
811
|
});
|
|
909
812
|
|
|
910
|
-
// ---------------------------------------------------------------------------
|
|
911
|
-
// TASKS COMMAND
|
|
912
|
-
// ---------------------------------------------------------------------------
|
|
913
813
|
program
|
|
914
|
-
.command("
|
|
915
|
-
.description(
|
|
916
|
-
|
|
917
|
-
|
|
814
|
+
.command("backup [action]")
|
|
815
|
+
.description(
|
|
816
|
+
"Trigger or manage client workspace backups (trigger | list | delete)",
|
|
817
|
+
)
|
|
818
|
+
.optionsGroup("Target Options:")
|
|
819
|
+
.option("--client <id>", "Client ID")
|
|
820
|
+
.option("--backup-id <id>", "Backup ID (for delete)")
|
|
821
|
+
.option("--group <groupId>", "Specific workspace group ID")
|
|
822
|
+
.optionsGroup("Control Plane Connection Options:")
|
|
918
823
|
.option("--host <host>", "Control plane host")
|
|
919
824
|
.option("--port <port>", "Control plane port")
|
|
920
825
|
.option("--token <token>", "Control token")
|
|
921
826
|
.option("--https", "Connect to server via HTTPS", false)
|
|
922
827
|
.option("-k, --insecure", "Allow self-signed TLS certificates", true)
|
|
828
|
+
.optionsGroup("Transport & Peer Options:")
|
|
923
829
|
.option("--transport <transport>", "Transport to use: http | webrtc", "http")
|
|
924
830
|
.option("--peer-id <id>", "Custom WebRTC CLI peer ID")
|
|
925
831
|
.option(
|
|
@@ -928,50 +834,190 @@ program
|
|
|
928
834
|
false,
|
|
929
835
|
)
|
|
930
836
|
.option("--cache-dir <dir>", "Custom cache directory")
|
|
931
|
-
.action(async (options) => {
|
|
932
|
-
await
|
|
837
|
+
.action(async (action, options) => {
|
|
838
|
+
await runBackupCommand(action || "trigger", options);
|
|
933
839
|
});
|
|
934
840
|
|
|
935
841
|
// ---------------------------------------------------------------------------
|
|
936
|
-
//
|
|
842
|
+
// WEBRTC COMMANDS
|
|
937
843
|
// ---------------------------------------------------------------------------
|
|
844
|
+
program.commandsGroup("WebRTC:");
|
|
845
|
+
|
|
938
846
|
program
|
|
939
|
-
.command("
|
|
847
|
+
.command("webrtc [action] [customId]")
|
|
848
|
+
.summary(
|
|
849
|
+
"Manage WebRTC CLI configuration and peer identity (.cache/cli-peer-id)",
|
|
850
|
+
)
|
|
940
851
|
.description(
|
|
941
|
-
"
|
|
852
|
+
"Manage WebRTC CLI configuration and peer identity (.cache/cli-peer-id)\n\n" +
|
|
853
|
+
" Actions:\n" +
|
|
854
|
+
" (default) Show or generate the CLI peer ID\n" +
|
|
855
|
+
" listen Register as a live PeerJS peer — browser tabs can then\n" +
|
|
856
|
+
" connect directly without a control-plane connection",
|
|
942
857
|
)
|
|
943
|
-
.
|
|
944
|
-
.option("--client <id>", "Target client ID (defaults to first active client)")
|
|
945
|
-
.option("--host <host>", "Control plane host")
|
|
946
|
-
.option("--port <port>", "Control plane port or HTTP MCP port")
|
|
947
|
-
.option("--token <token>", "Control token")
|
|
948
|
-
.option("--https", "Connect to server via HTTPS", false)
|
|
949
|
-
.option("-k, --insecure", "Allow self-signed TLS certificates", true)
|
|
858
|
+
.optionsGroup("Identity Options:")
|
|
950
859
|
.option(
|
|
951
|
-
"--
|
|
952
|
-
"
|
|
953
|
-
"http",
|
|
860
|
+
"-r, --renew",
|
|
861
|
+
"Force renewal / generation of a new WebRTC CLI peer ID",
|
|
954
862
|
)
|
|
955
|
-
.option("--
|
|
863
|
+
.option("--set <id>", "Set a specific custom WebRTC CLI peer ID")
|
|
864
|
+
.option("--cache-dir <dir>", "Custom cache directory (defaults to .cache)")
|
|
865
|
+
.option("-q, --quiet", "Output only the peer ID string")
|
|
866
|
+
.option("--json", "Output peer ID and file path as JSON")
|
|
867
|
+
.optionsGroup("Signaling & Listener Options (for listen action):")
|
|
868
|
+
.option("--host <host>", "PeerJS signaling server host (for listen)")
|
|
869
|
+
.option("--port <port>", "PeerJS signaling server port (for listen)", "8888")
|
|
870
|
+
.option("--path <path>", "PeerJS signaling server path (for listen)", "/")
|
|
956
871
|
.option(
|
|
957
|
-
"--
|
|
958
|
-
"
|
|
872
|
+
"--secure",
|
|
873
|
+
"Use TLS (wss://) for the signaling server (for listen)",
|
|
874
|
+
false,
|
|
875
|
+
)
|
|
876
|
+
.option(
|
|
877
|
+
"--https",
|
|
878
|
+
"Alias for --secure: use TLS (wss://) for the signaling server",
|
|
879
|
+
false,
|
|
880
|
+
)
|
|
881
|
+
.option(
|
|
882
|
+
"--trusted-peer <id>",
|
|
883
|
+
"Accept connections only from this peer ID (repeatable, for listen)",
|
|
884
|
+
(v, prev) => (prev ? [...prev, v] : [v]),
|
|
885
|
+
[],
|
|
886
|
+
)
|
|
887
|
+
.option("--verbose", "Verbose connection logging (for listen)", false)
|
|
888
|
+
.option("--renew-peer-id", "Renew CLI peer ID before listening", false)
|
|
889
|
+
.option(
|
|
890
|
+
"-k, --insecure",
|
|
891
|
+
"Allow self-signed TLS certificates for the signaling server (wss://)",
|
|
959
892
|
true,
|
|
960
893
|
)
|
|
961
|
-
.
|
|
962
|
-
|
|
963
|
-
|
|
894
|
+
.action(async (action, customId, options) => {
|
|
895
|
+
if (action === "listen") {
|
|
896
|
+
await runWebRtcListenCommand(options);
|
|
897
|
+
return;
|
|
898
|
+
}
|
|
899
|
+
const opts = { ...options };
|
|
900
|
+
if (customId && !opts.set) {
|
|
901
|
+
opts.set = customId;
|
|
902
|
+
}
|
|
903
|
+
await runPeerIdCommand(action, opts);
|
|
904
|
+
});
|
|
905
|
+
|
|
906
|
+
program
|
|
907
|
+
.command("peer-id [action] [customId]")
|
|
908
|
+
.alias("webrtc-peer-id")
|
|
909
|
+
.description(
|
|
910
|
+
"Get, generate, or renew the WebRTC CLI peer ID stored in .cache/cli-peer-id",
|
|
911
|
+
)
|
|
912
|
+
.optionsGroup("Identity Options:")
|
|
913
|
+
.option(
|
|
914
|
+
"-r, --renew",
|
|
915
|
+
"Force renewal / generation of a new WebRTC CLI peer ID",
|
|
916
|
+
)
|
|
917
|
+
.option("--set <id>", "Set a specific custom WebRTC CLI peer ID")
|
|
918
|
+
.option("--cache-dir <dir>", "Custom cache directory (defaults to .cache)")
|
|
919
|
+
.option("-q, --quiet", "Output only the peer ID string")
|
|
920
|
+
.option("--json", "Output peer ID and file path as JSON")
|
|
921
|
+
.action(async (action, customId, options) => {
|
|
922
|
+
const opts = { ...options };
|
|
923
|
+
if (customId && !opts.set) {
|
|
924
|
+
opts.set = customId;
|
|
925
|
+
}
|
|
926
|
+
await runPeerIdCommand(action, opts);
|
|
964
927
|
});
|
|
965
928
|
|
|
966
929
|
// ---------------------------------------------------------------------------
|
|
967
|
-
//
|
|
930
|
+
// PROJECT & PROTOCOL COMMANDS
|
|
968
931
|
// ---------------------------------------------------------------------------
|
|
932
|
+
program.commandsGroup("Project:");
|
|
933
|
+
|
|
934
|
+
program
|
|
935
|
+
.command("init [dir]")
|
|
936
|
+
.description(
|
|
937
|
+
"Initialize a new ShadowClaw content template in the specified directory",
|
|
938
|
+
)
|
|
939
|
+
.action(async (dirArg) => {
|
|
940
|
+
try {
|
|
941
|
+
const targetDir = path.resolve(dirArg || process.cwd());
|
|
942
|
+
await mkdir(path.join(targetDir, "pages/main"), { recursive: true });
|
|
943
|
+
|
|
944
|
+
const configPath = path.join(targetDir, "shadow-claw-config.json");
|
|
945
|
+
const legacyConfigPath1 = path.join(targetDir, "shadow-claw.config.json");
|
|
946
|
+
const legacyConfigPath2 = path.join(targetDir, "site-config.json");
|
|
947
|
+
if (
|
|
948
|
+
!(await pathExists(configPath)) &&
|
|
949
|
+
!(await pathExists(legacyConfigPath1)) &&
|
|
950
|
+
!(await pathExists(legacyConfigPath2))
|
|
951
|
+
) {
|
|
952
|
+
const defaultSiteConfig = {
|
|
953
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
954
|
+
site: {
|
|
955
|
+
title: "My ShadowClaw Site",
|
|
956
|
+
description:
|
|
957
|
+
"Personal AI assistant and knowledge hub powered by ShadowClaw.",
|
|
958
|
+
},
|
|
959
|
+
branding: {
|
|
960
|
+
titleText: "My ShadowClaw Site",
|
|
961
|
+
},
|
|
962
|
+
pages: {
|
|
963
|
+
sortOrder: "asc",
|
|
964
|
+
defaultPinnedPage: "/pages/main/index.html",
|
|
965
|
+
},
|
|
966
|
+
};
|
|
967
|
+
await writeFile(
|
|
968
|
+
configPath,
|
|
969
|
+
JSON.stringify(defaultSiteConfig, null, 2) + "\n",
|
|
970
|
+
"utf8",
|
|
971
|
+
);
|
|
972
|
+
console.log(`Created ${configPath}`);
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
const indexPath = path.join(targetDir, "pages/main/index.html");
|
|
976
|
+
if (!(await pathExists(indexPath))) {
|
|
977
|
+
const defaultIndexHtml = `---
|
|
978
|
+
title: "Welcome to ShadowClaw"
|
|
979
|
+
created: "${new Date().toISOString()}"
|
|
980
|
+
updated: "${new Date().toISOString()}"
|
|
981
|
+
slug: "home"
|
|
982
|
+
---
|
|
983
|
+
|
|
984
|
+
<article>
|
|
985
|
+
<h1>Welcome to ShadowClaw</h1>
|
|
986
|
+
<p>Your browser-native personal AI assistant and static site publisher.</p>
|
|
987
|
+
</article>
|
|
988
|
+
`;
|
|
989
|
+
await writeFile(indexPath, defaultIndexHtml, "utf8");
|
|
990
|
+
console.log(`Created ${indexPath}`);
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
const gitignorePath = path.join(targetDir, ".gitignore");
|
|
994
|
+
if (!(await pathExists(gitignorePath))) {
|
|
995
|
+
await writeFile(
|
|
996
|
+
gitignorePath,
|
|
997
|
+
"dist/\n.cache/\nnode_modules/\n",
|
|
998
|
+
"utf8",
|
|
999
|
+
);
|
|
1000
|
+
console.log(`Created ${gitignorePath}`);
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
console.log(
|
|
1004
|
+
`\nShadowClaw template successfully initialized in ${targetDir}`,
|
|
1005
|
+
);
|
|
1006
|
+
console.log(`To start developing, run:`);
|
|
1007
|
+
console.log(` npx shadow-claw dev\n`);
|
|
1008
|
+
} catch (err) {
|
|
1009
|
+
console.error("Init failed:", err);
|
|
1010
|
+
process.exit(1);
|
|
1011
|
+
}
|
|
1012
|
+
});
|
|
1013
|
+
|
|
969
1014
|
program
|
|
970
1015
|
.command("skills:index [dir]")
|
|
971
1016
|
.alias("agent-skills")
|
|
972
1017
|
.description(
|
|
973
1018
|
"Generate or update .well-known/agent-skills/index.json per the Agent Skills Discovery RFC",
|
|
974
1019
|
)
|
|
1020
|
+
.optionsGroup("Output & Path Options:")
|
|
975
1021
|
.option(
|
|
976
1022
|
"--out-dir <dir>",
|
|
977
1023
|
"Output directory relative to content root (default: .well-known/agent-skills)",
|
|
@@ -985,6 +1031,7 @@ program
|
|
|
985
1031
|
"--config <file>",
|
|
986
1032
|
"Explicit path to shadow-claw.config.json or site-config.json",
|
|
987
1033
|
)
|
|
1034
|
+
.optionsGroup("Generation Options:")
|
|
988
1035
|
.option("--no-bundled", "Exclude bundled ShadowClaw skills from index")
|
|
989
1036
|
.option("--stdout", "Print generated index.json to stdout", false)
|
|
990
1037
|
.option("--no-write", "Skip writing file to disk")
|
|
@@ -997,4 +1044,10 @@ program
|
|
|
997
1044
|
}
|
|
998
1045
|
});
|
|
999
1046
|
|
|
1047
|
+
// ---------------------------------------------------------------------------
|
|
1048
|
+
// HELP & UTILITY COMMANDS
|
|
1049
|
+
// ---------------------------------------------------------------------------
|
|
1050
|
+
program.commandsGroup("Help & Utility:");
|
|
1051
|
+
program.helpCommand("help [command]", "display help for command");
|
|
1052
|
+
|
|
1000
1053
|
program.parse(process.argv);
|