jishushell 0.6.5 → 0.6.18
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/apps/anythingllm-container.yaml +15 -170
- package/apps/browserless-chromium-container.yaml +15 -10
- package/apps/filebrowser-container.yaml +14 -9
- package/apps/hermes-container.yaml +23 -2
- package/apps/jishu-kb-container.yaml +29 -161
- package/apps/ollama-binary.yaml +32 -28
- package/apps/ollama-cpu-container.yaml +5 -0
- package/apps/ollama-with-hollama-binary.yaml +33 -28
- package/apps/openclaw-binary.yaml +34 -10
- package/apps/openclaw-container.yaml +31 -7
- package/apps/openclaw-with-ollama-container.yaml +8 -2
- package/apps/openclaw-with-searxng-container.yaml +18 -6
- package/apps/searxng-container.yaml +11 -6
- package/apps/weknora-container.yaml +21 -21
- package/dependencies/jishushell-panel-0.6.18.tgz +0 -0
- package/dist/cli/app.js +244 -213
- package/dist/cli/app.js.map +1 -1
- package/dist/cli/backup.js +15 -12
- package/dist/cli/backup.js.map +1 -1
- package/dist/cli/core.d.ts +4 -3
- package/dist/cli/core.js +392 -227
- package/dist/cli/core.js.map +1 -1
- package/dist/cli/doctor.d.ts +1 -1
- package/dist/cli/doctor.js +17 -10
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/job.js +62 -14
- package/dist/cli/job.js.map +1 -1
- package/dist/cli/llm.js +80 -11
- package/dist/cli/llm.js.map +1 -1
- package/dist/cli/managed-list.d.ts +1 -3
- package/dist/cli/managed-list.js +18 -16
- package/dist/cli/managed-list.js.map +1 -1
- package/dist/cli/migrate.d.ts +2 -0
- package/dist/cli/migrate.js +160 -0
- package/dist/cli/migrate.js.map +1 -0
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +23 -19
- package/dist/config.js +60 -49
- package/dist/config.js.map +1 -1
- package/dist/control.d.ts +6 -6
- package/dist/control.js +31 -23
- package/dist/control.js.map +1 -1
- package/dist/core.d.ts +5 -5
- package/dist/core.js +5 -5
- package/dist/core.js.map +1 -1
- package/dist/install.d.ts +2 -2
- package/dist/install.js +18 -18
- package/dist/install.js.map +1 -1
- package/dist/routes/apps.d.ts +1 -1
- package/dist/routes/apps.js +101 -193
- package/dist/routes/apps.js.map +1 -1
- package/dist/routes/auth.js +1 -1
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/backup.js +1 -1
- package/dist/routes/backup.js.map +1 -1
- package/dist/routes/external-mounts.d.ts +1 -1
- package/dist/routes/external-mounts.js +1 -1
- package/dist/routes/external-mounts.js.map +1 -1
- package/dist/routes/file-mounts.d.ts +4 -3
- package/dist/routes/file-mounts.js +51 -30
- package/dist/routes/file-mounts.js.map +1 -1
- package/dist/routes/files-organize.d.ts +2 -2
- package/dist/routes/files-organize.js +5 -5
- package/dist/routes/files-organize.js.map +1 -1
- package/dist/routes/files.d.ts +1 -1
- package/dist/routes/files.js +1 -1
- package/dist/routes/files.js.map +1 -1
- package/dist/routes/instances.d.ts +10 -4
- package/dist/routes/instances.js +323 -541
- package/dist/routes/instances.js.map +1 -1
- package/dist/routes/integration-apps.d.ts +14 -0
- package/dist/routes/integration-apps.js +81 -0
- package/dist/routes/integration-apps.js.map +1 -0
- package/dist/routes/integrations.d.ts +9 -0
- package/dist/routes/integrations.js +12 -0
- package/dist/routes/integrations.js.map +1 -0
- package/dist/routes/llm-proxy.js +26 -3
- package/dist/routes/llm-proxy.js.map +1 -1
- package/dist/routes/setup.js +53 -38
- package/dist/routes/setup.js.map +1 -1
- package/dist/routes/system.js +108 -68
- package/dist/routes/system.js.map +1 -1
- package/dist/routes/webdav.d.ts +1 -1
- package/dist/routes/webdav.js +2 -2
- package/dist/routes/webdav.js.map +1 -1
- package/dist/server.js +315 -213
- package/dist/server.js.map +1 -1
- package/dist/services/app-common/app-compiler.js +186 -0
- package/dist/services/app-common/app-compiler.js.map +1 -0
- package/dist/services/app-common/app-shared.d.ts +15 -0
- package/dist/services/app-common/app-shared.js +64 -0
- package/dist/services/app-common/app-shared.js.map +1 -0
- package/dist/services/app-common/capability-service.d.ts +45 -0
- package/dist/services/app-common/capability-service.js +331 -0
- package/dist/services/app-common/capability-service.js.map +1 -0
- package/dist/services/app-common/catalog-service.d.ts +59 -0
- package/dist/services/app-common/catalog-service.js +308 -0
- package/dist/services/app-common/catalog-service.js.map +1 -0
- package/dist/services/app-common/create-pipeline.d.ts +26 -0
- package/dist/services/app-common/create-pipeline.js +298 -0
- package/dist/services/app-common/create-pipeline.js.map +1 -0
- package/dist/services/app-common/delete-service.d.ts +5 -0
- package/dist/services/app-common/delete-service.js +104 -0
- package/dist/services/app-common/delete-service.js.map +1 -0
- package/dist/services/app-common/execution-owner.d.ts +23 -0
- package/dist/services/app-common/execution-owner.js +124 -0
- package/dist/services/app-common/execution-owner.js.map +1 -0
- package/dist/services/app-common/execution-service.d.ts +23 -0
- package/dist/services/app-common/execution-service.js +105 -0
- package/dist/services/app-common/execution-service.js.map +1 -0
- package/dist/services/app-common/id-normalizer.d.ts +31 -0
- package/dist/services/app-common/id-normalizer.js +83 -0
- package/dist/services/app-common/id-normalizer.js.map +1 -0
- package/dist/services/app-common/install-store.d.ts +34 -0
- package/dist/services/app-common/install-store.js +261 -0
- package/dist/services/app-common/install-store.js.map +1 -0
- package/dist/services/app-common/instance-store.d.ts +78 -0
- package/dist/services/app-common/instance-store.js +495 -0
- package/dist/services/app-common/instance-store.js.map +1 -0
- package/dist/services/app-common/integration-refs.d.ts +17 -0
- package/dist/services/app-common/integration-refs.js +47 -0
- package/dist/services/app-common/integration-refs.js.map +1 -0
- package/dist/services/app-common/lifecycle-pipeline.d.ts +62 -0
- package/dist/services/app-common/lifecycle-pipeline.js +317 -0
- package/dist/services/app-common/lifecycle-pipeline.js.map +1 -0
- package/dist/services/app-common/lifecycle-scripts.d.ts +38 -0
- package/dist/services/app-common/lifecycle-scripts.js +935 -0
- package/dist/services/app-common/lifecycle-scripts.js.map +1 -0
- package/dist/services/app-common/lifecycle-service.d.ts +68 -0
- package/dist/services/app-common/lifecycle-service.js +467 -0
- package/dist/services/app-common/lifecycle-service.js.map +1 -0
- package/dist/services/app-common/paths.d.ts +29 -0
- package/dist/services/app-common/paths.js +34 -0
- package/dist/services/app-common/paths.js.map +1 -0
- package/dist/services/app-common/platform-transform.d.ts +32 -0
- package/dist/services/app-common/platform-transform.js +65 -0
- package/dist/services/app-common/platform-transform.js.map +1 -0
- package/dist/services/app-common/provide-resolver.d.ts +29 -0
- package/dist/services/app-common/provide-resolver.js +129 -0
- package/dist/services/app-common/provide-resolver.js.map +1 -0
- package/dist/services/app-common/remote-spec.d.ts +14 -0
- package/dist/services/app-common/remote-spec.js +58 -0
- package/dist/services/app-common/remote-spec.js.map +1 -0
- package/dist/services/app-common/runtime-builder.d.ts +1 -0
- package/dist/services/app-common/runtime-builder.js +2 -0
- package/dist/services/app-common/runtime-builder.js.map +1 -0
- package/dist/services/app-common/runtime-facts.d.ts +19 -0
- package/dist/services/app-common/runtime-facts.js +126 -0
- package/dist/services/app-common/runtime-facts.js.map +1 -0
- package/dist/services/app-common/service.d.ts +9 -0
- package/dist/services/app-common/service.js +10 -0
- package/dist/services/app-common/service.js.map +1 -0
- package/dist/services/app-common/spec-materializer.d.ts +9 -0
- package/dist/services/app-common/spec-materializer.js +361 -0
- package/dist/services/app-common/spec-materializer.js.map +1 -0
- package/dist/services/app-common/status-refresh.d.ts +33 -0
- package/dist/services/app-common/status-refresh.js +759 -0
- package/dist/services/app-common/status-refresh.js.map +1 -0
- package/dist/services/app-common/task-service.d.ts +29 -0
- package/dist/services/app-common/task-service.js +93 -0
- package/dist/services/app-common/task-service.js.map +1 -0
- package/dist/services/app-common/terminal-session-manager.js +157 -0
- package/dist/services/app-common/terminal-session-manager.js.map +1 -0
- package/dist/services/app-modules/browserless/routes.d.ts +9 -0
- package/dist/services/app-modules/browserless/routes.js +517 -0
- package/dist/services/app-modules/browserless/routes.js.map +1 -0
- package/dist/services/app-modules/routes.d.ts +2 -0
- package/dist/services/app-modules/routes.js +5 -0
- package/dist/services/app-modules/routes.js.map +1 -0
- package/dist/services/backup/backup-admin.d.ts +95 -0
- package/dist/services/backup/backup-admin.js +246 -0
- package/dist/services/backup/backup-admin.js.map +1 -0
- package/dist/services/backup/backup-manager.d.ts +264 -0
- package/dist/services/backup/backup-manager.js +2318 -0
- package/dist/services/backup/backup-manager.js.map +1 -0
- package/dist/services/backup/backup-verify.js +240 -0
- package/dist/services/backup/backup-verify.js.map +1 -0
- package/dist/services/capabilities/browser-policy.d.ts +14 -0
- package/dist/services/capabilities/browser-policy.js +141 -0
- package/dist/services/capabilities/browser-policy.js.map +1 -0
- package/dist/services/capabilities/contract.d.ts +50 -0
- package/dist/services/capabilities/contract.js +129 -0
- package/dist/services/capabilities/contract.js.map +1 -0
- package/dist/services/capabilities/endpoint-validator.d.ts +42 -0
- package/dist/services/capabilities/endpoint-validator.js +114 -0
- package/dist/services/capabilities/endpoint-validator.js.map +1 -0
- package/dist/services/capabilities/health.d.ts +16 -0
- package/dist/services/capabilities/health.js +121 -0
- package/dist/services/capabilities/health.js.map +1 -0
- package/dist/services/capabilities/registry.d.ts +56 -0
- package/dist/services/capabilities/registry.js +222 -0
- package/dist/services/capabilities/registry.js.map +1 -0
- package/dist/services/capabilities/sync.d.ts +7 -0
- package/dist/services/capabilities/sync.js +223 -0
- package/dist/services/capabilities/sync.js.map +1 -0
- package/dist/services/capability-proxy/html-rewriters/browserless.d.ts +1 -0
- package/dist/services/capability-proxy/html-rewriters/browserless.js +83 -0
- package/dist/services/capability-proxy/html-rewriters/browserless.js.map +1 -0
- package/dist/services/capability-proxy/html-rewriters/index.d.ts +12 -0
- package/dist/services/capability-proxy/html-rewriters/index.js +25 -0
- package/dist/services/capability-proxy/html-rewriters/index.js.map +1 -0
- package/dist/services/capability-proxy/html-rewriters/jishukb.d.ts +1 -0
- package/dist/services/capability-proxy/html-rewriters/jishukb.js +161 -0
- package/dist/services/capability-proxy/html-rewriters/jishukb.js.map +1 -0
- package/dist/services/connections/admin.d.ts +80 -0
- package/dist/services/connections/admin.js +327 -0
- package/dist/services/connections/admin.js.map +1 -0
- package/dist/services/connections/apply.d.ts +110 -0
- package/dist/services/connections/apply.js +444 -0
- package/dist/services/connections/apply.js.map +1 -0
- package/dist/services/connections/resolver.d.ts +82 -0
- package/dist/services/connections/resolver.js +289 -0
- package/dist/services/connections/resolver.js.map +1 -0
- package/dist/services/connections/suggestions.d.ts +27 -0
- package/dist/services/connections/suggestions.js +124 -0
- package/dist/services/connections/suggestions.js.map +1 -0
- package/dist/services/connections/transactor.d.ts +39 -0
- package/dist/services/connections/transactor.js +307 -0
- package/dist/services/connections/transactor.js.map +1 -0
- package/dist/services/files/external-mounts.js +187 -0
- package/dist/services/files/external-mounts.js.map +1 -0
- package/dist/services/files/files-manager.d.ts +265 -0
- package/dist/services/files/files-manager.js +1189 -0
- package/dist/services/files/files-manager.js.map +1 -0
- package/dist/services/files/files-mounts.d.ts +42 -0
- package/dist/services/files/files-mounts.js +207 -0
- package/dist/services/files/files-mounts.js.map +1 -0
- package/dist/services/files/organize/applier.js +218 -0
- package/dist/services/files/organize/applier.js.map +1 -0
- package/dist/services/files/organize/rules.js +286 -0
- package/dist/services/files/organize/rules.js.map +1 -0
- package/dist/services/files/organize/scanner.js +366 -0
- package/dist/services/files/organize/scanner.js.map +1 -0
- package/dist/services/files/organize/store.js +82 -0
- package/dist/services/files/organize/store.js.map +1 -0
- package/dist/services/files/webdav/server.d.ts +47 -0
- package/dist/services/files/webdav/server.js +329 -0
- package/dist/services/files/webdav/server.js.map +1 -0
- package/dist/services/files/webdav/xml-builder.js.map +1 -0
- package/dist/services/instances/admin.d.ts +23 -0
- package/dist/services/instances/admin.js +218 -0
- package/dist/services/instances/admin.js.map +1 -0
- package/dist/services/instances/clone.d.ts +26 -0
- package/dist/services/instances/clone.js +78 -0
- package/dist/services/instances/clone.js.map +1 -0
- package/dist/services/instances/config-admin.d.ts +17 -0
- package/dist/services/instances/config-admin.js +181 -0
- package/dist/services/instances/config-admin.js.map +1 -0
- package/dist/services/instances/manager.d.ts +231 -0
- package/dist/services/instances/manager.js +1348 -0
- package/dist/services/instances/manager.js.map +1 -0
- package/dist/services/instances/passwords.js +173 -0
- package/dist/services/instances/passwords.js.map +1 -0
- package/dist/services/instances/types.d.ts +21 -0
- package/dist/services/instances/types.js +2 -0
- package/dist/services/instances/types.js.map +1 -0
- package/dist/services/integrations/anythingllm/integration.d.ts +25 -0
- package/dist/services/integrations/anythingllm/integration.js +251 -0
- package/dist/services/integrations/anythingllm/integration.js.map +1 -0
- package/dist/services/integrations/catalog.d.ts +3 -0
- package/dist/services/integrations/catalog.js +73 -0
- package/dist/services/integrations/catalog.js.map +1 -0
- package/dist/services/integrations/custom/integration.d.ts +28 -0
- package/dist/services/integrations/custom/integration.js +179 -0
- package/dist/services/integrations/custom/integration.js.map +1 -0
- package/dist/services/integrations/hermes/integration.d.ts +194 -0
- package/dist/services/integrations/hermes/integration.js +1669 -0
- package/dist/services/integrations/hermes/integration.js.map +1 -0
- package/dist/services/integrations/index.d.ts +40 -0
- package/dist/services/integrations/index.js +59 -0
- package/dist/services/integrations/index.js.map +1 -0
- package/dist/services/integrations/installable/catalog.d.ts +33 -0
- package/dist/services/integrations/installable/catalog.js +88 -0
- package/dist/services/integrations/installable/catalog.js.map +1 -0
- package/dist/services/integrations/installable/index.d.ts +35 -0
- package/dist/services/integrations/installable/index.js +170 -0
- package/dist/services/integrations/installable/index.js.map +1 -0
- package/dist/services/integrations/installable/installers/integration-probes.d.ts +50 -0
- package/dist/services/integrations/installable/installers/integration-probes.js +231 -0
- package/dist/services/integrations/installable/installers/integration-probes.js.map +1 -0
- package/dist/services/integrations/installable/installers/integration.d.ts +30 -0
- package/dist/services/integrations/installable/installers/integration.js +177 -0
- package/dist/services/integrations/installable/installers/integration.js.map +1 -0
- package/dist/services/integrations/installable/installers/registry-probe.js.map +1 -0
- package/dist/services/integrations/installable/installers/shell-script.d.ts +46 -0
- package/dist/services/integrations/installable/installers/shell-script.js +487 -0
- package/dist/services/integrations/installable/installers/shell-script.js.map +1 -0
- package/dist/services/integrations/installable/types.d.ts +130 -0
- package/dist/services/integrations/installable/types.js +19 -0
- package/dist/services/integrations/installable/types.js.map +1 -0
- package/dist/services/integrations/jishukb/integration.d.ts +22 -0
- package/dist/services/integrations/jishukb/integration.js +189 -0
- package/dist/services/integrations/jishukb/integration.js.map +1 -0
- package/dist/services/integrations/openclaw/anythingllm-shim.d.ts +46 -0
- package/dist/services/integrations/openclaw/anythingllm-shim.js +281 -0
- package/dist/services/integrations/openclaw/anythingllm-shim.js.map +1 -0
- package/dist/services/integrations/openclaw/drive-shim.js +490 -0
- package/dist/services/integrations/openclaw/drive-shim.js.map +1 -0
- package/dist/services/integrations/openclaw/integration.d.ts +424 -0
- package/dist/services/integrations/openclaw/integration.js +4402 -0
- package/dist/services/integrations/openclaw/integration.js.map +1 -0
- package/dist/services/integrations/openclaw/jishukb-shim.d.ts +48 -0
- package/dist/services/integrations/openclaw/jishukb-shim.js +750 -0
- package/dist/services/integrations/openclaw/jishukb-shim.js.map +1 -0
- package/dist/services/integrations/openclaw/mcporter-lite.js +276 -0
- package/dist/services/integrations/openclaw/mcporter-lite.js.map +1 -0
- package/dist/services/integrations/openclaw/mcporter.d.ts +46 -0
- package/dist/services/integrations/openclaw/mcporter.js +112 -0
- package/dist/services/integrations/openclaw/mcporter.js.map +1 -0
- package/dist/services/integrations/openclaw/routes.d.ts +21 -0
- package/dist/services/integrations/openclaw/routes.js +1191 -0
- package/dist/services/integrations/openclaw/routes.js.map +1 -0
- package/dist/services/integrations/registry.d.ts +17 -0
- package/dist/services/integrations/registry.js +36 -0
- package/dist/services/integrations/registry.js.map +1 -0
- package/dist/services/integrations/routes.d.ts +2 -0
- package/dist/services/integrations/routes.js +9 -0
- package/dist/services/integrations/routes.js.map +1 -0
- package/dist/services/integrations/types.d.ts +469 -0
- package/dist/services/integrations/types.js +2 -0
- package/dist/services/integrations/types.js.map +1 -0
- package/dist/services/legacy-migrator/classifier.d.ts +44 -0
- package/dist/services/legacy-migrator/classifier.js +309 -0
- package/dist/services/legacy-migrator/classifier.js.map +1 -0
- package/dist/services/legacy-migrator/executor.d.ts +42 -0
- package/dist/services/legacy-migrator/executor.js +637 -0
- package/dist/services/legacy-migrator/executor.js.map +1 -0
- package/dist/services/legacy-migrator/index.d.ts +31 -0
- package/dist/services/legacy-migrator/index.js +34 -0
- package/dist/services/legacy-migrator/index.js.map +1 -0
- package/dist/services/legacy-migrator/planner.d.ts +8 -0
- package/dist/services/legacy-migrator/planner.js +154 -0
- package/dist/services/legacy-migrator/planner.js.map +1 -0
- package/dist/services/legacy-migrator/provider-settings.d.ts +6 -0
- package/dist/services/legacy-migrator/provider-settings.js +72 -0
- package/dist/services/legacy-migrator/provider-settings.js.map +1 -0
- package/dist/services/legacy-migrator/report.d.ts +9 -0
- package/dist/services/legacy-migrator/report.js +99 -0
- package/dist/services/legacy-migrator/report.js.map +1 -0
- package/dist/services/legacy-migrator/scanner.d.ts +13 -0
- package/dist/services/legacy-migrator/scanner.js +157 -0
- package/dist/services/legacy-migrator/scanner.js.map +1 -0
- package/dist/services/legacy-migrator/types.d.ts +97 -0
- package/dist/services/legacy-migrator/types.js +23 -0
- package/dist/services/legacy-migrator/types.js.map +1 -0
- package/dist/services/llm-proxy/instance-proxy.d.ts +17 -1
- package/dist/services/llm-proxy/instance-proxy.js +171 -44
- package/dist/services/llm-proxy/instance-proxy.js.map +1 -1
- package/dist/services/llm-proxy/probe.js +5 -14
- package/dist/services/llm-proxy/probe.js.map +1 -1
- package/dist/services/llm-proxy/providers.js +23 -31
- package/dist/services/llm-proxy/providers.js.map +1 -1
- package/dist/services/llm-proxy/ssrf.d.ts +11 -4
- package/dist/services/llm-proxy/ssrf.js +45 -7
- package/dist/services/llm-proxy/ssrf.js.map +1 -1
- package/dist/services/llm-proxy/validate-key.js +16 -37
- package/dist/services/llm-proxy/validate-key.js.map +1 -1
- package/dist/services/repair/runtime-repair.d.ts +22 -0
- package/dist/services/repair/runtime-repair.js +307 -0
- package/dist/services/repair/runtime-repair.js.map +1 -0
- package/dist/services/runtime/driver-registry.d.ts +21 -0
- package/dist/services/runtime/driver-registry.js +22 -0
- package/dist/services/runtime/driver-registry.js.map +1 -0
- package/dist/services/runtime/drivers/nomad.d.ts +260 -0
- package/dist/services/runtime/drivers/nomad.js +3092 -0
- package/dist/services/runtime/drivers/nomad.js.map +1 -0
- package/dist/services/runtime/errors.d.ts +3 -3
- package/dist/services/runtime/errors.js +3 -3
- package/dist/services/runtime/instance.d.ts +14 -16
- package/dist/services/runtime/instance.js +93 -123
- package/dist/services/runtime/instance.js.map +1 -1
- package/dist/services/runtime/job-id.d.ts +1 -1
- package/dist/services/runtime/job-id.js +1 -1
- package/dist/services/runtime/mcp-shims/firewall.d.ts +2 -2
- package/dist/services/runtime/mcp-shims/firewall.js +2 -2
- package/dist/services/runtime/mcp-shims/searxng-shim.d.ts +3 -5
- package/dist/services/runtime/mcp-shims/searxng-shim.js +3 -5
- package/dist/services/runtime/mcp-shims/searxng-shim.js.map +1 -1
- package/dist/services/runtime/mcp-shims/write-mcp-entry.d.ts +20 -20
- package/dist/services/runtime/mcp-shims/write-mcp-entry.js +16 -16
- package/dist/services/runtime/mcp-shims/write-mcp-entry.js.map +1 -1
- package/dist/services/runtime/ownership-marker.d.ts +83 -0
- package/dist/services/runtime/ownership-marker.js +109 -0
- package/dist/services/runtime/ownership-marker.js.map +1 -0
- package/dist/services/runtime/types.d.ts +22 -501
- package/dist/services/runtime/types.js +0 -12
- package/dist/services/runtime/types.js.map +1 -1
- package/dist/services/runtime/workload-compiler.d.ts +17 -0
- package/dist/services/runtime/workload-compiler.js +525 -0
- package/dist/services/runtime/workload-compiler.js.map +1 -0
- package/dist/services/runtime/workload-types.d.ts +11 -0
- package/dist/services/runtime/workload-types.js +2 -0
- package/dist/services/runtime/workload-types.js.map +1 -0
- package/dist/services/setup/core-manager.d.ts +50 -0
- package/dist/services/setup/core-manager.js +456 -0
- package/dist/services/setup/core-manager.js.map +1 -0
- package/dist/services/setup/plugin-installer.js +136 -0
- package/dist/services/setup/plugin-installer.js.map +1 -0
- package/dist/services/setup/setup-manager.d.ts +158 -0
- package/dist/services/setup/setup-manager.js +2768 -0
- package/dist/services/setup/setup-manager.js.map +1 -0
- package/dist/services/system/cli-command.d.ts +5 -0
- package/dist/services/system/cli-command.js +18 -0
- package/dist/services/system/cli-command.js.map +1 -0
- package/dist/services/system/macos-launchd.js +312 -0
- package/dist/services/system/macos-launchd.js.map +1 -0
- package/dist/services/system/repair-orchestrator.d.ts +71 -0
- package/dist/services/system/repair-orchestrator.js +412 -0
- package/dist/services/system/repair-orchestrator.js.map +1 -0
- package/dist/services/system/system-monitor.js +96 -0
- package/dist/services/system/system-monitor.js.map +1 -0
- package/dist/services/system/system-ollama-provider.d.ts +14 -0
- package/dist/services/system/system-ollama-provider.js +129 -0
- package/dist/services/system/system-ollama-provider.js.map +1 -0
- package/dist/services/system/system-reconciler.d.ts +59 -0
- package/dist/services/system/system-reconciler.js +710 -0
- package/dist/services/system/system-reconciler.js.map +1 -0
- package/dist/services/system/update-manager.d.ts +43 -0
- package/dist/services/system/update-manager.js +315 -0
- package/dist/services/system/update-manager.js.map +1 -0
- package/dist/services/system/upgrade-finalize.d.ts +80 -0
- package/dist/services/system/upgrade-finalize.js +507 -0
- package/dist/services/system/upgrade-finalize.js.map +1 -0
- package/dist/services/tasks/registry.d.ts +44 -0
- package/dist/services/tasks/registry.js +90 -0
- package/dist/services/tasks/registry.js.map +1 -0
- package/dist/services/telemetry/activation.d.ts +6 -2
- package/dist/services/telemetry/activation.js +6 -2
- package/dist/services/telemetry/activation.js.map +1 -1
- package/dist/services/telemetry/heartbeat.d.ts +6 -2
- package/dist/services/telemetry/heartbeat.js +6 -2
- package/dist/services/telemetry/heartbeat.js.map +1 -1
- package/dist/services/workspaces/builder.d.ts +29 -0
- package/dist/services/workspaces/builder.js +186 -0
- package/dist/services/workspaces/builder.js.map +1 -0
- package/dist/types.d.ts +331 -45
- package/dist/utils/instance-lock.d.ts +2 -2
- package/dist/utils/instance-lock.js +2 -2
- package/install/jishu-install.sh +107 -26
- package/install/jishu-uninstall.sh +8 -0
- package/install/post-install.sh +162 -185
- package/install/post-uninstall.sh +6 -0
- package/node_modules/@fastify/static/.github/workflows/ci.yml +1 -1
- package/node_modules/@fastify/static/.github/workflows/lock-threads.yml +19 -0
- package/node_modules/@fastify/static/LICENSE +1 -3
- package/node_modules/@fastify/static/example/server-benchmark.js +39 -0
- package/node_modules/@fastify/static/index.js +169 -23
- package/node_modules/@fastify/static/lib/dirList.js +20 -6
- package/node_modules/@fastify/static/package.json +10 -8
- package/node_modules/@fastify/static/test/dir-list.test.js +82 -0
- package/node_modules/@fastify/static/test/static.test.js +326 -4
- package/node_modules/@fastify/static/types/index.d.ts +0 -4
- package/node_modules/@fastify/static/types/index.test-d.ts +1 -1
- package/node_modules/content-disposition/README.md +21 -22
- package/node_modules/content-disposition/index.js +122 -44
- package/node_modules/content-disposition/package.json +16 -20
- package/node_modules/glob/README.md +39 -130
- package/node_modules/glob/dist/commonjs/glob.d.ts +8 -0
- package/node_modules/glob/dist/commonjs/glob.d.ts.map +1 -1
- package/node_modules/glob/dist/commonjs/glob.js +2 -1
- package/node_modules/glob/dist/commonjs/glob.js.map +1 -1
- package/node_modules/glob/dist/commonjs/index.min.js +4 -0
- package/node_modules/glob/dist/commonjs/index.min.js.map +7 -0
- package/node_modules/glob/dist/commonjs/pattern.d.ts +3 -0
- package/node_modules/glob/dist/commonjs/pattern.d.ts.map +1 -1
- package/node_modules/glob/dist/commonjs/pattern.js +4 -0
- package/node_modules/glob/dist/commonjs/pattern.js.map +1 -1
- package/node_modules/glob/dist/esm/glob.d.ts +8 -0
- package/node_modules/glob/dist/esm/glob.d.ts.map +1 -1
- package/node_modules/glob/dist/esm/glob.js +2 -1
- package/node_modules/glob/dist/esm/glob.js.map +1 -1
- package/node_modules/glob/dist/esm/index.min.js +4 -0
- package/node_modules/glob/dist/esm/index.min.js.map +7 -0
- package/node_modules/glob/dist/esm/pattern.d.ts +3 -0
- package/node_modules/glob/dist/esm/pattern.d.ts.map +1 -1
- package/node_modules/glob/dist/esm/pattern.js +4 -0
- package/node_modules/glob/dist/esm/pattern.js.map +1 -1
- package/node_modules/glob/package.json +38 -37
- package/node_modules/jishushell-panel/README.md +4 -4
- package/node_modules/jishushell-panel/output/dist/server.js +17 -6
- package/node_modules/jishushell-panel/output/dist/server.js.map +1 -1
- package/node_modules/jishushell-panel/output/public/assets/ApiKeyField-NKcbHjNz.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/Dashboard-Da1fL38t.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/HermesChatPanel-DZvmYsoh.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/HermesConfigForm-BLUWlKwm.js +4 -0
- package/node_modules/jishushell-panel/output/public/assets/InitPassword-BAKsshzk.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/InstanceDetail-Dgyc_TX5.js +14 -0
- package/node_modules/jishushell-panel/output/public/assets/Login-DHeOmwI8.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/NewInstance-CIy0cYtp.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/ProviderRecommendations-H0ByEYF0.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/Settings-DAT-UMfP.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/Setup-g3uckFYR.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/WeixinLoginPanel-D-T6BxkQ.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/api-C70Gt678.js +4 -0
- package/node_modules/jishushell-panel/output/public/assets/index-DnnqTf7s.css +1 -0
- package/node_modules/jishushell-panel/output/public/assets/index-ERt6_ngA.js +23 -0
- package/node_modules/jishushell-panel/output/public/assets/registry-DF93EzIb.js +2 -0
- package/node_modules/jishushell-panel/output/public/assets/rolldown-runtime-QTnfLwEv.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/setup-task-q21GnI0E.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/usePolling-DeoThIQn.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/vendor-i18n-CS8DFbkQ.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/vendor-react-Cc84NArf.js +8 -0
- package/node_modules/jishushell-panel/output/public/index.html +6 -4
- package/node_modules/jishushell-panel/package.json +2 -2
- package/node_modules/semver/classes/range.js +11 -2
- package/node_modules/semver/package.json +2 -2
- package/package.json +12 -64
- package/scripts/check-app-path-boundaries.mjs +121 -0
- package/scripts/check-app-spec.mjs +127 -25
- package/scripts/check-colima-launchd.mjs +10 -8
- package/scripts/check-integration-isolation.ts +541 -0
- package/scripts/check-new-file-tests.mjs +11 -3
- package/scripts/check-open-core-boundaries.mjs +60 -10
- package/scripts/check-test-layering.sh +1 -1
- package/scripts/fixtures/instances/hermes-sample/instance.json +3 -2
- package/scripts/fixtures/instances/legacy-openclaw-sample/instance.json +1 -1
- package/scripts/local-web-upgrade-test.README +4 -3
- package/scripts/local-web-upgrade-test.example.env +2 -2
- package/scripts/local-web-upgrade-test.sh +14 -1
- package/scripts/pack-gui-and-send-pi.sh +41 -0
- package/scripts/perf/instances.js +1 -1
- package/scripts/prune-open-core-dist.mjs +89 -2
- package/scripts/smoke/hermes-bootstrap.sh +5 -5
- package/templates/hermes-entrypoint.sh +19 -29
- package/apps/openwebui-container.yaml +0 -97
- package/apps/playwright-container.yaml +0 -126
- package/dependencies/jishushell-panel-0.6.5.tgz +0 -0
- package/dist/crypto-shim.d.ts +0 -1
- package/dist/crypto-shim.js +0 -2
- package/dist/crypto-shim.js.map +0 -1
- package/dist/routes/agent-apps.d.ts +0 -14
- package/dist/routes/agent-apps.js +0 -77
- package/dist/routes/agent-apps.js.map +0 -1
- package/dist/routes/internal.d.ts +0 -2
- package/dist/routes/internal.js +0 -55
- package/dist/routes/internal.js.map +0 -1
- package/dist/routes/openclaw-routes.d.ts +0 -22
- package/dist/routes/openclaw-routes.js +0 -1020
- package/dist/routes/openclaw-routes.js.map +0 -1
- package/dist/routes/runtime.d.ts +0 -15
- package/dist/routes/runtime.js +0 -76
- package/dist/routes/runtime.js.map +0 -1
- package/dist/services/agent-apps/catalog.d.ts +0 -33
- package/dist/services/agent-apps/catalog.js +0 -88
- package/dist/services/agent-apps/catalog.js.map +0 -1
- package/dist/services/agent-apps/index.d.ts +0 -36
- package/dist/services/agent-apps/index.js +0 -171
- package/dist/services/agent-apps/index.js.map +0 -1
- package/dist/services/agent-apps/installers/adapter-probes.d.ts +0 -49
- package/dist/services/agent-apps/installers/adapter-probes.js +0 -230
- package/dist/services/agent-apps/installers/adapter-probes.js.map +0 -1
- package/dist/services/agent-apps/installers/adapter.d.ts +0 -30
- package/dist/services/agent-apps/installers/adapter.js +0 -171
- package/dist/services/agent-apps/installers/adapter.js.map +0 -1
- package/dist/services/agent-apps/installers/registry-probe.js.map +0 -1
- package/dist/services/agent-apps/installers/shell-script.d.ts +0 -47
- package/dist/services/agent-apps/installers/shell-script.js +0 -488
- package/dist/services/agent-apps/installers/shell-script.js.map +0 -1
- package/dist/services/agent-apps/types.d.ts +0 -128
- package/dist/services/agent-apps/types.js +0 -17
- package/dist/services/agent-apps/types.js.map +0 -1
- package/dist/services/app/app-compiler.js +0 -185
- package/dist/services/app/app-compiler.js.map +0 -1
- package/dist/services/app/app-manager.d.ts +0 -184
- package/dist/services/app/app-manager.js +0 -2933
- package/dist/services/app/app-manager.js.map +0 -1
- package/dist/services/app/custom-manager.d.ts +0 -27
- package/dist/services/app/custom-manager.js +0 -382
- package/dist/services/app/custom-manager.js.map +0 -1
- package/dist/services/app/hermes-agent-manager.d.ts +0 -20
- package/dist/services/app/hermes-agent-manager.js +0 -299
- package/dist/services/app/hermes-agent-manager.js.map +0 -1
- package/dist/services/app/id-normalizer.d.ts +0 -27
- package/dist/services/app/id-normalizer.js +0 -77
- package/dist/services/app/id-normalizer.js.map +0 -1
- package/dist/services/app/ollama-manager.d.ts +0 -18
- package/dist/services/app/ollama-manager.js +0 -224
- package/dist/services/app/ollama-manager.js.map +0 -1
- package/dist/services/app/openclaw-manager.d.ts +0 -63
- package/dist/services/app/openclaw-manager.js +0 -1215
- package/dist/services/app/openclaw-manager.js.map +0 -1
- package/dist/services/app/paths.d.ts +0 -27
- package/dist/services/app/paths.js +0 -40
- package/dist/services/app/paths.js.map +0 -1
- package/dist/services/app/platform-transform.d.ts +0 -32
- package/dist/services/app/platform-transform.js +0 -65
- package/dist/services/app/platform-transform.js.map +0 -1
- package/dist/services/app/provide-resolver.d.ts +0 -29
- package/dist/services/app/provide-resolver.js +0 -135
- package/dist/services/app/provide-resolver.js.map +0 -1
- package/dist/services/app/registry.d.ts +0 -17
- package/dist/services/app/registry.js +0 -31
- package/dist/services/app/registry.js.map +0 -1
- package/dist/services/app/remote-spec.d.ts +0 -14
- package/dist/services/app/remote-spec.js +0 -58
- package/dist/services/app/remote-spec.js.map +0 -1
- package/dist/services/app/terminal-session-manager.js +0 -157
- package/dist/services/app/terminal-session-manager.js.map +0 -1
- package/dist/services/app/types.d.ts +0 -74
- package/dist/services/app/types.js +0 -16
- package/dist/services/app/types.js.map +0 -1
- package/dist/services/app-config-admin.d.ts +0 -17
- package/dist/services/app-config-admin.js +0 -177
- package/dist/services/app-config-admin.js.map +0 -1
- package/dist/services/app-create-from-installed.d.ts +0 -23
- package/dist/services/app-create-from-installed.js +0 -75
- package/dist/services/app-create-from-installed.js.map +0 -1
- package/dist/services/app-passwords.js +0 -173
- package/dist/services/app-passwords.js.map +0 -1
- package/dist/services/backup-admin.d.ts +0 -101
- package/dist/services/backup-admin.js +0 -259
- package/dist/services/backup-admin.js.map +0 -1
- package/dist/services/backup-manager.d.ts +0 -264
- package/dist/services/backup-manager.js +0 -2263
- package/dist/services/backup-manager.js.map +0 -1
- package/dist/services/backup-verify.js +0 -240
- package/dist/services/backup-verify.js.map +0 -1
- package/dist/services/capability-endpoint-validator.d.ts +0 -41
- package/dist/services/capability-endpoint-validator.js +0 -114
- package/dist/services/capability-endpoint-validator.js.map +0 -1
- package/dist/services/capability-health.d.ts +0 -16
- package/dist/services/capability-health.js +0 -121
- package/dist/services/capability-health.js.map +0 -1
- package/dist/services/capability-registry.d.ts +0 -29
- package/dist/services/capability-registry.js +0 -176
- package/dist/services/capability-registry.js.map +0 -1
- package/dist/services/capability-sync.d.ts +0 -4
- package/dist/services/capability-sync.js +0 -220
- package/dist/services/capability-sync.js.map +0 -1
- package/dist/services/connection-admin.d.ts +0 -74
- package/dist/services/connection-admin.js +0 -287
- package/dist/services/connection-admin.js.map +0 -1
- package/dist/services/connection-apply.d.ts +0 -91
- package/dist/services/connection-apply.js +0 -471
- package/dist/services/connection-apply.js.map +0 -1
- package/dist/services/connection-resolver.d.ts +0 -65
- package/dist/services/connection-resolver.js +0 -281
- package/dist/services/connection-resolver.js.map +0 -1
- package/dist/services/connection-transactor.d.ts +0 -39
- package/dist/services/connection-transactor.js +0 -354
- package/dist/services/connection-transactor.js.map +0 -1
- package/dist/services/core-manager.d.ts +0 -50
- package/dist/services/core-manager.js +0 -411
- package/dist/services/core-manager.js.map +0 -1
- package/dist/services/external-mounts.js +0 -187
- package/dist/services/external-mounts.js.map +0 -1
- package/dist/services/files-manager.d.ts +0 -252
- package/dist/services/files-manager.js +0 -1156
- package/dist/services/files-manager.js.map +0 -1
- package/dist/services/files-mounts.d.ts +0 -42
- package/dist/services/files-mounts.js +0 -207
- package/dist/services/files-mounts.js.map +0 -1
- package/dist/services/instance-admin.d.ts +0 -26
- package/dist/services/instance-admin.js +0 -218
- package/dist/services/instance-admin.js.map +0 -1
- package/dist/services/instance-manager.d.ts +0 -192
- package/dist/services/instance-manager.js +0 -1289
- package/dist/services/instance-manager.js.map +0 -1
- package/dist/services/macos-launchd.js +0 -312
- package/dist/services/macos-launchd.js.map +0 -1
- package/dist/services/nomad-manager.d.ts +0 -307
- package/dist/services/nomad-manager.js +0 -3958
- package/dist/services/nomad-manager.js.map +0 -1
- package/dist/services/organize/applier.js +0 -218
- package/dist/services/organize/applier.js.map +0 -1
- package/dist/services/organize/rules.js +0 -286
- package/dist/services/organize/rules.js.map +0 -1
- package/dist/services/organize/scanner.js +0 -366
- package/dist/services/organize/scanner.js.map +0 -1
- package/dist/services/organize/store.js +0 -82
- package/dist/services/organize/store.js.map +0 -1
- package/dist/services/plugin-installer.js +0 -128
- package/dist/services/plugin-installer.js.map +0 -1
- package/dist/services/process-manager.d.ts +0 -25
- package/dist/services/process-manager.js +0 -568
- package/dist/services/process-manager.js.map +0 -1
- package/dist/services/runtime/adapters/custom.d.ts +0 -20
- package/dist/services/runtime/adapters/custom.js +0 -188
- package/dist/services/runtime/adapters/custom.js.map +0 -1
- package/dist/services/runtime/adapters/hermes.d.ts +0 -204
- package/dist/services/runtime/adapters/hermes.js +0 -1684
- package/dist/services/runtime/adapters/hermes.js.map +0 -1
- package/dist/services/runtime/adapters/openclaw-mcporter.d.ts +0 -45
- package/dist/services/runtime/adapters/openclaw-mcporter.js +0 -108
- package/dist/services/runtime/adapters/openclaw-mcporter.js.map +0 -1
- package/dist/services/runtime/adapters/openclaw.d.ts +0 -426
- package/dist/services/runtime/adapters/openclaw.js +0 -3975
- package/dist/services/runtime/adapters/openclaw.js.map +0 -1
- package/dist/services/runtime/index.d.ts +0 -34
- package/dist/services/runtime/index.js +0 -51
- package/dist/services/runtime/index.js.map +0 -1
- package/dist/services/runtime/mcp-shims/anythingllm-shim.d.ts +0 -46
- package/dist/services/runtime/mcp-shims/anythingllm-shim.js +0 -281
- package/dist/services/runtime/mcp-shims/anythingllm-shim.js.map +0 -1
- package/dist/services/runtime/mcp-shims/drive-shim.js +0 -490
- package/dist/services/runtime/mcp-shims/drive-shim.js.map +0 -1
- package/dist/services/runtime/mcp-shims/jishukb-shim.d.ts +0 -48
- package/dist/services/runtime/mcp-shims/jishukb-shim.js +0 -723
- package/dist/services/runtime/mcp-shims/jishukb-shim.js.map +0 -1
- package/dist/services/runtime/mcp-shims/mcporter-lite.js +0 -276
- package/dist/services/runtime/mcp-shims/mcporter-lite.js.map +0 -1
- package/dist/services/runtime/migrations.d.ts +0 -23
- package/dist/services/runtime/migrations.js +0 -125
- package/dist/services/runtime/migrations.js.map +0 -1
- package/dist/services/runtime/registry.d.ts +0 -13
- package/dist/services/runtime/registry.js +0 -32
- package/dist/services/runtime/registry.js.map +0 -1
- package/dist/services/runtime-identity.d.ts +0 -13
- package/dist/services/runtime-identity.js +0 -166
- package/dist/services/runtime-identity.js.map +0 -1
- package/dist/services/runtime-repair.d.ts +0 -52
- package/dist/services/runtime-repair.js +0 -352
- package/dist/services/runtime-repair.js.map +0 -1
- package/dist/services/setup-manager.d.ts +0 -158
- package/dist/services/setup-manager.js +0 -2740
- package/dist/services/setup-manager.js.map +0 -1
- package/dist/services/suggestions.d.ts +0 -27
- package/dist/services/suggestions.js +0 -133
- package/dist/services/suggestions.js.map +0 -1
- package/dist/services/system-monitor.js +0 -79
- package/dist/services/system-monitor.js.map +0 -1
- package/dist/services/system-ollama-provider.d.ts +0 -14
- package/dist/services/system-ollama-provider.js +0 -125
- package/dist/services/system-ollama-provider.js.map +0 -1
- package/dist/services/system-reconciler.d.ts +0 -72
- package/dist/services/system-reconciler.js +0 -600
- package/dist/services/system-reconciler.js.map +0 -1
- package/dist/services/task-registry.d.ts +0 -44
- package/dist/services/task-registry.js +0 -76
- package/dist/services/task-registry.js.map +0 -1
- package/dist/services/types-shim.d.ts +0 -16
- package/dist/services/types-shim.js +0 -2
- package/dist/services/types-shim.js.map +0 -1
- package/dist/services/update-manager.d.ts +0 -47
- package/dist/services/update-manager.js +0 -351
- package/dist/services/update-manager.js.map +0 -1
- package/dist/services/webdav/server.d.ts +0 -24
- package/dist/services/webdav/server.js +0 -420
- package/dist/services/webdav/server.js.map +0 -1
- package/dist/services/webdav/xml-builder.js.map +0 -1
- package/dist/services/workspace-builder.d.ts +0 -29
- package/dist/services/workspace-builder.js +0 -188
- package/dist/services/workspace-builder.js.map +0 -1
- package/node_modules/@fastify/static/.github/stale.yml +0 -21
- package/node_modules/@isaacs/cliui/LICENSE.md +0 -63
- package/node_modules/@isaacs/cliui/README.md +0 -151
- package/node_modules/@isaacs/cliui/dist/commonjs/ansi-regex/index.d.ts +0 -4
- package/node_modules/@isaacs/cliui/dist/commonjs/ansi-regex/index.d.ts.map +0 -1
- package/node_modules/@isaacs/cliui/dist/commonjs/ansi-regex/index.js +0 -16
- package/node_modules/@isaacs/cliui/dist/commonjs/ansi-regex/index.js.map +0 -1
- package/node_modules/@isaacs/cliui/dist/commonjs/ansi-styles/index.d.ts +0 -34
- package/node_modules/@isaacs/cliui/dist/commonjs/ansi-styles/index.d.ts.map +0 -1
- package/node_modules/@isaacs/cliui/dist/commonjs/ansi-styles/index.js +0 -170
- package/node_modules/@isaacs/cliui/dist/commonjs/ansi-styles/index.js.map +0 -1
- package/node_modules/@isaacs/cliui/dist/commonjs/eastasianwidth/index.d.ts +0 -6
- package/node_modules/@isaacs/cliui/dist/commonjs/eastasianwidth/index.d.ts.map +0 -1
- package/node_modules/@isaacs/cliui/dist/commonjs/eastasianwidth/index.js +0 -307
- package/node_modules/@isaacs/cliui/dist/commonjs/eastasianwidth/index.js.map +0 -1
- package/node_modules/@isaacs/cliui/dist/commonjs/emoji-regex/index.d.ts +0 -2
- package/node_modules/@isaacs/cliui/dist/commonjs/emoji-regex/index.d.ts.map +0 -1
- package/node_modules/@isaacs/cliui/dist/commonjs/emoji-regex/index.js +0 -7
- package/node_modules/@isaacs/cliui/dist/commonjs/emoji-regex/index.js.map +0 -1
- package/node_modules/@isaacs/cliui/dist/commonjs/index.d.ts +0 -41
- package/node_modules/@isaacs/cliui/dist/commonjs/index.d.ts.map +0 -1
- package/node_modules/@isaacs/cliui/dist/commonjs/index.js +0 -322
- package/node_modules/@isaacs/cliui/dist/commonjs/index.js.map +0 -1
- package/node_modules/@isaacs/cliui/dist/commonjs/index.min.js +0 -12
- package/node_modules/@isaacs/cliui/dist/commonjs/index.min.js.map +0 -7
- package/node_modules/@isaacs/cliui/dist/commonjs/package.json +0 -3
- package/node_modules/@isaacs/cliui/dist/commonjs/string-width/index.d.ts +0 -5
- package/node_modules/@isaacs/cliui/dist/commonjs/string-width/index.d.ts.map +0 -1
- package/node_modules/@isaacs/cliui/dist/commonjs/string-width/index.js +0 -49
- package/node_modules/@isaacs/cliui/dist/commonjs/string-width/index.js.map +0 -1
- package/node_modules/@isaacs/cliui/dist/commonjs/strip-ansi/index.d.ts +0 -2
- package/node_modules/@isaacs/cliui/dist/commonjs/strip-ansi/index.d.ts.map +0 -1
- package/node_modules/@isaacs/cliui/dist/commonjs/strip-ansi/index.js +0 -8
- package/node_modules/@isaacs/cliui/dist/commonjs/strip-ansi/index.js.map +0 -1
- package/node_modules/@isaacs/cliui/dist/commonjs/wrap-ansi/index.d.ts +0 -7
- package/node_modules/@isaacs/cliui/dist/commonjs/wrap-ansi/index.d.ts.map +0 -1
- package/node_modules/@isaacs/cliui/dist/commonjs/wrap-ansi/index.js +0 -176
- package/node_modules/@isaacs/cliui/dist/commonjs/wrap-ansi/index.js.map +0 -1
- package/node_modules/@isaacs/cliui/dist/esm/ansi-regex/index.d.ts +0 -4
- package/node_modules/@isaacs/cliui/dist/esm/ansi-regex/index.d.ts.map +0 -1
- package/node_modules/@isaacs/cliui/dist/esm/ansi-regex/index.js +0 -12
- package/node_modules/@isaacs/cliui/dist/esm/ansi-regex/index.js.map +0 -1
- package/node_modules/@isaacs/cliui/dist/esm/ansi-styles/index.d.ts +0 -34
- package/node_modules/@isaacs/cliui/dist/esm/ansi-styles/index.d.ts.map +0 -1
- package/node_modules/@isaacs/cliui/dist/esm/ansi-styles/index.js +0 -167
- package/node_modules/@isaacs/cliui/dist/esm/ansi-styles/index.js.map +0 -1
- package/node_modules/@isaacs/cliui/dist/esm/eastasianwidth/index.d.ts +0 -6
- package/node_modules/@isaacs/cliui/dist/esm/eastasianwidth/index.d.ts.map +0 -1
- package/node_modules/@isaacs/cliui/dist/esm/eastasianwidth/index.js +0 -299
- package/node_modules/@isaacs/cliui/dist/esm/eastasianwidth/index.js.map +0 -1
- package/node_modules/@isaacs/cliui/dist/esm/emoji-regex/index.d.ts +0 -2
- package/node_modules/@isaacs/cliui/dist/esm/emoji-regex/index.d.ts.map +0 -1
- package/node_modules/@isaacs/cliui/dist/esm/emoji-regex/index.js +0 -3
- package/node_modules/@isaacs/cliui/dist/esm/emoji-regex/index.js.map +0 -1
- package/node_modules/@isaacs/cliui/dist/esm/index.d.ts +0 -41
- package/node_modules/@isaacs/cliui/dist/esm/index.d.ts.map +0 -1
- package/node_modules/@isaacs/cliui/dist/esm/index.js +0 -317
- package/node_modules/@isaacs/cliui/dist/esm/index.js.map +0 -1
- package/node_modules/@isaacs/cliui/dist/esm/index.min.js +0 -12
- package/node_modules/@isaacs/cliui/dist/esm/index.min.js.map +0 -7
- package/node_modules/@isaacs/cliui/dist/esm/package.json +0 -3
- package/node_modules/@isaacs/cliui/dist/esm/string-width/index.d.ts +0 -5
- package/node_modules/@isaacs/cliui/dist/esm/string-width/index.d.ts.map +0 -1
- package/node_modules/@isaacs/cliui/dist/esm/string-width/index.js +0 -46
- package/node_modules/@isaacs/cliui/dist/esm/string-width/index.js.map +0 -1
- package/node_modules/@isaacs/cliui/dist/esm/strip-ansi/index.d.ts +0 -2
- package/node_modules/@isaacs/cliui/dist/esm/strip-ansi/index.d.ts.map +0 -1
- package/node_modules/@isaacs/cliui/dist/esm/strip-ansi/index.js +0 -4
- package/node_modules/@isaacs/cliui/dist/esm/strip-ansi/index.js.map +0 -1
- package/node_modules/@isaacs/cliui/dist/esm/wrap-ansi/index.d.ts +0 -7
- package/node_modules/@isaacs/cliui/dist/esm/wrap-ansi/index.d.ts.map +0 -1
- package/node_modules/@isaacs/cliui/dist/esm/wrap-ansi/index.js +0 -172
- package/node_modules/@isaacs/cliui/dist/esm/wrap-ansi/index.js.map +0 -1
- package/node_modules/@isaacs/cliui/package.json +0 -163
- package/node_modules/content-disposition/HISTORY.md +0 -60
- package/node_modules/cross-spawn/LICENSE +0 -21
- package/node_modules/cross-spawn/README.md +0 -89
- package/node_modules/cross-spawn/index.js +0 -39
- package/node_modules/cross-spawn/lib/enoent.js +0 -59
- package/node_modules/cross-spawn/lib/parse.js +0 -91
- package/node_modules/cross-spawn/lib/util/escape.js +0 -47
- package/node_modules/cross-spawn/lib/util/readShebang.js +0 -23
- package/node_modules/cross-spawn/lib/util/resolveCommand.js +0 -52
- package/node_modules/cross-spawn/package.json +0 -73
- package/node_modules/foreground-child/LICENSE +0 -15
- package/node_modules/foreground-child/README.md +0 -128
- package/node_modules/foreground-child/dist/commonjs/all-signals.d.ts +0 -2
- package/node_modules/foreground-child/dist/commonjs/all-signals.d.ts.map +0 -1
- package/node_modules/foreground-child/dist/commonjs/all-signals.js +0 -58
- package/node_modules/foreground-child/dist/commonjs/all-signals.js.map +0 -1
- package/node_modules/foreground-child/dist/commonjs/index.d.ts +0 -58
- package/node_modules/foreground-child/dist/commonjs/index.d.ts.map +0 -1
- package/node_modules/foreground-child/dist/commonjs/index.js +0 -123
- package/node_modules/foreground-child/dist/commonjs/index.js.map +0 -1
- package/node_modules/foreground-child/dist/commonjs/package.json +0 -3
- package/node_modules/foreground-child/dist/commonjs/proxy-signals.d.ts +0 -6
- package/node_modules/foreground-child/dist/commonjs/proxy-signals.d.ts.map +0 -1
- package/node_modules/foreground-child/dist/commonjs/proxy-signals.js +0 -38
- package/node_modules/foreground-child/dist/commonjs/proxy-signals.js.map +0 -1
- package/node_modules/foreground-child/dist/commonjs/watchdog.d.ts +0 -10
- package/node_modules/foreground-child/dist/commonjs/watchdog.d.ts.map +0 -1
- package/node_modules/foreground-child/dist/commonjs/watchdog.js +0 -50
- package/node_modules/foreground-child/dist/commonjs/watchdog.js.map +0 -1
- package/node_modules/foreground-child/dist/esm/all-signals.d.ts +0 -2
- package/node_modules/foreground-child/dist/esm/all-signals.d.ts.map +0 -1
- package/node_modules/foreground-child/dist/esm/all-signals.js +0 -52
- package/node_modules/foreground-child/dist/esm/all-signals.js.map +0 -1
- package/node_modules/foreground-child/dist/esm/index.d.ts +0 -58
- package/node_modules/foreground-child/dist/esm/index.d.ts.map +0 -1
- package/node_modules/foreground-child/dist/esm/index.js +0 -115
- package/node_modules/foreground-child/dist/esm/index.js.map +0 -1
- package/node_modules/foreground-child/dist/esm/package.json +0 -3
- package/node_modules/foreground-child/dist/esm/proxy-signals.d.ts +0 -6
- package/node_modules/foreground-child/dist/esm/proxy-signals.d.ts.map +0 -1
- package/node_modules/foreground-child/dist/esm/proxy-signals.js +0 -34
- package/node_modules/foreground-child/dist/esm/proxy-signals.js.map +0 -1
- package/node_modules/foreground-child/dist/esm/watchdog.d.ts +0 -10
- package/node_modules/foreground-child/dist/esm/watchdog.d.ts.map +0 -1
- package/node_modules/foreground-child/dist/esm/watchdog.js +0 -46
- package/node_modules/foreground-child/dist/esm/watchdog.js.map +0 -1
- package/node_modules/foreground-child/package.json +0 -106
- package/node_modules/glob/dist/esm/bin.d.mts +0 -3
- package/node_modules/glob/dist/esm/bin.d.mts.map +0 -1
- package/node_modules/glob/dist/esm/bin.mjs +0 -346
- package/node_modules/glob/dist/esm/bin.mjs.map +0 -1
- package/node_modules/isexe/.npmignore +0 -2
- package/node_modules/isexe/LICENSE +0 -15
- package/node_modules/isexe/README.md +0 -51
- package/node_modules/isexe/index.js +0 -57
- package/node_modules/isexe/mode.js +0 -41
- package/node_modules/isexe/package.json +0 -31
- package/node_modules/isexe/test/basic.js +0 -221
- package/node_modules/isexe/windows.js +0 -42
- package/node_modules/jackspeak/LICENSE.md +0 -55
- package/node_modules/jackspeak/README.md +0 -394
- package/node_modules/jackspeak/dist/commonjs/index.d.ts +0 -323
- package/node_modules/jackspeak/dist/commonjs/index.d.ts.map +0 -1
- package/node_modules/jackspeak/dist/commonjs/index.js +0 -944
- package/node_modules/jackspeak/dist/commonjs/index.js.map +0 -1
- package/node_modules/jackspeak/dist/commonjs/index.min.js +0 -33
- package/node_modules/jackspeak/dist/commonjs/index.min.js.map +0 -7
- package/node_modules/jackspeak/dist/commonjs/package.json +0 -3
- package/node_modules/jackspeak/dist/esm/index.d.ts +0 -323
- package/node_modules/jackspeak/dist/esm/index.d.ts.map +0 -1
- package/node_modules/jackspeak/dist/esm/index.js +0 -936
- package/node_modules/jackspeak/dist/esm/index.js.map +0 -1
- package/node_modules/jackspeak/dist/esm/index.min.js +0 -33
- package/node_modules/jackspeak/dist/esm/index.min.js.map +0 -7
- package/node_modules/jackspeak/dist/esm/package.json +0 -3
- package/node_modules/jackspeak/package.json +0 -115
- package/node_modules/jishushell-panel/output/public/assets/ApiKeyField-D1i7zWXR.js +0 -1
- package/node_modules/jishushell-panel/output/public/assets/Dashboard-sWIvL43F.js +0 -1
- package/node_modules/jishushell-panel/output/public/assets/HermesChatPanel-DQ8RyvQY.js +0 -1
- package/node_modules/jishushell-panel/output/public/assets/HermesConfigForm-tIbPP1sB.js +0 -4
- package/node_modules/jishushell-panel/output/public/assets/InitPassword-C3Slq3Dd.js +0 -1
- package/node_modules/jishushell-panel/output/public/assets/InstanceDetail-7JqY9tq4.js +0 -92
- package/node_modules/jishushell-panel/output/public/assets/Login-BXLDJlQN.js +0 -1
- package/node_modules/jishushell-panel/output/public/assets/NewInstance-dLc5Xrpx.js +0 -1
- package/node_modules/jishushell-panel/output/public/assets/ProviderRecommendations-DIAXxesl.js +0 -1
- package/node_modules/jishushell-panel/output/public/assets/Settings-Bd5utbBh.js +0 -1
- package/node_modules/jishushell-panel/output/public/assets/Setup-Yn9_20FL.js +0 -1
- package/node_modules/jishushell-panel/output/public/assets/WeixinLoginPanel-C21doQTJ.js +0 -9
- package/node_modules/jishushell-panel/output/public/assets/index-CCkaIEjn.js +0 -20
- package/node_modules/jishushell-panel/output/public/assets/index-D7qxy-Vh.css +0 -1
- package/node_modules/jishushell-panel/output/public/assets/registry-B2ZQZXWL.js +0 -2
- package/node_modules/jishushell-panel/output/public/assets/usePolling-BFZm4do_.js +0 -1
- package/node_modules/jishushell-panel/output/public/assets/vendor-i18n-DqPtOicc.js +0 -9
- package/node_modules/jishushell-panel/output/public/assets/vendor-react-DW5juQin.js +0 -59
- package/node_modules/package-json-from-dist/LICENSE.md +0 -63
- package/node_modules/package-json-from-dist/README.md +0 -110
- package/node_modules/package-json-from-dist/dist/commonjs/index.d.ts +0 -89
- package/node_modules/package-json-from-dist/dist/commonjs/index.d.ts.map +0 -1
- package/node_modules/package-json-from-dist/dist/commonjs/index.js +0 -134
- package/node_modules/package-json-from-dist/dist/commonjs/index.js.map +0 -1
- package/node_modules/package-json-from-dist/dist/commonjs/package.json +0 -3
- package/node_modules/package-json-from-dist/dist/esm/index.d.ts +0 -89
- package/node_modules/package-json-from-dist/dist/esm/index.d.ts.map +0 -1
- package/node_modules/package-json-from-dist/dist/esm/index.js +0 -129
- package/node_modules/package-json-from-dist/dist/esm/index.js.map +0 -1
- package/node_modules/package-json-from-dist/dist/esm/package.json +0 -3
- package/node_modules/package-json-from-dist/package.json +0 -68
- package/node_modules/path-key/index.d.ts +0 -40
- package/node_modules/path-key/index.js +0 -16
- package/node_modules/path-key/license +0 -9
- package/node_modules/path-key/package.json +0 -39
- package/node_modules/path-key/readme.md +0 -61
- package/node_modules/safe-buffer/LICENSE +0 -21
- package/node_modules/safe-buffer/README.md +0 -584
- package/node_modules/safe-buffer/index.d.ts +0 -187
- package/node_modules/safe-buffer/index.js +0 -65
- package/node_modules/safe-buffer/package.json +0 -51
- package/node_modules/shebang-command/index.js +0 -19
- package/node_modules/shebang-command/license +0 -9
- package/node_modules/shebang-command/package.json +0 -34
- package/node_modules/shebang-command/readme.md +0 -34
- package/node_modules/shebang-regex/index.d.ts +0 -22
- package/node_modules/shebang-regex/index.js +0 -2
- package/node_modules/shebang-regex/license +0 -9
- package/node_modules/shebang-regex/package.json +0 -35
- package/node_modules/shebang-regex/readme.md +0 -33
- package/node_modules/signal-exit/LICENSE.txt +0 -16
- package/node_modules/signal-exit/README.md +0 -74
- package/node_modules/signal-exit/dist/cjs/browser.d.ts +0 -12
- package/node_modules/signal-exit/dist/cjs/browser.d.ts.map +0 -1
- package/node_modules/signal-exit/dist/cjs/browser.js +0 -10
- package/node_modules/signal-exit/dist/cjs/browser.js.map +0 -1
- package/node_modules/signal-exit/dist/cjs/index.d.ts +0 -48
- package/node_modules/signal-exit/dist/cjs/index.d.ts.map +0 -1
- package/node_modules/signal-exit/dist/cjs/index.js +0 -279
- package/node_modules/signal-exit/dist/cjs/index.js.map +0 -1
- package/node_modules/signal-exit/dist/cjs/package.json +0 -3
- package/node_modules/signal-exit/dist/cjs/signals.d.ts +0 -29
- package/node_modules/signal-exit/dist/cjs/signals.d.ts.map +0 -1
- package/node_modules/signal-exit/dist/cjs/signals.js +0 -42
- package/node_modules/signal-exit/dist/cjs/signals.js.map +0 -1
- package/node_modules/signal-exit/dist/mjs/browser.d.ts +0 -12
- package/node_modules/signal-exit/dist/mjs/browser.d.ts.map +0 -1
- package/node_modules/signal-exit/dist/mjs/browser.js +0 -4
- package/node_modules/signal-exit/dist/mjs/browser.js.map +0 -1
- package/node_modules/signal-exit/dist/mjs/index.d.ts +0 -48
- package/node_modules/signal-exit/dist/mjs/index.d.ts.map +0 -1
- package/node_modules/signal-exit/dist/mjs/index.js +0 -275
- package/node_modules/signal-exit/dist/mjs/index.js.map +0 -1
- package/node_modules/signal-exit/dist/mjs/package.json +0 -3
- package/node_modules/signal-exit/dist/mjs/signals.d.ts +0 -29
- package/node_modules/signal-exit/dist/mjs/signals.d.ts.map +0 -1
- package/node_modules/signal-exit/dist/mjs/signals.js +0 -39
- package/node_modules/signal-exit/dist/mjs/signals.js.map +0 -1
- package/node_modules/signal-exit/package.json +0 -106
- package/node_modules/which/CHANGELOG.md +0 -166
- package/node_modules/which/LICENSE +0 -15
- package/node_modules/which/README.md +0 -54
- package/node_modules/which/bin/node-which +0 -52
- package/node_modules/which/package.json +0 -43
- package/node_modules/which/which.js +0 -125
- package/scripts/check-adapter-isolation.ts +0 -293
- /package/dist/services/{app → app-common}/app-compiler.d.ts +0 -0
- /package/dist/services/{app → app-common}/terminal-session-manager.d.ts +0 -0
- /package/dist/services/{backup-verify.d.ts → backup/backup-verify.d.ts} +0 -0
- /package/dist/services/{external-mounts.d.ts → files/external-mounts.d.ts} +0 -0
- /package/dist/services/{organize → files/organize}/applier.d.ts +0 -0
- /package/dist/services/{organize → files/organize}/rules.d.ts +0 -0
- /package/dist/services/{organize → files/organize}/scanner.d.ts +0 -0
- /package/dist/services/{organize → files/organize}/store.d.ts +0 -0
- /package/dist/services/{webdav → files/webdav}/xml-builder.d.ts +0 -0
- /package/dist/services/{webdav → files/webdav}/xml-builder.js +0 -0
- /package/dist/services/{app-passwords.d.ts → instances/passwords.d.ts} +0 -0
- /package/dist/services/{agent-apps → integrations/installable}/installers/registry-probe.d.ts +0 -0
- /package/dist/services/{agent-apps → integrations/installable}/installers/registry-probe.js +0 -0
- /package/dist/services/{runtime/mcp-shims → integrations/openclaw}/drive-shim.d.ts +0 -0
- /package/dist/services/{runtime/mcp-shims → integrations/openclaw}/mcporter-lite.d.ts +0 -0
- /package/dist/services/{plugin-installer.d.ts → setup/plugin-installer.d.ts} +0 -0
- /package/dist/services/{macos-launchd.d.ts → system/macos-launchd.d.ts} +0 -0
- /package/dist/services/{system-monitor.d.ts → system/system-monitor.d.ts} +0 -0
|
@@ -0,0 +1,1191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw-specific HTTP routes — private Panel route integration.
|
|
3
|
+
*
|
|
4
|
+
* These endpoints know about the OpenClaw workspace layout (mcporter.json,
|
|
5
|
+
* .openclaw/workspace/skills/, sessions.json), OpenClaw's Feishu/WeChat
|
|
6
|
+
* channel plugins, and the OpenClaw control-UI HTML that needs
|
|
7
|
+
* boot-script injection. The OpenClaw integration registers them through the
|
|
8
|
+
* AppIntegration route hook; the framework only dispatches that hook.
|
|
9
|
+
*/
|
|
10
|
+
import { createHash } from "crypto";
|
|
11
|
+
import { existsSync, realpathSync } from "fs";
|
|
12
|
+
import { readFile, stat } from "fs/promises";
|
|
13
|
+
import { request as httpRequest } from "http";
|
|
14
|
+
import { join } from "path";
|
|
15
|
+
import { PROXY_IDENTITY_HEADERS } from "../../../constants.js";
|
|
16
|
+
import * as appLifecycle from "../../app-common/lifecycle-service.js";
|
|
17
|
+
import * as appService from "../../app-common/service.js";
|
|
18
|
+
import { invalidateExecutionOwner } from "../../app-common/execution-owner.js";
|
|
19
|
+
import { readAppConfig, writeAppConfig } from "../../instances/config-admin.js";
|
|
20
|
+
import { assertNotLocked } from "../../backup/backup-manager.js";
|
|
21
|
+
import * as instanceManager from "../../instances/manager.js";
|
|
22
|
+
import { markRuntimeRepairRestartApplied } from "../../repair/runtime-repair.js";
|
|
23
|
+
import * as pluginInstaller from "../../setup/plugin-installer.js";
|
|
24
|
+
import { supportsChatPanelUi } from "../../runtime/instance.js";
|
|
25
|
+
import { getIntegration, resolvePrimaryIntegrationKind } from "../index.js";
|
|
26
|
+
import { addTemporaryBrowserAllowedHostname, DEFAULT_BROWSER_ALLOWED_HOSTNAMES, mergeBrowserAllowedHostnames, normalizeBrowserAllowedHostname, readTemporaryBrowserAllowedHostnames, removeTemporaryBrowserAllowedHostname, } from "../../capabilities/browser-policy.js";
|
|
27
|
+
import { writeConfigFile, ensureDirContainer } from "../../../utils/fs.js";
|
|
28
|
+
import { HOP_BY_HOP, getSvc, inferRequestOrigin, validateId, } from "../../../routes/instances.js";
|
|
29
|
+
import { ensureOpenclawControlUiAllowedOrigin } from "./integration.js";
|
|
30
|
+
/**
|
|
31
|
+
* Register all OpenClaw-specific HTTP endpoints on the given Fastify app.
|
|
32
|
+
* Called by the Panel route composition at server startup.
|
|
33
|
+
*/
|
|
34
|
+
const REFERER_INSTANCE_ID_RE = /\/api\/integrations\/openclaw\/instances\/([a-z0-9][a-z0-9-]*)\/control-ui(?:\/|$|\?|#)/i;
|
|
35
|
+
function resolveOpenclawHome(instanceId) {
|
|
36
|
+
const integration = getIntegration("openclaw");
|
|
37
|
+
if (typeof integration.resolveAgentHome !== "function") {
|
|
38
|
+
throw new Error("OpenClaw integration does not expose its canonical home path");
|
|
39
|
+
}
|
|
40
|
+
return integration.resolveAgentHome(instanceId);
|
|
41
|
+
}
|
|
42
|
+
function normalizeBrowserHostCandidate(value) {
|
|
43
|
+
return normalizeBrowserAllowedHostname(value);
|
|
44
|
+
}
|
|
45
|
+
function mergeHostnames(...lists) {
|
|
46
|
+
return lists.reduce((acc, list) => mergeBrowserAllowedHostnames(acc, list), []);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Extract the instance id from an iframe Referer header that points at the
|
|
50
|
+
* control-UI proxy (`/api/integrations/openclaw/instances/<id>/control-ui/...`). Used by the
|
|
51
|
+
* referer-forwarded proxy to recover routing context for OpenClaw chat
|
|
52
|
+
* messages that embed jishushell-absolute URLs (e.g. screenshot media).
|
|
53
|
+
*
|
|
54
|
+
* Returns null when the Referer is missing, malformed, or doesn't match a
|
|
55
|
+
* control UI URL — caller should fall through to a 404.
|
|
56
|
+
*/
|
|
57
|
+
export function extractRefererInstanceId(refererHeader) {
|
|
58
|
+
const ref = typeof refererHeader === "string"
|
|
59
|
+
? refererHeader
|
|
60
|
+
: Array.isArray(refererHeader)
|
|
61
|
+
? String(refererHeader[0] ?? "")
|
|
62
|
+
: "";
|
|
63
|
+
if (!ref)
|
|
64
|
+
return null;
|
|
65
|
+
const m = ref.match(REFERER_INSTANCE_ID_RE);
|
|
66
|
+
return m ? m[1] : null;
|
|
67
|
+
}
|
|
68
|
+
export function registerOpenclawRoutes(app) {
|
|
69
|
+
app.post("/api/integrations/openclaw/instances/:id/browser-allowlist", async (req, reply) => {
|
|
70
|
+
const idErr = validateId(req.params.id);
|
|
71
|
+
if (idErr)
|
|
72
|
+
return reply.status(400).send({ detail: idErr });
|
|
73
|
+
try {
|
|
74
|
+
assertNotLocked(req.params.id);
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
return reply.status(e.statusCode || 409).send({ detail: e.message });
|
|
78
|
+
}
|
|
79
|
+
const instance = appService.getInstance(req.params.id);
|
|
80
|
+
if (!instance)
|
|
81
|
+
return reply.status(404).send({ detail: "Instance not found" });
|
|
82
|
+
if (resolvePrimaryIntegrationKind(instance) !== "openclaw") {
|
|
83
|
+
return reply.status(400).send({ detail: "Browser allowlist actions are only supported for OpenClaw instances" });
|
|
84
|
+
}
|
|
85
|
+
const host = normalizeBrowserHostCandidate(req.body?.host);
|
|
86
|
+
if (!host)
|
|
87
|
+
return reply.status(400).send({ detail: "A valid hostname is required" });
|
|
88
|
+
const scope = req.body?.scope;
|
|
89
|
+
if (scope !== "temporary" && scope !== "persistent") {
|
|
90
|
+
return reply.status(400).send({ detail: "scope must be 'temporary' or 'persistent'" });
|
|
91
|
+
}
|
|
92
|
+
const current = await readAppConfig(req.params.id);
|
|
93
|
+
if (!current || typeof current !== "object" || Array.isArray(current)) {
|
|
94
|
+
return reply.status(400).send({ detail: "Config must be a JSON object" });
|
|
95
|
+
}
|
|
96
|
+
const next = structuredClone(current);
|
|
97
|
+
next.browser ??= {};
|
|
98
|
+
next.browser.ssrfPolicy ??= {};
|
|
99
|
+
const existing = Array.isArray(next.browser.ssrfPolicy.allowedHostnames)
|
|
100
|
+
? next.browser.ssrfPolicy.allowedHostnames.map((entry) => String(entry))
|
|
101
|
+
: [];
|
|
102
|
+
next.browser.ssrfPolicy.allowedHostnames = mergeHostnames(existing, [host]);
|
|
103
|
+
const alreadyPersistent = existing.some((entry) => normalizeBrowserHostCandidate(entry) === host);
|
|
104
|
+
const addedTemporary = scope === "temporary" && !alreadyPersistent;
|
|
105
|
+
try {
|
|
106
|
+
if (addedTemporary) {
|
|
107
|
+
addTemporaryBrowserAllowedHostname(req.params.id, host);
|
|
108
|
+
}
|
|
109
|
+
else if (scope === "persistent") {
|
|
110
|
+
removeTemporaryBrowserAllowedHostname(req.params.id, host);
|
|
111
|
+
}
|
|
112
|
+
await writeAppConfig(req.params.id, next);
|
|
113
|
+
const controlUiOrigin = inferRequestOrigin(req);
|
|
114
|
+
const restart = controlUiOrigin
|
|
115
|
+
? await appLifecycle.restartInstance(req.params.id, { controlUiOrigin })
|
|
116
|
+
: await appLifecycle.restartInstance(req.params.id);
|
|
117
|
+
invalidateExecutionOwner(req.params.id);
|
|
118
|
+
if (!restart.ok) {
|
|
119
|
+
return reply.status(400).send({ detail: restart.error || "Failed to restart instance after updating the browser allowlist" });
|
|
120
|
+
}
|
|
121
|
+
markRuntimeRepairRestartApplied(req.params.id);
|
|
122
|
+
const temporaryAllowedHostnames = readTemporaryBrowserAllowedHostnames(req.params.id);
|
|
123
|
+
const persistentAllowedHostnames = mergeHostnames(next.browser.ssrfPolicy.allowedHostnames, [])
|
|
124
|
+
.filter((entry) => !temporaryAllowedHostnames.includes(entry));
|
|
125
|
+
return {
|
|
126
|
+
ok: true,
|
|
127
|
+
host,
|
|
128
|
+
scope,
|
|
129
|
+
temporaryAllowedHostnames,
|
|
130
|
+
persistentAllowedHostnames,
|
|
131
|
+
effectiveAllowedHostnames: mergeHostnames(persistentAllowedHostnames, temporaryAllowedHostnames),
|
|
132
|
+
restart,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
if (addedTemporary)
|
|
137
|
+
removeTemporaryBrowserAllowedHostname(req.params.id, host);
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
app.post("/api/integrations/openclaw/instances/:id/browser-allow-all", async (req, reply) => {
|
|
142
|
+
const idErr = validateId(req.params.id);
|
|
143
|
+
if (idErr)
|
|
144
|
+
return reply.status(400).send({ detail: idErr });
|
|
145
|
+
try {
|
|
146
|
+
assertNotLocked(req.params.id);
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
return reply.status(e.statusCode || 409).send({ detail: e.message });
|
|
150
|
+
}
|
|
151
|
+
const instance = appService.getInstance(req.params.id);
|
|
152
|
+
if (!instance)
|
|
153
|
+
return reply.status(404).send({ detail: "Instance not found" });
|
|
154
|
+
if (resolvePrimaryIntegrationKind(instance) !== "openclaw") {
|
|
155
|
+
return reply.status(400).send({ detail: "Browser allow-all is only supported for OpenClaw instances" });
|
|
156
|
+
}
|
|
157
|
+
if (typeof req.body?.allowAll !== "boolean") {
|
|
158
|
+
return reply.status(400).send({ detail: "allowAll must be a boolean" });
|
|
159
|
+
}
|
|
160
|
+
const current = await readAppConfig(req.params.id);
|
|
161
|
+
if (!current || typeof current !== "object" || Array.isArray(current)) {
|
|
162
|
+
return reply.status(400).send({ detail: "Config must be a JSON object" });
|
|
163
|
+
}
|
|
164
|
+
const next = structuredClone(current);
|
|
165
|
+
next.browser ??= {};
|
|
166
|
+
if (req.body.allowAll) {
|
|
167
|
+
next.meta ??= {};
|
|
168
|
+
next.meta._js_allowAll = true;
|
|
169
|
+
delete next.browser.ssrfPolicy;
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
if (next.meta)
|
|
173
|
+
delete next.meta._js_allowAll;
|
|
174
|
+
next.browser.ssrfPolicy = { allowedHostnames: [...DEFAULT_BROWSER_ALLOWED_HOSTNAMES] };
|
|
175
|
+
}
|
|
176
|
+
const tempHosts = readTemporaryBrowserAllowedHostnames(req.params.id);
|
|
177
|
+
for (const tempHost of tempHosts) {
|
|
178
|
+
removeTemporaryBrowserAllowedHostname(req.params.id, tempHost);
|
|
179
|
+
}
|
|
180
|
+
await writeAppConfig(req.params.id, next);
|
|
181
|
+
const controlUiOrigin = inferRequestOrigin(req);
|
|
182
|
+
const restart = controlUiOrigin
|
|
183
|
+
? await appLifecycle.restartInstance(req.params.id, { controlUiOrigin })
|
|
184
|
+
: await appLifecycle.restartInstance(req.params.id);
|
|
185
|
+
invalidateExecutionOwner(req.params.id);
|
|
186
|
+
if (!restart.ok) {
|
|
187
|
+
return reply.status(400).send({ detail: restart.error || "Failed to restart instance after updating the browser allowlist" });
|
|
188
|
+
}
|
|
189
|
+
markRuntimeRepairRestartApplied(req.params.id);
|
|
190
|
+
return {
|
|
191
|
+
ok: true,
|
|
192
|
+
allowAll: req.body.allowAll,
|
|
193
|
+
allowedHostnames: next.browser.ssrfPolicy?.allowedHostnames ?? [],
|
|
194
|
+
restart,
|
|
195
|
+
};
|
|
196
|
+
});
|
|
197
|
+
// ── Plugin check & install — host-side, no container dependency ────
|
|
198
|
+
app.get("/api/integrations/openclaw/instances/:id/plugins/check/:channelId", async (req, reply) => {
|
|
199
|
+
const idErr = validateId(req.params.id);
|
|
200
|
+
if (idErr)
|
|
201
|
+
return reply.status(400).send({ detail: idErr });
|
|
202
|
+
if (!instanceManager.getInstance(req.params.id)) {
|
|
203
|
+
return reply.status(404).send({ detail: "Instance not found" });
|
|
204
|
+
}
|
|
205
|
+
const inst = instanceManager.getInstance(req.params.id);
|
|
206
|
+
const integrationKind = resolvePrimaryIntegrationKind(inst);
|
|
207
|
+
if (!integrationKind) {
|
|
208
|
+
return reply.status(501).send({ detail: "Plugin check is not supported for this runtime" });
|
|
209
|
+
}
|
|
210
|
+
const integration = getIntegration(integrationKind);
|
|
211
|
+
const installed = typeof integration.isChannelPluginInstalled === "function"
|
|
212
|
+
? integration.isChannelPluginInstalled(req.params.id, req.params.channelId)
|
|
213
|
+
: false;
|
|
214
|
+
return { channelId: req.params.channelId, installed };
|
|
215
|
+
});
|
|
216
|
+
app.get("/api/integrations/openclaw/instances/:id/plugins/status", async (req, reply) => {
|
|
217
|
+
const idErr = validateId(req.params.id);
|
|
218
|
+
if (idErr)
|
|
219
|
+
return reply.status(400).send({ detail: idErr });
|
|
220
|
+
if (!instanceManager.getInstance(req.params.id)) {
|
|
221
|
+
return reply.status(404).send({ detail: "Instance not found" });
|
|
222
|
+
}
|
|
223
|
+
return { plugins: pluginInstaller.getAllPluginStatuses(req.params.id) };
|
|
224
|
+
});
|
|
225
|
+
app.get("/api/integrations/openclaw/instances/:id/quick-status", async (req, reply) => {
|
|
226
|
+
const idErr = validateId(req.params.id);
|
|
227
|
+
if (idErr)
|
|
228
|
+
return reply.status(400).send({ detail: idErr });
|
|
229
|
+
if (!instanceManager.getInstance(req.params.id)) {
|
|
230
|
+
return reply.status(404).send({ detail: "Instance not found" });
|
|
231
|
+
}
|
|
232
|
+
const id = req.params.id;
|
|
233
|
+
const cfg = instanceManager.getConfig(id) ?? {};
|
|
234
|
+
const channels = cfg.channels ?? {};
|
|
235
|
+
const feishuCh = channels["feishu"] ?? channels["lark"] ?? {};
|
|
236
|
+
const weixinCh = channels["openclaw-weixin"] ?? {};
|
|
237
|
+
const feishuBound = !!(feishuCh.enabled &&
|
|
238
|
+
(feishuCh.appId || feishuCh.token || feishuCh.deviceToken || feishuCh.accessToken));
|
|
239
|
+
const weixinBound = !!(weixinCh.enabled &&
|
|
240
|
+
weixinCh.accounts &&
|
|
241
|
+
Object.keys(weixinCh.accounts).length > 0);
|
|
242
|
+
const { readdirSync: fsReaddir, readFileSync: fsRead } = await import("fs");
|
|
243
|
+
const { join: fsJoin } = await import("path");
|
|
244
|
+
const workspaceDir = fsJoin(resolveOpenclawHome(id), ".openclaw", "workspace");
|
|
245
|
+
const stateDir = fsJoin(workspaceDir, "skills");
|
|
246
|
+
let installedSkillDirs = [];
|
|
247
|
+
try {
|
|
248
|
+
installedSkillDirs = fsReaddir(stateDir, { withFileTypes: true })
|
|
249
|
+
.filter((e) => e.isDirectory())
|
|
250
|
+
.map((e) => e.name);
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
/* no skills dir */
|
|
254
|
+
}
|
|
255
|
+
const mcporterInstalled = installedSkillDirs.some((d) => d.toLowerCase() === "mcporter");
|
|
256
|
+
let mcporterServers = {};
|
|
257
|
+
const mcporterCfgPath = fsJoin(workspaceDir, "config", "mcporter.json");
|
|
258
|
+
try {
|
|
259
|
+
const raw = JSON.parse(fsRead(mcporterCfgPath, "utf8"));
|
|
260
|
+
mcporterServers = raw.mcpServers ?? {};
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
/* no mcporter config */
|
|
264
|
+
}
|
|
265
|
+
return {
|
|
266
|
+
im: { feishu: feishuBound, weixin: weixinBound },
|
|
267
|
+
installedSkillDirs,
|
|
268
|
+
mcporterInstalled,
|
|
269
|
+
mcporterServers,
|
|
270
|
+
};
|
|
271
|
+
});
|
|
272
|
+
// ── MCPorter server CRUD ──────────────────────────────────────────
|
|
273
|
+
app.get("/api/integrations/openclaw/instances/:id/mcporter/list", async (req, reply) => {
|
|
274
|
+
const idErr = validateId(req.params.id);
|
|
275
|
+
if (idErr)
|
|
276
|
+
return reply.status(400).send({ detail: idErr });
|
|
277
|
+
if (!instanceManager.getInstance(req.params.id)) {
|
|
278
|
+
return reply.status(404).send({ detail: "Instance not found" });
|
|
279
|
+
}
|
|
280
|
+
const id = req.params.id;
|
|
281
|
+
const openclawHome = resolveOpenclawHome(id);
|
|
282
|
+
const workspaceDir = join(openclawHome, ".openclaw", "workspace");
|
|
283
|
+
const mcporterBinPath = join(openclawHome, ".npm-global", "bin", "mcporter");
|
|
284
|
+
const mcporterFallbackPath = join(openclawHome, ".npm-global", "bin", "jishushell-mcporter");
|
|
285
|
+
const mcporterCfg = join(workspaceDir, "config", "mcporter.json");
|
|
286
|
+
const binPath = existsSync(mcporterBinPath)
|
|
287
|
+
? mcporterBinPath
|
|
288
|
+
: existsSync(mcporterFallbackPath)
|
|
289
|
+
? mcporterFallbackPath
|
|
290
|
+
: "";
|
|
291
|
+
if (!binPath) {
|
|
292
|
+
return { servers: [], installed: false };
|
|
293
|
+
}
|
|
294
|
+
const { execFile } = await import("child_process");
|
|
295
|
+
const { promisify } = await import("util");
|
|
296
|
+
const execFileAsync = promisify(execFile);
|
|
297
|
+
try {
|
|
298
|
+
const useNodeLauncher = binPath === mcporterFallbackPath;
|
|
299
|
+
const { stdout } = await execFileAsync(useNodeLauncher ? process.execPath : binPath, useNodeLauncher ? [binPath, "list", "--json"] : ["list", "--json"], {
|
|
300
|
+
env: { ...process.env, HOME: openclawHome, MCPORTER_CONFIG: mcporterCfg },
|
|
301
|
+
timeout: 60_000,
|
|
302
|
+
});
|
|
303
|
+
const parsed = JSON.parse(stdout);
|
|
304
|
+
return { servers: parsed.servers ?? [], installed: true };
|
|
305
|
+
}
|
|
306
|
+
catch (err) {
|
|
307
|
+
const raw = err?.stdout ?? "";
|
|
308
|
+
try {
|
|
309
|
+
const parsed = JSON.parse(raw);
|
|
310
|
+
return { servers: parsed.servers ?? [], installed: true };
|
|
311
|
+
}
|
|
312
|
+
catch {
|
|
313
|
+
/* fall through */
|
|
314
|
+
}
|
|
315
|
+
return { servers: [], installed: true, error: err?.message ?? "unknown" };
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
app.post("/api/integrations/openclaw/instances/:id/mcporter/add", async (req, reply) => {
|
|
319
|
+
const idErr = validateId(req.params.id);
|
|
320
|
+
if (idErr)
|
|
321
|
+
return reply.status(400).send({ detail: idErr });
|
|
322
|
+
if (!instanceManager.getInstance(req.params.id)) {
|
|
323
|
+
return reply.status(404).send({ detail: "Instance not found" });
|
|
324
|
+
}
|
|
325
|
+
const { servers } = req.body;
|
|
326
|
+
if (!servers || typeof servers !== "object" || Array.isArray(servers)) {
|
|
327
|
+
return reply.status(400).send({ detail: "servers must be an object" });
|
|
328
|
+
}
|
|
329
|
+
const openclawHome = resolveOpenclawHome(req.params.id);
|
|
330
|
+
const workspaceDir = join(openclawHome, ".openclaw", "workspace");
|
|
331
|
+
const mcporterCfgPath = join(workspaceDir, "config", "mcporter.json");
|
|
332
|
+
const { readFileSync } = await import("fs");
|
|
333
|
+
let cfg = { mcpServers: {}, imports: [] };
|
|
334
|
+
try {
|
|
335
|
+
cfg = JSON.parse(readFileSync(mcporterCfgPath, "utf8"));
|
|
336
|
+
}
|
|
337
|
+
catch {
|
|
338
|
+
/* start fresh */
|
|
339
|
+
}
|
|
340
|
+
if (!cfg.mcpServers)
|
|
341
|
+
cfg.mcpServers = {};
|
|
342
|
+
// Prototype-pollution guard.
|
|
343
|
+
const PROTO_KEYS = new Set(["__proto__", "constructor", "prototype"]);
|
|
344
|
+
for (const [k, v] of Object.entries(servers)) {
|
|
345
|
+
if (!PROTO_KEYS.has(k))
|
|
346
|
+
cfg.mcpServers[k] = v;
|
|
347
|
+
}
|
|
348
|
+
try {
|
|
349
|
+
ensureDirContainer(join(workspaceDir, "config"));
|
|
350
|
+
writeConfigFile(mcporterCfgPath, JSON.stringify(cfg, null, 2));
|
|
351
|
+
}
|
|
352
|
+
catch (err) {
|
|
353
|
+
return reply.status(500).send({ detail: `Write failed: ${err.message}` });
|
|
354
|
+
}
|
|
355
|
+
return { ok: true, mcpServers: cfg.mcpServers };
|
|
356
|
+
});
|
|
357
|
+
app.delete("/api/integrations/openclaw/instances/:id/mcporter/:serverName", async (req, reply) => {
|
|
358
|
+
const idErr = validateId(req.params.id);
|
|
359
|
+
if (idErr)
|
|
360
|
+
return reply.status(400).send({ detail: idErr });
|
|
361
|
+
if (!instanceManager.getInstance(req.params.id)) {
|
|
362
|
+
return reply.status(404).send({ detail: "Instance not found" });
|
|
363
|
+
}
|
|
364
|
+
const { serverName } = req.params;
|
|
365
|
+
if (!serverName || typeof serverName !== "string") {
|
|
366
|
+
return reply.status(400).send({ detail: "serverName is required" });
|
|
367
|
+
}
|
|
368
|
+
const openclawHome = resolveOpenclawHome(req.params.id);
|
|
369
|
+
const workspaceDir = join(openclawHome, ".openclaw", "workspace");
|
|
370
|
+
const mcporterCfgPath = join(workspaceDir, "config", "mcporter.json");
|
|
371
|
+
const { readFileSync } = await import("fs");
|
|
372
|
+
let cfg = { mcpServers: {}, imports: [] };
|
|
373
|
+
try {
|
|
374
|
+
cfg = JSON.parse(readFileSync(mcporterCfgPath, "utf8"));
|
|
375
|
+
}
|
|
376
|
+
catch {
|
|
377
|
+
/* start fresh */
|
|
378
|
+
}
|
|
379
|
+
if (!cfg.mcpServers || !(serverName in cfg.mcpServers)) {
|
|
380
|
+
return reply.status(404).send({ detail: `Server '${serverName}' not found` });
|
|
381
|
+
}
|
|
382
|
+
delete cfg.mcpServers[serverName];
|
|
383
|
+
try {
|
|
384
|
+
writeConfigFile(mcporterCfgPath, JSON.stringify(cfg, null, 2));
|
|
385
|
+
}
|
|
386
|
+
catch (err) {
|
|
387
|
+
return reply.status(500).send({ detail: `Write failed: ${err.message}` });
|
|
388
|
+
}
|
|
389
|
+
return { ok: true, mcpServers: cfg.mcpServers };
|
|
390
|
+
});
|
|
391
|
+
// ── Skills CRUD ───────────────────────────────────────────────────
|
|
392
|
+
app.delete("/api/integrations/openclaw/instances/:id/skills/:skillDir", async (req, reply) => {
|
|
393
|
+
const idErr = validateId(req.params.id);
|
|
394
|
+
if (idErr)
|
|
395
|
+
return reply.status(400).send({ detail: idErr });
|
|
396
|
+
if (!instanceManager.getInstance(req.params.id)) {
|
|
397
|
+
return reply.status(404).send({ detail: "Instance not found" });
|
|
398
|
+
}
|
|
399
|
+
const { skillDir } = req.params;
|
|
400
|
+
if (!skillDir || skillDir.includes("/") || skillDir.includes("..") || skillDir.startsWith(".")) {
|
|
401
|
+
return reply.status(400).send({ detail: "Invalid skill directory name" });
|
|
402
|
+
}
|
|
403
|
+
const openclawHome = resolveOpenclawHome(req.params.id);
|
|
404
|
+
const skillPath = join(openclawHome, ".openclaw", "workspace", "skills", skillDir);
|
|
405
|
+
const { existsSync: fsEx, rmSync } = await import("fs");
|
|
406
|
+
if (!fsEx(skillPath)) {
|
|
407
|
+
return reply.status(404).send({ detail: `Skill '${skillDir}' not found` });
|
|
408
|
+
}
|
|
409
|
+
try {
|
|
410
|
+
rmSync(skillPath, { recursive: true, force: true });
|
|
411
|
+
}
|
|
412
|
+
catch (err) {
|
|
413
|
+
return reply.status(500).send({ detail: `Delete failed: ${err.message}` });
|
|
414
|
+
}
|
|
415
|
+
return { ok: true };
|
|
416
|
+
});
|
|
417
|
+
// ── Plugin install ────────────────────────────────────────────────
|
|
418
|
+
app.post("/api/integrations/openclaw/instances/:id/plugins/install", async (req, reply) => {
|
|
419
|
+
const idErr = validateId(req.params.id);
|
|
420
|
+
if (idErr)
|
|
421
|
+
return reply.status(400).send({ detail: idErr });
|
|
422
|
+
if (!instanceManager.getInstance(req.params.id)) {
|
|
423
|
+
return reply.status(404).send({ detail: "Instance not found" });
|
|
424
|
+
}
|
|
425
|
+
try {
|
|
426
|
+
assertNotLocked(req.params.id);
|
|
427
|
+
}
|
|
428
|
+
catch (e) {
|
|
429
|
+
return reply.status(e.statusCode || 409).send({ detail: e.message });
|
|
430
|
+
}
|
|
431
|
+
const { channelId } = req.body;
|
|
432
|
+
if (!channelId || typeof channelId !== "string") {
|
|
433
|
+
return reply.status(400).send({ detail: "channelId is required" });
|
|
434
|
+
}
|
|
435
|
+
const inst2 = instanceManager.getInstance(req.params.id);
|
|
436
|
+
const integrationKind2 = resolvePrimaryIntegrationKind(inst2);
|
|
437
|
+
if (!integrationKind2) {
|
|
438
|
+
return reply.status(501).send({ detail: "Plugin install is not supported for this runtime" });
|
|
439
|
+
}
|
|
440
|
+
const pkg = getIntegration(integrationKind2).channelPluginMap?.[channelId];
|
|
441
|
+
if (!pkg) {
|
|
442
|
+
return reply.status(400).send({ detail: `Unknown channel: ${channelId}` });
|
|
443
|
+
}
|
|
444
|
+
const pStatus = pluginInstaller.getPluginStatus(req.params.id, channelId);
|
|
445
|
+
if (pStatus.status === "installed")
|
|
446
|
+
return { ok: true, status: "already_installed" };
|
|
447
|
+
if (pStatus.status === "installing")
|
|
448
|
+
return { ok: true, status: "installing" };
|
|
449
|
+
pluginInstaller.enqueueInstall(req.params.id, channelId);
|
|
450
|
+
return { ok: true, status: "queued" };
|
|
451
|
+
});
|
|
452
|
+
// Check-only helper; throws if the plugin needed by an IM login is missing.
|
|
453
|
+
async function ensurePluginInstalled(instanceId, channelId) {
|
|
454
|
+
const inst = instanceManager.getInstance(instanceId);
|
|
455
|
+
const integrationKind = resolvePrimaryIntegrationKind(inst);
|
|
456
|
+
// Non-integrated generic instances cannot have channel plugins — return silently so
|
|
457
|
+
// IM login on such an instance fails on its own check (channel not bound),
|
|
458
|
+
// not on a "plugin missing" error that does not make sense for it.
|
|
459
|
+
if (!integrationKind)
|
|
460
|
+
return;
|
|
461
|
+
const integration = getIntegration(integrationKind);
|
|
462
|
+
if (!integration.channelPluginMap?.[channelId])
|
|
463
|
+
return;
|
|
464
|
+
const installed = typeof integration.isChannelPluginInstalled === "function"
|
|
465
|
+
? integration.isChannelPluginInstalled(instanceId, channelId)
|
|
466
|
+
: false;
|
|
467
|
+
if (!installed) {
|
|
468
|
+
throw new Error(`Plugin ${channelId} is not installed. Please install it from the config page.`);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
// ── Feishu/Lark OAuth Device Code Login ───────────────────────────
|
|
472
|
+
const FEISHU_AUTH_URL = "https://accounts.feishu.cn";
|
|
473
|
+
const MAX_LOGIN_SESSIONS = 100;
|
|
474
|
+
const feishuLogins = new Map();
|
|
475
|
+
app.post("/api/integrations/openclaw/instances/:id/feishu/login", async (req, reply) => {
|
|
476
|
+
const channelKey = req.body?.channelKey || "feishu";
|
|
477
|
+
const idErr = validateId(req.params.id);
|
|
478
|
+
if (idErr)
|
|
479
|
+
return reply.status(400).send({ detail: idErr });
|
|
480
|
+
if (!instanceManager.getInstance(req.params.id)) {
|
|
481
|
+
return reply.status(404).send({ detail: "Instance not found" });
|
|
482
|
+
}
|
|
483
|
+
const svc = await getSvc();
|
|
484
|
+
const svcStatus = await svc.getStatus(req.params.id);
|
|
485
|
+
if (svcStatus.status !== "running") {
|
|
486
|
+
return reply.status(400).send({ detail: "Instance must be running first" });
|
|
487
|
+
}
|
|
488
|
+
try {
|
|
489
|
+
await ensurePluginInstalled(req.params.id, channelKey);
|
|
490
|
+
}
|
|
491
|
+
catch (e) {
|
|
492
|
+
return reply.status(400).send({ detail: e.message });
|
|
493
|
+
}
|
|
494
|
+
try {
|
|
495
|
+
await fetch(`${FEISHU_AUTH_URL}/oauth/v1/app/registration`, {
|
|
496
|
+
method: "POST",
|
|
497
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
498
|
+
body: "action=init",
|
|
499
|
+
signal: AbortSignal.timeout(30_000),
|
|
500
|
+
});
|
|
501
|
+
const beginResp = await fetch(`${FEISHU_AUTH_URL}/oauth/v1/app/registration`, {
|
|
502
|
+
method: "POST",
|
|
503
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
504
|
+
body: "action=begin&archetype=PersonalAgent&auth_method=client_secret&request_user_info=open_id",
|
|
505
|
+
signal: AbortSignal.timeout(30_000),
|
|
506
|
+
});
|
|
507
|
+
if (!beginResp.ok)
|
|
508
|
+
throw new Error(`Feishu API error: ${beginResp.status}`);
|
|
509
|
+
const beginData = (await beginResp.json());
|
|
510
|
+
const sessionKey = `${req.params.id}-${channelKey}-${Date.now()}`;
|
|
511
|
+
feishuLogins.set(sessionKey, {
|
|
512
|
+
instanceId: req.params.id,
|
|
513
|
+
deviceCode: beginData.device_code,
|
|
514
|
+
startedAt: Date.now(),
|
|
515
|
+
interval: beginData.interval || 5,
|
|
516
|
+
expireIn: beginData.expire_in || 600,
|
|
517
|
+
channelKey,
|
|
518
|
+
});
|
|
519
|
+
for (const [k, v] of feishuLogins) {
|
|
520
|
+
if (Date.now() - v.startedAt > v.expireIn * 1000)
|
|
521
|
+
feishuLogins.delete(k);
|
|
522
|
+
}
|
|
523
|
+
while (feishuLogins.size > MAX_LOGIN_SESSIONS) {
|
|
524
|
+
feishuLogins.delete(feishuLogins.keys().next().value);
|
|
525
|
+
}
|
|
526
|
+
return { qrcodeUrl: beginData.verification_uri_complete, sessionKey };
|
|
527
|
+
}
|
|
528
|
+
catch (e) {
|
|
529
|
+
return reply.status(502).send({ detail: e.message || "Failed to start Feishu login" });
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
app.get("/api/integrations/openclaw/instances/:id/feishu/login/:sessionKey", async (req, reply) => {
|
|
533
|
+
const idErr = validateId(req.params.id);
|
|
534
|
+
if (idErr)
|
|
535
|
+
return reply.status(400).send({ detail: idErr });
|
|
536
|
+
const login = feishuLogins.get(req.params.sessionKey);
|
|
537
|
+
if (!login)
|
|
538
|
+
return reply.status(404).send({ detail: "Login session not found or expired" });
|
|
539
|
+
if (login.instanceId !== req.params.id) {
|
|
540
|
+
return reply.status(403).send({ detail: "Session belongs to a different instance" });
|
|
541
|
+
}
|
|
542
|
+
if (Date.now() - login.startedAt > login.expireIn * 1000) {
|
|
543
|
+
feishuLogins.delete(req.params.sessionKey);
|
|
544
|
+
return { status: "expired", connected: false, message: "QR code expired, please regenerate." };
|
|
545
|
+
}
|
|
546
|
+
try {
|
|
547
|
+
const resp = await fetch(`${FEISHU_AUTH_URL}/oauth/v1/app/registration`, {
|
|
548
|
+
method: "POST",
|
|
549
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
550
|
+
body: `action=poll&device_code=${encodeURIComponent(login.deviceCode)}`,
|
|
551
|
+
signal: AbortSignal.timeout(10_000),
|
|
552
|
+
});
|
|
553
|
+
const data = (await resp.json());
|
|
554
|
+
if (data.client_id && data.client_secret) {
|
|
555
|
+
const storedChannelKey = login.channelKey || "feishu";
|
|
556
|
+
feishuLogins.delete(req.params.sessionKey);
|
|
557
|
+
const domain = data.user_info?.tenant_brand === "lark" ? "lark" : "feishu";
|
|
558
|
+
instanceManager.saveFeishuCredentials(req.params.id, {
|
|
559
|
+
appId: data.client_id,
|
|
560
|
+
appSecret: data.client_secret,
|
|
561
|
+
domain,
|
|
562
|
+
channelKey: storedChannelKey,
|
|
563
|
+
});
|
|
564
|
+
return {
|
|
565
|
+
status: "confirmed",
|
|
566
|
+
connected: true,
|
|
567
|
+
domain,
|
|
568
|
+
message: domain === "lark" ? "Lark bot configured!" : "Feishu bot configured!",
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
if (data.error === "authorization_pending") {
|
|
572
|
+
return { status: "waiting", connected: false, message: "Waiting for scan..." };
|
|
573
|
+
}
|
|
574
|
+
if (data.error === "expired_token") {
|
|
575
|
+
feishuLogins.delete(req.params.sessionKey);
|
|
576
|
+
return { status: "expired", connected: false, message: "QR code expired, please regenerate." };
|
|
577
|
+
}
|
|
578
|
+
return { status: "waiting", connected: false, message: "Waiting for scan..." };
|
|
579
|
+
}
|
|
580
|
+
catch (e) {
|
|
581
|
+
return reply.status(502).send({ detail: e.message || "Poll failed" });
|
|
582
|
+
}
|
|
583
|
+
});
|
|
584
|
+
// ── WeChat accounts + QR Login ────────────────────────────────────
|
|
585
|
+
app.get("/api/integrations/openclaw/instances/:id/weixin/accounts", async (req, reply) => {
|
|
586
|
+
const idErr = validateId(req.params.id);
|
|
587
|
+
if (idErr)
|
|
588
|
+
return reply.status(400).send({ detail: idErr });
|
|
589
|
+
if (!instanceManager.getInstance(req.params.id)) {
|
|
590
|
+
return reply.status(404).send({ detail: "Instance not found" });
|
|
591
|
+
}
|
|
592
|
+
return { accounts: instanceManager.getWeixinAccounts(req.params.id) };
|
|
593
|
+
});
|
|
594
|
+
const WEIXIN_API_BASE = "https://ilinkai.weixin.qq.com";
|
|
595
|
+
const WEIXIN_BOT_TYPE = "3";
|
|
596
|
+
const weixinLogins = new Map();
|
|
597
|
+
app.post("/api/integrations/openclaw/instances/:id/weixin/login", async (req, reply) => {
|
|
598
|
+
const idErr = validateId(req.params.id);
|
|
599
|
+
if (idErr)
|
|
600
|
+
return reply.status(400).send({ detail: idErr });
|
|
601
|
+
if (!instanceManager.getInstance(req.params.id)) {
|
|
602
|
+
return reply.status(404).send({ detail: "Instance not found" });
|
|
603
|
+
}
|
|
604
|
+
const svc = await getSvc();
|
|
605
|
+
const svcStatus = await svc.getStatus(req.params.id);
|
|
606
|
+
if (svcStatus.status !== "running") {
|
|
607
|
+
return reply.status(400).send({ detail: "Instance must be running first" });
|
|
608
|
+
}
|
|
609
|
+
try {
|
|
610
|
+
await ensurePluginInstalled(req.params.id, "openclaw-weixin");
|
|
611
|
+
}
|
|
612
|
+
catch (e) {
|
|
613
|
+
return reply.status(400).send({ detail: e.message });
|
|
614
|
+
}
|
|
615
|
+
try {
|
|
616
|
+
const resp = await fetch(`${WEIXIN_API_BASE}/ilink/bot/get_bot_qrcode?bot_type=${WEIXIN_BOT_TYPE}`, { signal: AbortSignal.timeout(30_000) });
|
|
617
|
+
if (!resp.ok)
|
|
618
|
+
throw new Error(`WeChat API error: ${resp.status}`);
|
|
619
|
+
const data = (await resp.json());
|
|
620
|
+
const sessionKey = `${req.params.id}-${Date.now()}`;
|
|
621
|
+
weixinLogins.set(sessionKey, {
|
|
622
|
+
instanceId: req.params.id,
|
|
623
|
+
qrcode: data.qrcode,
|
|
624
|
+
qrcodeUrl: data.qrcode_img_content,
|
|
625
|
+
startedAt: Date.now(),
|
|
626
|
+
});
|
|
627
|
+
for (const [k, v] of weixinLogins) {
|
|
628
|
+
if (Date.now() - v.startedAt > 5 * 60_000)
|
|
629
|
+
weixinLogins.delete(k);
|
|
630
|
+
}
|
|
631
|
+
while (weixinLogins.size > MAX_LOGIN_SESSIONS) {
|
|
632
|
+
weixinLogins.delete(weixinLogins.keys().next().value);
|
|
633
|
+
}
|
|
634
|
+
return { qrcodeUrl: data.qrcode_img_content, sessionKey };
|
|
635
|
+
}
|
|
636
|
+
catch (e) {
|
|
637
|
+
return reply.status(502).send({ detail: e.message || "Failed to get QR code" });
|
|
638
|
+
}
|
|
639
|
+
});
|
|
640
|
+
app.get("/api/integrations/openclaw/instances/:id/weixin/login/:sessionKey", async (req, reply) => {
|
|
641
|
+
const idErr = validateId(req.params.id);
|
|
642
|
+
if (idErr)
|
|
643
|
+
return reply.status(400).send({ detail: idErr });
|
|
644
|
+
const login = weixinLogins.get(req.params.sessionKey);
|
|
645
|
+
if (!login)
|
|
646
|
+
return reply.status(404).send({ detail: "Login session not found or expired" });
|
|
647
|
+
if (login.instanceId !== req.params.id) {
|
|
648
|
+
return reply.status(403).send({ detail: "Session belongs to a different instance" });
|
|
649
|
+
}
|
|
650
|
+
if (Date.now() - login.startedAt > 5 * 60_000) {
|
|
651
|
+
weixinLogins.delete(req.params.sessionKey);
|
|
652
|
+
return { status: "expired", connected: false, message: "QR code expired, please regenerate." };
|
|
653
|
+
}
|
|
654
|
+
try {
|
|
655
|
+
const resp = await fetch(`${WEIXIN_API_BASE}/ilink/bot/get_qrcode_status?qrcode=${encodeURIComponent(login.qrcode)}`, { headers: { "iLink-App-ClientVersion": "1" }, signal: AbortSignal.timeout(35_000) });
|
|
656
|
+
if (!resp.ok)
|
|
657
|
+
throw new Error(`Status poll failed: ${resp.status}`);
|
|
658
|
+
const data = (await resp.json());
|
|
659
|
+
if (data.status === "confirmed") {
|
|
660
|
+
// iLink occasionally returns `confirmed` with an empty payload
|
|
661
|
+
// (seen when the upstream QR session raced an internal refresh
|
|
662
|
+
// on their side). Without all four fields the runtime can't
|
|
663
|
+
// actually pair — write it anyway and the next `docker pull` of
|
|
664
|
+
// updates 401s with a cryptic "token missing" error. Reject at
|
|
665
|
+
// the route layer so the UI surfaces a clear failure instead.
|
|
666
|
+
if (!data.ilink_bot_id || !data.bot_token) {
|
|
667
|
+
console.error(`[weixin-login] iLink returned confirmed but payload incomplete: ` +
|
|
668
|
+
`bot_id=${data.ilink_bot_id ? "<present>" : "<missing>"}, ` +
|
|
669
|
+
`bot_token=${data.bot_token ? "<present>" : "<missing>"}`);
|
|
670
|
+
weixinLogins.delete(req.params.sessionKey);
|
|
671
|
+
return reply.status(502).send({
|
|
672
|
+
status: "error",
|
|
673
|
+
connected: false,
|
|
674
|
+
detail: "WeChat confirmed the scan but returned an incomplete credential payload. " +
|
|
675
|
+
"Please retry the QR login.",
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
weixinLogins.delete(req.params.sessionKey);
|
|
679
|
+
try {
|
|
680
|
+
instanceManager.saveWeixinCredentials(req.params.id, {
|
|
681
|
+
accountId: data.ilink_bot_id,
|
|
682
|
+
token: data.bot_token,
|
|
683
|
+
baseUrl: data.baseurl || WEIXIN_API_BASE,
|
|
684
|
+
userId: data.ilink_user_id || "",
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
catch (e) {
|
|
688
|
+
console.error(`[weixin-login] Failed to save credentials: ${e.message}`);
|
|
689
|
+
return reply.status(500).send({
|
|
690
|
+
status: "confirmed",
|
|
691
|
+
connected: false,
|
|
692
|
+
detail: "WeChat authenticated but failed to save credentials: " + e.message,
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
return {
|
|
696
|
+
status: "confirmed",
|
|
697
|
+
connected: true,
|
|
698
|
+
accountId: data.ilink_bot_id,
|
|
699
|
+
message: "WeChat connected!",
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
if (data.status === "expired") {
|
|
703
|
+
try {
|
|
704
|
+
const refreshResp = await fetch(`${WEIXIN_API_BASE}/ilink/bot/get_bot_qrcode?bot_type=${WEIXIN_BOT_TYPE}`, { signal: AbortSignal.timeout(30_000) });
|
|
705
|
+
if (refreshResp.ok) {
|
|
706
|
+
const refreshData = (await refreshResp.json());
|
|
707
|
+
login.qrcode = refreshData.qrcode;
|
|
708
|
+
login.qrcodeUrl = refreshData.qrcode_img_content;
|
|
709
|
+
login.startedAt = Date.now();
|
|
710
|
+
return {
|
|
711
|
+
status: "refreshed",
|
|
712
|
+
connected: false,
|
|
713
|
+
qrcodeUrl: refreshData.qrcode_img_content,
|
|
714
|
+
message: "QR code refreshed, please scan again.",
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
catch {
|
|
719
|
+
/* fall through */
|
|
720
|
+
}
|
|
721
|
+
weixinLogins.delete(req.params.sessionKey);
|
|
722
|
+
return { status: "expired", connected: false, message: "QR code expired, please regenerate." };
|
|
723
|
+
}
|
|
724
|
+
return {
|
|
725
|
+
status: data.status,
|
|
726
|
+
connected: false,
|
|
727
|
+
message: data.status === "scaned" ? "Scanned, please confirm on WeChat..." : "Waiting for scan...",
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
catch (e) {
|
|
731
|
+
return reply.status(502).send({ detail: e.message || "Status poll failed" });
|
|
732
|
+
}
|
|
733
|
+
});
|
|
734
|
+
// ── Usage (reads OpenClaw sessions.json) ──────────────────────────
|
|
735
|
+
app.get("/api/integrations/openclaw/instances/:id/usage", async (req, reply) => {
|
|
736
|
+
const idErr = validateId(req.params.id);
|
|
737
|
+
if (idErr)
|
|
738
|
+
return reply.status(400).send({ detail: idErr });
|
|
739
|
+
const inst = instanceManager.getInstance(req.params.id);
|
|
740
|
+
if (!inst)
|
|
741
|
+
return reply.status(404).send({ detail: "Instance not found" });
|
|
742
|
+
const openclawHome = resolveOpenclawHome(req.params.id);
|
|
743
|
+
const sessionsIndex = join(openclawHome, ".openclaw", "agents", "main", "sessions", "sessions.json");
|
|
744
|
+
const emptyTotals = {
|
|
745
|
+
input: 0,
|
|
746
|
+
output: 0,
|
|
747
|
+
cacheRead: 0,
|
|
748
|
+
cacheWrite: 0,
|
|
749
|
+
totalTokens: 0,
|
|
750
|
+
costTotal: 0,
|
|
751
|
+
messages: 0,
|
|
752
|
+
};
|
|
753
|
+
if (!existsSync(sessionsIndex))
|
|
754
|
+
return { sessions: [], totals: emptyTotals };
|
|
755
|
+
const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
|
|
756
|
+
const indexStat = await stat(sessionsIndex);
|
|
757
|
+
if (indexStat.size > MAX_FILE_SIZE) {
|
|
758
|
+
return reply.status(400).send({ detail: "sessions.json exceeds 10MB size limit" });
|
|
759
|
+
}
|
|
760
|
+
let sessionsMap;
|
|
761
|
+
try {
|
|
762
|
+
const raw = await readFile(sessionsIndex, "utf-8");
|
|
763
|
+
sessionsMap = JSON.parse(raw);
|
|
764
|
+
}
|
|
765
|
+
catch {
|
|
766
|
+
return reply.status(500).send({ detail: "Failed to parse sessions.json" });
|
|
767
|
+
}
|
|
768
|
+
const sessions = [];
|
|
769
|
+
const totals = { ...emptyTotals };
|
|
770
|
+
for (const [sessionKey, sessionMeta] of Object.entries(sessionsMap)) {
|
|
771
|
+
const sessionFile = sessionMeta?.sessionFile;
|
|
772
|
+
if (!sessionFile || !existsSync(sessionFile))
|
|
773
|
+
continue;
|
|
774
|
+
try {
|
|
775
|
+
const resolvedSession = realpathSync(sessionFile);
|
|
776
|
+
const resolvedHome = realpathSync(openclawHome);
|
|
777
|
+
if (!resolvedSession.startsWith(resolvedHome + "/") && resolvedSession !== resolvedHome)
|
|
778
|
+
continue;
|
|
779
|
+
}
|
|
780
|
+
catch {
|
|
781
|
+
continue;
|
|
782
|
+
}
|
|
783
|
+
let sessionStat;
|
|
784
|
+
try {
|
|
785
|
+
sessionStat = await stat(sessionFile);
|
|
786
|
+
}
|
|
787
|
+
catch {
|
|
788
|
+
continue;
|
|
789
|
+
}
|
|
790
|
+
if (sessionStat.size > MAX_FILE_SIZE)
|
|
791
|
+
continue;
|
|
792
|
+
const sessionUsage = {
|
|
793
|
+
input: 0,
|
|
794
|
+
output: 0,
|
|
795
|
+
cacheRead: 0,
|
|
796
|
+
cacheWrite: 0,
|
|
797
|
+
totalTokens: 0,
|
|
798
|
+
costTotal: 0,
|
|
799
|
+
messages: 0,
|
|
800
|
+
};
|
|
801
|
+
let model = "";
|
|
802
|
+
let firstTs = "";
|
|
803
|
+
let lastTs = "";
|
|
804
|
+
const originLabel = sessionMeta?.origin?.label || "";
|
|
805
|
+
const channel = sessionMeta?.origin?.provider || "";
|
|
806
|
+
let sessionContent;
|
|
807
|
+
try {
|
|
808
|
+
sessionContent = await readFile(sessionFile, "utf-8");
|
|
809
|
+
}
|
|
810
|
+
catch {
|
|
811
|
+
continue;
|
|
812
|
+
}
|
|
813
|
+
for (const line of sessionContent.split("\n")) {
|
|
814
|
+
let entry;
|
|
815
|
+
try {
|
|
816
|
+
entry = JSON.parse(line.trim());
|
|
817
|
+
}
|
|
818
|
+
catch {
|
|
819
|
+
continue;
|
|
820
|
+
}
|
|
821
|
+
if (entry.type !== "message")
|
|
822
|
+
continue;
|
|
823
|
+
const msg = entry.message || {};
|
|
824
|
+
const ts = entry.timestamp || "";
|
|
825
|
+
if (ts && !firstTs)
|
|
826
|
+
firstTs = ts;
|
|
827
|
+
if (ts)
|
|
828
|
+
lastTs = ts;
|
|
829
|
+
if (msg.role === "assistant") {
|
|
830
|
+
if (!model && msg.model)
|
|
831
|
+
model = msg.model;
|
|
832
|
+
const usage = msg.usage;
|
|
833
|
+
if (usage) {
|
|
834
|
+
sessionUsage.input += usage.input || 0;
|
|
835
|
+
sessionUsage.output += usage.output || 0;
|
|
836
|
+
sessionUsage.cacheRead += usage.cacheRead || 0;
|
|
837
|
+
sessionUsage.cacheWrite += usage.cacheWrite || 0;
|
|
838
|
+
sessionUsage.totalTokens += usage.totalTokens || 0;
|
|
839
|
+
if (typeof usage.cost === "object")
|
|
840
|
+
sessionUsage.costTotal += usage.cost.total || 0;
|
|
841
|
+
}
|
|
842
|
+
sessionUsage.messages++;
|
|
843
|
+
}
|
|
844
|
+
else if (msg.role === "user") {
|
|
845
|
+
sessionUsage.messages++;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
sessions.push({
|
|
849
|
+
key: sessionKey,
|
|
850
|
+
model,
|
|
851
|
+
channel,
|
|
852
|
+
origin: originLabel,
|
|
853
|
+
firstMessage: firstTs,
|
|
854
|
+
lastMessage: lastTs,
|
|
855
|
+
usage: sessionUsage,
|
|
856
|
+
});
|
|
857
|
+
for (const k of ["input", "output", "cacheRead", "cacheWrite", "totalTokens", "messages"]) {
|
|
858
|
+
totals[k] += sessionUsage[k];
|
|
859
|
+
}
|
|
860
|
+
totals.costTotal += sessionUsage.costTotal;
|
|
861
|
+
}
|
|
862
|
+
sessions.sort((a, b) => (b.lastMessage || "").localeCompare(a.lastMessage || ""));
|
|
863
|
+
return { sessions, totals };
|
|
864
|
+
});
|
|
865
|
+
// ── Control UI launch (OpenClaw iframe boot) ──────────────
|
|
866
|
+
app.get("/api/integrations/openclaw/instances/:id/control-ui/launch", async (req, reply) => {
|
|
867
|
+
const idErr = validateId(req.params.id);
|
|
868
|
+
if (idErr)
|
|
869
|
+
return reply.status(400).send({ detail: idErr });
|
|
870
|
+
const inst = instanceManager.getInstance(req.params.id);
|
|
871
|
+
if (!inst)
|
|
872
|
+
return reply.status(404).send({ detail: "Instance not found" });
|
|
873
|
+
if (!(await supportsChatPanelUi(req.params.id, inst))) {
|
|
874
|
+
return reply
|
|
875
|
+
.status(501)
|
|
876
|
+
.send({ detail: "Control UI chat panel is not supported for this runtime" });
|
|
877
|
+
}
|
|
878
|
+
const panelOrigin = inferRequestOrigin(req);
|
|
879
|
+
let controlUiOriginAdded = false;
|
|
880
|
+
if (panelOrigin) {
|
|
881
|
+
try {
|
|
882
|
+
controlUiOriginAdded = await ensureOpenclawControlUiAllowedOrigin(req.params.id, panelOrigin);
|
|
883
|
+
if (controlUiOriginAdded) {
|
|
884
|
+
console.log(`[openclaw-control-ui-launch] added allowed origin for ${req.params.id} origin=${panelOrigin}; restart required if already running`);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
catch (err) {
|
|
888
|
+
console.warn(`[openclaw-control-ui-launch] failed to add allowed origin for ${req.params.id}:`, err.message || err);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
const baseUrl = `/api/integrations/openclaw/instances/${req.params.id}/control-ui/`;
|
|
892
|
+
const cfg = instanceManager.getStoredConfig(req.params.id);
|
|
893
|
+
const token = cfg?.gateway?.auth?.token;
|
|
894
|
+
const payload = { url: baseUrl };
|
|
895
|
+
if (controlUiOriginAdded)
|
|
896
|
+
payload.controlUiOriginAdded = true;
|
|
897
|
+
if (controlUiOriginAdded)
|
|
898
|
+
payload.restartRequired = true;
|
|
899
|
+
if (typeof token !== "string" || !token.trim()) {
|
|
900
|
+
return payload;
|
|
901
|
+
}
|
|
902
|
+
payload.url = `${baseUrl}#token=${encodeURIComponent(token.trim())}`;
|
|
903
|
+
return payload;
|
|
904
|
+
});
|
|
905
|
+
// ── Control UI HTTP proxy (with HTML injection) ───────────
|
|
906
|
+
const controlUiProxy = async (request, reply) => {
|
|
907
|
+
const { id } = request.params;
|
|
908
|
+
const idErr = validateId(id);
|
|
909
|
+
if (idErr)
|
|
910
|
+
return reply.status(400).send({ detail: idErr });
|
|
911
|
+
const inst = instanceManager.getInstance(id);
|
|
912
|
+
if (!inst)
|
|
913
|
+
return reply.status(404).send({ detail: "Instance not found" });
|
|
914
|
+
if (!(await supportsChatPanelUi(id, inst))) {
|
|
915
|
+
return reply.status(501).send({ detail: "Control UI proxy is not supported for this runtime" });
|
|
916
|
+
}
|
|
917
|
+
let port = 0;
|
|
918
|
+
let gwHost = "127.0.0.1";
|
|
919
|
+
try {
|
|
920
|
+
port = instanceManager.getPrimaryHostPort(id);
|
|
921
|
+
gwHost = await instanceManager.getPrimaryHostForInstance(id);
|
|
922
|
+
}
|
|
923
|
+
catch (error) {
|
|
924
|
+
if (instanceManager.isCanonicalRuntimePortRequiredError(error)) {
|
|
925
|
+
return reply.status(error.statusCode || 409).send({ detail: error.message, code: error.code });
|
|
926
|
+
}
|
|
927
|
+
throw error;
|
|
928
|
+
}
|
|
929
|
+
const suffix = request.params["*"] || "";
|
|
930
|
+
const qs = request.url.includes("?") ? request.url.slice(request.url.indexOf("?")) : "";
|
|
931
|
+
const urlGwHost = instanceManager.urlHost(gwHost);
|
|
932
|
+
const targetUrl = `http://${urlGwHost}:${port}/${suffix}${qs}`;
|
|
933
|
+
try {
|
|
934
|
+
const fwdHeaders = {};
|
|
935
|
+
const rawHeaders = request.raw.headers;
|
|
936
|
+
for (const [k, v] of Object.entries(rawHeaders)) {
|
|
937
|
+
if (v === undefined)
|
|
938
|
+
continue;
|
|
939
|
+
const lk = k.toLowerCase();
|
|
940
|
+
if (HOP_BY_HOP.has(lk) ||
|
|
941
|
+
PROXY_IDENTITY_HEADERS.has(lk) ||
|
|
942
|
+
lk === "host" ||
|
|
943
|
+
lk === "cookie" ||
|
|
944
|
+
lk === "authorization")
|
|
945
|
+
continue;
|
|
946
|
+
fwdHeaders[k] = Array.isArray(v) ? v.join(", ") : v;
|
|
947
|
+
}
|
|
948
|
+
fwdHeaders["host"] = `${urlGwHost}:${port}`;
|
|
949
|
+
// Forward the browser's real Origin/Referer. OpenClaw validates the
|
|
950
|
+
// control UI against gateway.controlUi.allowedOrigins, which Core
|
|
951
|
+
// prepares before explicit lifecycle start/restart and best-effort in
|
|
952
|
+
// control-ui launch without hidden lifecycle actions.
|
|
953
|
+
fwdHeaders["accept-encoding"] = "identity";
|
|
954
|
+
// Inject the per-instance gateway auth token so plain HTTP requests
|
|
955
|
+
// from the iframe (notably `<img src="/api/chat/media/...">` for
|
|
956
|
+
// server-emitted screenshot/upload URLs) authenticate against
|
|
957
|
+
// OpenClaw. The browser-supplied Authorization/Cookie are stripped
|
|
958
|
+
// above to avoid leaking panel auth into OpenClaw; without this
|
|
959
|
+
// injection chat-embedded media renders as 401 broken-image.
|
|
960
|
+
// The token is per-instance and only valid for this gateway, so
|
|
961
|
+
// attaching it on every proxied request is safe.
|
|
962
|
+
try {
|
|
963
|
+
const cfg = instanceManager.getStoredConfig(id);
|
|
964
|
+
const token = cfg?.gateway?.auth?.token;
|
|
965
|
+
if (typeof token === "string" && token.trim()) {
|
|
966
|
+
fwdHeaders["authorization"] = `Bearer ${token.trim()}`;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
catch { /* best-effort: a missing config means no auth, request will get the same 401 it does today */ }
|
|
970
|
+
const upstreamRes = await new Promise((resolve, reject) => {
|
|
971
|
+
const proxyReq = httpRequest(targetUrl, { method: request.method, headers: fwdHeaders }, resolve);
|
|
972
|
+
proxyReq.on("error", reject);
|
|
973
|
+
if (request.method !== "GET" && request.method !== "HEAD") {
|
|
974
|
+
request.raw.pipe(proxyReq);
|
|
975
|
+
}
|
|
976
|
+
else {
|
|
977
|
+
proxyReq.end();
|
|
978
|
+
}
|
|
979
|
+
});
|
|
980
|
+
reply.status(upstreamRes.statusCode || 502);
|
|
981
|
+
for (const [k, v] of Object.entries(upstreamRes.headers)) {
|
|
982
|
+
if (v === undefined)
|
|
983
|
+
continue;
|
|
984
|
+
const lk = k.toLowerCase();
|
|
985
|
+
if (HOP_BY_HOP.has(lk))
|
|
986
|
+
continue;
|
|
987
|
+
if (lk === "x-frame-options") {
|
|
988
|
+
reply.header("x-frame-options", "SAMEORIGIN");
|
|
989
|
+
continue;
|
|
990
|
+
}
|
|
991
|
+
if (lk === "content-security-policy") {
|
|
992
|
+
const csp = Array.isArray(v) ? v.join(", ") : v;
|
|
993
|
+
const rewritten = csp.replace(/frame-ancestors\s+[^;]*/i, "frame-ancestors 'self'");
|
|
994
|
+
reply.header("content-security-policy", rewritten === csp ? `${csp}; frame-ancestors 'self'` : rewritten);
|
|
995
|
+
continue;
|
|
996
|
+
}
|
|
997
|
+
reply.header(k, Array.isArray(v) ? v.join(", ") : v);
|
|
998
|
+
}
|
|
999
|
+
const respCt = upstreamRes.headers["content-type"] || "";
|
|
1000
|
+
if (suffix === "__openclaw/control-ui-config.json" && respCt.includes("application/json")) {
|
|
1001
|
+
const chunks = [];
|
|
1002
|
+
for await (const chunk of upstreamRes)
|
|
1003
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
1004
|
+
try {
|
|
1005
|
+
const config = JSON.parse(Buffer.concat(chunks).toString("utf-8"));
|
|
1006
|
+
config.basePath = `/api/integrations/openclaw/instances/${id}/control-ui`;
|
|
1007
|
+
const buf = Buffer.from(JSON.stringify(config));
|
|
1008
|
+
reply.header("content-length", buf.length);
|
|
1009
|
+
reply.removeHeader("content-encoding");
|
|
1010
|
+
return reply.send(buf);
|
|
1011
|
+
}
|
|
1012
|
+
catch {
|
|
1013
|
+
/* fall through to stream */
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
if (respCt.includes("text/html")) {
|
|
1017
|
+
const chunks = [];
|
|
1018
|
+
for await (const chunk of upstreamRes)
|
|
1019
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
1020
|
+
let html = Buffer.concat(chunks).toString("utf-8");
|
|
1021
|
+
const basePath = `/api/integrations/openclaw/instances/${id}/control-ui`;
|
|
1022
|
+
const injectScript = [
|
|
1023
|
+
`window.__OPENCLAW_CONTROL_UI_BASE_PATH__=${JSON.stringify(basePath)};`,
|
|
1024
|
+
`(()=>{`,
|
|
1025
|
+
` try {`,
|
|
1026
|
+
` const settingsKey='openclaw.control.settings.v1';`,
|
|
1027
|
+
` const tokenStoragePrefix='openclaw.control.token.v1:';`,
|
|
1028
|
+
` const normalizeGatewayScope=(gatewayUrl)=>{`,
|
|
1029
|
+
` const raw=(gatewayUrl||'').trim();`,
|
|
1030
|
+
` if(!raw) return 'default';`,
|
|
1031
|
+
` try {`,
|
|
1032
|
+
` const base=\`\${window.location.protocol}//\${window.location.host}\${window.location.pathname||'/'}\`;`,
|
|
1033
|
+
` const parsed=new URL(raw, base);`,
|
|
1034
|
+
` const pathname=parsed.pathname==='/'?'':(parsed.pathname.replace(/\\/+$/,'')||parsed.pathname);`,
|
|
1035
|
+
` return \`\${parsed.protocol}//\${parsed.host}\${pathname}\`;`,
|
|
1036
|
+
` } catch {`,
|
|
1037
|
+
` return raw;`,
|
|
1038
|
+
` }`,
|
|
1039
|
+
` };`,
|
|
1040
|
+
` const proto=window.location.protocol==='https:'?'wss':'ws';`,
|
|
1041
|
+
` const gatewayUrl=\`\${proto}://\${window.location.host}${basePath}\`;`,
|
|
1042
|
+
` const tokenSessionKey=\`\${tokenStoragePrefix}\${normalizeGatewayScope(gatewayUrl)}\`;`,
|
|
1043
|
+
` const raw=window.localStorage.getItem(settingsKey);`,
|
|
1044
|
+
` let next={};`,
|
|
1045
|
+
` try { next=raw ? JSON.parse(raw) : {}; } catch { next={}; }`,
|
|
1046
|
+
` next.gatewayUrl=gatewayUrl;`,
|
|
1047
|
+
` if('token' in next) delete next.token;`,
|
|
1048
|
+
` const hashParams=new URLSearchParams(window.location.hash.startsWith('#')?window.location.hash.slice(1):window.location.hash);`,
|
|
1049
|
+
` const searchParams=new URLSearchParams(window.location.search);`,
|
|
1050
|
+
` const launchToken=(hashParams.get('token')||searchParams.get('token')||'').trim();`,
|
|
1051
|
+
` if(launchToken){`,
|
|
1052
|
+
` window.sessionStorage.setItem(tokenSessionKey, launchToken);`,
|
|
1053
|
+
` }`,
|
|
1054
|
+
` window.localStorage.setItem(settingsKey, JSON.stringify(next));`,
|
|
1055
|
+
` const autoConnect=()=>{`,
|
|
1056
|
+
` const attempt=()=>{`,
|
|
1057
|
+
` const app=document.querySelector('openclaw-app');`,
|
|
1058
|
+
` if(!app||typeof app.connect!=='function'||typeof app.applySettings!=='function'||!app.settings||typeof app.settings!=='object') return false;`,
|
|
1059
|
+
` const sessionToken=(window.sessionStorage.getItem(tokenSessionKey)||'').trim();`,
|
|
1060
|
+
` const token=(sessionToken||launchToken||app.settings.token||'').trim();`,
|
|
1061
|
+
` if(!token) return false;`,
|
|
1062
|
+
` const nextSettings={...app.settings, gatewayUrl, token};`,
|
|
1063
|
+
` if(nextSettings.gatewayUrl!==app.settings.gatewayUrl||nextSettings.token!==app.settings.token){`,
|
|
1064
|
+
` app.applySettings(nextSettings);`,
|
|
1065
|
+
` }`,
|
|
1066
|
+
` if(app.connected) return true;`,
|
|
1067
|
+
` const wsState=app.client&&app.client.ws?app.client.ws.readyState:null;`,
|
|
1068
|
+
` const connecting=wsState===0||wsState===1;`,
|
|
1069
|
+
` if(!connecting){`,
|
|
1070
|
+
` window.setTimeout(()=>{`,
|
|
1071
|
+
` try { if(!app.connected) app.connect(); } catch {}`,
|
|
1072
|
+
` }, 0);`,
|
|
1073
|
+
` }`,
|
|
1074
|
+
` return false;`,
|
|
1075
|
+
` };`,
|
|
1076
|
+
` const start=()=>{`,
|
|
1077
|
+
` let tries=0;`,
|
|
1078
|
+
` let timer=0;`,
|
|
1079
|
+
` const tick=()=>{`,
|
|
1080
|
+
` tries+=1;`,
|
|
1081
|
+
` if(attempt()||tries>=120){`,
|
|
1082
|
+
` window.clearInterval(timer);`,
|
|
1083
|
+
` }`,
|
|
1084
|
+
` };`,
|
|
1085
|
+
` tick();`,
|
|
1086
|
+
` timer=window.setInterval(()=>{`,
|
|
1087
|
+
` tick();`,
|
|
1088
|
+
` },500);`,
|
|
1089
|
+
` };`,
|
|
1090
|
+
` if(window.customElements&&typeof window.customElements.whenDefined==='function'){`,
|
|
1091
|
+
` window.customElements.whenDefined('openclaw-app').then(start).catch(()=>{});`,
|
|
1092
|
+
` }else{`,
|
|
1093
|
+
` start();`,
|
|
1094
|
+
` }`,
|
|
1095
|
+
` };`,
|
|
1096
|
+
` autoConnect();`,
|
|
1097
|
+
` } catch {}`,
|
|
1098
|
+
`})();`,
|
|
1099
|
+
].join("");
|
|
1100
|
+
const inject = `<script>${injectScript}</script>`;
|
|
1101
|
+
const injectCmdScript = [
|
|
1102
|
+
`(function(){`,
|
|
1103
|
+
` var _jishuInject=function(cmd,send){`,
|
|
1104
|
+
` var app=document.querySelector('openclaw-app');`,
|
|
1105
|
+
` if(!app)return false;`,
|
|
1106
|
+
` if(send){`,
|
|
1107
|
+
` if(!app.connected)return false;`,
|
|
1108
|
+
` try{app.handleSendChat(cmd);return true;}catch(e){}`,
|
|
1109
|
+
` return false;`,
|
|
1110
|
+
` }else{`,
|
|
1111
|
+
` try{app.chatMessage=cmd;return true;}catch(e){}`,
|
|
1112
|
+
` return false;`,
|
|
1113
|
+
` }`,
|
|
1114
|
+
` };`,
|
|
1115
|
+
` window.addEventListener('message',function(e){`,
|
|
1116
|
+
` if(!e.data||e.data.type!=='jishu:inject-cmd')return;`,
|
|
1117
|
+
` var cmd=e.data.cmd,send=!!e.data.send,tries=0;`,
|
|
1118
|
+
` var poll=function(){if(_jishuInject(cmd,send)||++tries>=50)return;setTimeout(poll,200);};`,
|
|
1119
|
+
` poll();`,
|
|
1120
|
+
` },false);`,
|
|
1121
|
+
`})();`,
|
|
1122
|
+
].join("");
|
|
1123
|
+
const injectCmdScriptHash = createHash("sha256").update(injectCmdScript, "utf8").digest("base64");
|
|
1124
|
+
const fullHtmlInject = `${inject}<script>${injectCmdScript}</script>`;
|
|
1125
|
+
html = html.replace(/<head\b[^>]*>/i, (match) => `${match}${fullHtmlInject}`);
|
|
1126
|
+
const inlineScriptHash = createHash("sha256").update(injectScript, "utf8").digest("base64");
|
|
1127
|
+
const cspHeader = reply.getHeader("content-security-policy");
|
|
1128
|
+
if (typeof cspHeader === "string" && cspHeader) {
|
|
1129
|
+
const hashToken = `'sha256-${inlineScriptHash}'`;
|
|
1130
|
+
const hashToken2 = `'sha256-${injectCmdScriptHash}'`;
|
|
1131
|
+
const addHashes = (src) => {
|
|
1132
|
+
let s = src;
|
|
1133
|
+
if (!s.includes(hashToken))
|
|
1134
|
+
s = s + ` ${hashToken}`;
|
|
1135
|
+
if (!s.includes(hashToken2))
|
|
1136
|
+
s = s + ` ${hashToken2}`;
|
|
1137
|
+
return s;
|
|
1138
|
+
};
|
|
1139
|
+
const nextCsp = /\bscript-src\b/i.test(cspHeader)
|
|
1140
|
+
? cspHeader.replace(/\bscript-src\b([^;]*)/i, (_m, value) => `script-src${addHashes(value)}`)
|
|
1141
|
+
: `${cspHeader}; script-src 'self' ${hashToken} ${hashToken2}`;
|
|
1142
|
+
reply.header("content-security-policy", nextCsp);
|
|
1143
|
+
}
|
|
1144
|
+
const buf = Buffer.from(html, "utf-8");
|
|
1145
|
+
reply.header("cache-control", "no-store");
|
|
1146
|
+
reply.header("content-length", buf.length);
|
|
1147
|
+
reply.removeHeader("content-encoding");
|
|
1148
|
+
return reply.send(buf);
|
|
1149
|
+
}
|
|
1150
|
+
return reply.send(upstreamRes);
|
|
1151
|
+
}
|
|
1152
|
+
catch (err) {
|
|
1153
|
+
console.error(`[openclaw-control-ui-proxy] ${id}:`, err.message || err);
|
|
1154
|
+
return reply.status(502).send({ detail: "Cannot reach OpenClaw control UI" });
|
|
1155
|
+
}
|
|
1156
|
+
};
|
|
1157
|
+
app.all("/api/integrations/openclaw/instances/:id/control-ui/*", controlUiProxy);
|
|
1158
|
+
app.all("/api/integrations/openclaw/instances/:id/control-ui", controlUiProxy);
|
|
1159
|
+
// ── Referer-forwarded control UI proxy for OpenClaw internal URLs ─
|
|
1160
|
+
//
|
|
1161
|
+
// Some OpenClaw chat messages embed server-generated absolute URLs that
|
|
1162
|
+
// ignore `gateway.basePath` (e.g. screenshot/upload media references emitted
|
|
1163
|
+
// as `{type:"image", url:"/api/chat/media/outgoing/..."}` — `basePath` is
|
|
1164
|
+
// the client-side override for outgoing requests, but server-rendered
|
|
1165
|
+
// message URLs are baked at emit time without it). Inside the iframe the
|
|
1166
|
+
// browser resolves those against the panel origin and they land here on
|
|
1167
|
+
// jishushell instead of the instance's gateway.
|
|
1168
|
+
//
|
|
1169
|
+
// Handle this by recovering the instance id from the iframe Referer
|
|
1170
|
+
// (`/api/integrations/openclaw/instances/<id>/control-ui/...`) and replaying the request through
|
|
1171
|
+
// controlUiProxy. Limited to a narrow allowlist of OpenClaw-owned prefixes
|
|
1172
|
+
// to avoid colliding with jishushell's own routes.
|
|
1173
|
+
const refererForwardedProxy = async (request, reply) => {
|
|
1174
|
+
const id = extractRefererInstanceId(request.headers.referer);
|
|
1175
|
+
if (!id)
|
|
1176
|
+
return reply.status(404).send({ detail: "Not found" });
|
|
1177
|
+
const idErr = validateId(id);
|
|
1178
|
+
if (idErr)
|
|
1179
|
+
return reply.status(400).send({ detail: idErr });
|
|
1180
|
+
const path = String(request.url ?? "").split("?")[0];
|
|
1181
|
+
const suffix = path.replace(/^\/+/, "");
|
|
1182
|
+
Object.assign(request.params, { id, "*": suffix });
|
|
1183
|
+
return controlUiProxy(request, reply);
|
|
1184
|
+
};
|
|
1185
|
+
// /api/chat/* covers the screenshot/upload media that the runtime emits
|
|
1186
|
+
// as message-embedded absolute URLs. Add other OpenClaw-internal prefixes
|
|
1187
|
+
// here as they surface — keep the list narrow so jishushell-owned routes
|
|
1188
|
+
// (auth/instances/system/setup) stay unambiguous.
|
|
1189
|
+
app.all("/api/chat/*", refererForwardedProxy);
|
|
1190
|
+
}
|
|
1191
|
+
//# sourceMappingURL=routes.js.map
|