@xopcai/xopc 0.0.89 → 0.0.90
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/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/feishu/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/src/plugin.js +1 -1
- package/dist/extensions/telegram/src/routing-integration.js +2 -2
- package/dist/extensions/telegram/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/api/api.js +2 -2
- package/dist/extensions/weixin/src/auth/accounts.js +1 -1
- package/dist/extensions/weixin/src/cdn/upload.js +1 -1
- package/dist/extensions/weixin/src/media/data-url.js +1 -1
- package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
- package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.js +1 -1
- package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js +1 -1
- package/dist/gateway/static/root/assets/agents-cPvvYLXo.js +222 -0
- package/dist/gateway/static/root/assets/apps-page-Bk1_P5FJ.js +1 -0
- package/dist/gateway/static/root/assets/channels-settings-CZoeQwHz.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-DaHGkRF1.js → channels-status-swr-BrtH2VzC.js} +1 -1
- package/dist/gateway/static/root/assets/circle-check-C23XjkUj.js +1 -0
- package/dist/gateway/static/root/assets/cron-api-CyqbgfHM.js +1 -0
- package/dist/gateway/static/root/assets/cron-dreaming-jobs-Ip703-qM.js +2 -0
- package/dist/gateway/static/root/assets/cron-page-BpLdiQN8.js +1 -0
- package/dist/gateway/static/root/assets/dist-BpAiK86n.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-CtuKJ9tE.js → extension-debug-page-D6Ak0STa.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-ykzjOkR5.js → extension-page-Q0P3d6DW.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-Ce2qrdpO.js → extension-settings-page-CL55LwU_.js} +1 -1
- package/dist/gateway/static/root/assets/eye-DAfL1U7M.js +1 -0
- package/dist/gateway/static/root/assets/{fetch-C9FFJjuH.js → fetch-Dqa9iTWl.js} +1 -1
- package/dist/gateway/static/root/assets/{field-primitives-BFcrNeTU.js → field-primitives-HUR6JElP.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-CEg4Vr9R.js → heartbeat-config-api-DusckjUX.js} +1 -1
- package/dist/gateway/static/root/assets/{index-CZfy9oxs.js → index-BYcGfwcE.js} +97 -97
- package/dist/gateway/static/root/assets/index-V7MQ7834.css +1 -0
- package/dist/gateway/static/root/assets/logs-page-_HcZ2fgK.js +1 -0
- package/dist/gateway/static/root/assets/sessions-page-iezSMjho.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-BqdzA28u.js → settings-form-section-a0qGVOlr.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-C9_nYQwM.js +3 -0
- package/dist/gateway/static/root/assets/{share-preview-page-Di5Bzh4g.js → share-preview-page-DExl7CJy.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page-BlgGD93t.js +2 -0
- package/dist/gateway/static/root/assets/{theme-store-CNqbmTNV.js → theme-store-C0Ehmdo5.js} +1 -1
- package/dist/gateway/static/root/assets/url-fxyYANfA.js +3 -0
- package/dist/gateway/static/root/assets/{utils-BWm2tG2w.js → utils-DRQryzdn.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-D0viACE2.js +1 -0
- package/dist/gateway/static/root/assets/workflow-page.utils-DnG8JBhV.js +1 -0
- package/dist/gateway/static/root/assets/workflows-page-BvMobnJP.js +27 -0
- package/dist/gateway/static/root/index.html +7 -5
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.js +7 -7
- package/dist/src/agent/agent-scope.js +1 -1
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
- package/dist/src/agent/context/workspace-seed.js +2 -2
- package/dist/src/agent/goals/goal-run-store.js +4 -4
- package/dist/src/agent/goals/persistent-goal-service.js +1 -1
- package/dist/src/agent/goals/post-turn.js +2 -2
- package/dist/src/agent/image/load-image-media.js +2 -2
- package/dist/src/agent/ipc/bus.js +1 -1
- package/dist/src/agent/ipc/inbox.js +2 -2
- package/dist/src/agent/ipc/socket.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
- package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
- package/dist/src/agent/mcp/mcp-transport.js +1 -1
- package/dist/src/agent/memory/builtin-memory-store.js +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
- package/dist/src/agent/memory/dreaming/events.js +1 -1
- package/dist/src/agent/memory/dreaming/last-run.js +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
- package/dist/src/agent/memory/dreaming/preview.js +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/memory/plugin-discovery.js +1 -1
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
- package/dist/src/agent/reply/post-compaction-context.js +1 -1
- package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
- package/dist/src/agent/sandbox/path-policy.js +2 -2
- package/dist/src/agent/service/build-direct-message-content.js +1 -1
- package/dist/src/agent/service.js +4 -4
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/config.js +1 -1
- package/dist/src/agent/skills/hub-hash.js +2 -2
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +2 -2
- package/dist/src/agent/skills/index.js +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js +20 -18
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js.map +1 -1
- package/dist/src/agent/skills/scanner.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/skills/skill-manager.js +1 -1
- package/dist/src/agent/tools/cronjob-tool.d.ts +6 -0
- package/dist/src/agent/tools/cronjob-tool.js +74 -9
- package/dist/src/agent/tools/cronjob-tool.js.map +1 -1
- package/dist/src/agent/tools/dreaming-tool.js +1 -1
- package/dist/src/agent/tools/edit.d.ts +5 -1
- package/dist/src/agent/tools/edit.js +7 -5
- package/dist/src/agent/tools/edit.js.map +1 -1
- package/dist/src/agent/tools/factory.js +3 -3
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +1 -1
- package/dist/src/agent/tools/send-media.js +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js +1 -1
- package/dist/src/agent/tools/workflow-tool.js +1 -1
- package/dist/src/agent/tools/write.d.ts +5 -1
- package/dist/src/agent/tools/write.js +8 -6
- package/dist/src/agent/tools/write.js.map +1 -1
- package/dist/src/agent/workflow/agent-progress.js +2 -0
- package/dist/src/agent/workflow/agent-progress.js.map +1 -1
- package/dist/src/agent/workflow/builtins/client-proposal.d.ts +12 -0
- package/dist/src/agent/workflow/builtins/client-proposal.js +155 -0
- package/dist/src/agent/workflow/builtins/client-proposal.js.map +1 -0
- package/dist/src/agent/workflow/builtins/competitor-scan.d.ts +12 -0
- package/dist/src/agent/workflow/builtins/competitor-scan.js +150 -0
- package/dist/src/agent/workflow/builtins/competitor-scan.js.map +1 -0
- package/dist/src/agent/workflow/builtins/content-draft.d.ts +13 -0
- package/dist/src/agent/workflow/builtins/content-draft.js +146 -0
- package/dist/src/agent/workflow/builtins/content-draft.js.map +1 -0
- package/dist/src/agent/workflow/builtins/content-repurpose.d.ts +11 -0
- package/dist/src/agent/workflow/builtins/content-repurpose.js +137 -0
- package/dist/src/agent/workflow/builtins/content-repurpose.js.map +1 -0
- package/dist/src/agent/workflow/builtins/decision-compare.d.ts +13 -0
- package/dist/src/agent/workflow/builtins/decision-compare.js +173 -0
- package/dist/src/agent/workflow/builtins/decision-compare.js.map +1 -0
- package/dist/src/agent/workflow/builtins/inbox-triage.d.ts +11 -0
- package/dist/src/agent/workflow/builtins/inbox-triage.js +148 -0
- package/dist/src/agent/workflow/builtins/inbox-triage.js.map +1 -0
- package/dist/src/agent/workflow/builtins/index.d.ts +10 -1
- package/dist/src/agent/workflow/builtins/index.js +46 -1
- package/dist/src/agent/workflow/builtins/index.js.map +1 -1
- package/dist/src/agent/workflow/builtins/meeting-prep.d.ts +12 -0
- package/dist/src/agent/workflow/builtins/meeting-prep.js +144 -0
- package/dist/src/agent/workflow/builtins/meeting-prep.js.map +1 -0
- package/dist/src/agent/workflow/builtins/offer-design.d.ts +12 -0
- package/dist/src/agent/workflow/builtins/offer-design.js +161 -0
- package/dist/src/agent/workflow/builtins/offer-design.js.map +1 -0
- package/dist/src/agent/workflow/builtins/weekly-review.d.ts +12 -0
- package/dist/src/agent/workflow/builtins/weekly-review.js +131 -0
- package/dist/src/agent/workflow/builtins/weekly-review.js.map +1 -0
- package/dist/src/agent/workflow/catalog.js +1 -1
- package/dist/src/agent/workflow/step-labels.js +2 -2
- package/dist/src/agent/workflow/step-labels.js.map +1 -1
- package/dist/src/agent/workflow/subagent-runner.js +3 -1
- package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
- package/dist/src/agent/workflow/types.d.ts +4 -0
- package/dist/src/auth/credentials.js +3 -3
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/browser/cache-dir-policy.js +1 -1
- package/dist/src/browser/cdp-local-launcher.js +2 -2
- package/dist/src/browser/providers/browser-ext-install.js +3 -3
- package/dist/src/browser/providers/cloakbrowser.js +4 -4
- package/dist/src/browser/providers/playwright-doctor.js +1 -1
- package/dist/src/browser/stealth.js +1 -1
- package/dist/src/channels/attachments/inbound-persist.js +1 -1
- package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
- package/dist/src/channels/outbound/persist-store.js +1 -1
- package/dist/src/channels/pairing/allow-from-file.js +1 -1
- package/dist/src/channels/pairing/pairing-store.js +2 -2
- package/dist/src/chat-commands/agent-edit.d.ts +4 -0
- package/dist/src/chat-commands/agent-edit.js +136 -0
- package/dist/src/chat-commands/agent-edit.js.map +1 -0
- package/dist/src/chat-commands/builtins/config.js +2 -2
- package/dist/src/chat-commands/context.js +1 -1
- package/dist/src/chat-commands/index.d.ts +1 -0
- package/dist/src/chat-commands/index.js +3 -1
- package/dist/src/chat-commands/index.js.map +1 -1
- package/dist/src/cli/bin.js +2 -0
- package/dist/src/cli/bin.js.map +1 -1
- package/dist/src/cli/commands/config.js +1 -1
- package/dist/src/cli/commands/cron.js +42 -3
- package/dist/src/cli/commands/cron.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/session-integrity.js +79 -56
- package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
- package/dist/src/cli/commands/extension-dev.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/extension-pack.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/cli/commands/gateway/logs.js +1 -1
- package/dist/src/cli/commands/image.js +1 -1
- package/dist/src/cli/commands/init.js +4 -4
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/commands/update.js +86 -79
- package/dist/src/cli/commands/update.js.map +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -2
- package/dist/src/commands/agents.config.d.ts +3 -2
- package/dist/src/commands/agents.config.js +5 -2
- package/dist/src/commands/agents.config.js.map +1 -1
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/agent-typed-models.d.ts +2 -7
- package/dist/src/config/agent-typed-models.js +3 -14
- package/dist/src/config/agent-typed-models.js.map +1 -1
- package/dist/src/config/gateway-bind.js +1 -1
- package/dist/src/config/index.js +5 -5
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/localized-text.d.ts +6 -0
- package/dist/src/config/localized-text.js +42 -0
- package/dist/src/config/localized-text.js.map +1 -0
- package/dist/src/config/models-json.d.ts +6 -6
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/paths-state.js +1 -1
- package/dist/src/config/profile.js +2 -2
- package/dist/src/config/schema.d.ts +6 -21
- package/dist/src/config/schema.js +4 -4
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/workspace-path.js +1 -1
- package/dist/src/cron/executor.d.ts +2 -0
- package/dist/src/cron/executor.js +113 -3
- package/dist/src/cron/executor.js.map +1 -1
- package/dist/src/cron/persistence.js +1 -1
- package/dist/src/cron/run-log-store.js +1 -1
- package/dist/src/cron/types.d.ts +8 -1
- package/dist/src/cron/validation.d.ts +4 -0
- package/dist/src/cron/validation.js +4 -3
- package/dist/src/cron/validation.js.map +1 -1
- package/dist/src/cron/workflow-run-completion.d.ts +23 -0
- package/dist/src/cron/workflow-run-completion.js +72 -0
- package/dist/src/cron/workflow-run-completion.js.map +1 -0
- package/dist/src/daemon/constants.js +1 -1
- package/dist/src/daemon/install-plan.js +2 -2
- package/dist/src/daemon/launchd.js +2 -2
- package/dist/src/daemon/schtasks.js +2 -2
- package/dist/src/daemon/systemd.js +2 -2
- package/dist/src/extensions/bundle-mcp.js +1 -1
- package/dist/src/extensions/discover-extensions.js +1 -1
- package/dist/src/extensions/health.js +1 -1
- package/dist/src/extensions/loader.js +1 -1
- package/dist/src/extensions/lockfile.js +2 -2
- package/dist/src/extensions/update.d.ts +51 -0
- package/dist/src/extensions/update.js +260 -0
- package/dist/src/extensions/update.js.map +1 -0
- package/dist/src/gateway/agents-admin.d.ts +15 -8
- package/dist/src/gateway/agents-admin.js +78 -29
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/file-path-classifier.js +2 -2
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +5 -0
- package/dist/src/gateway/hono/lib/config-payload.js +3 -2
- package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +2 -2
- package/dist/src/gateway/hono/lib/static-ui.js +2 -2
- package/dist/src/gateway/hono/middleware/auth.d.ts +2 -0
- package/dist/src/gateway/hono/middleware/auth.js +12 -7
- package/dist/src/gateway/hono/middleware/auth.js.map +1 -1
- package/dist/src/gateway/hono/oauth.js +1 -1
- package/dist/src/gateway/hono/routes/agents.js +56 -13
- package/dist/src/gateway/hono/routes/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/agents.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +1 -1
- package/dist/src/gateway/hono/routes/host-fs.js +2 -2
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/shares.js +1 -1
- package/dist/src/gateway/hono/routes/update.js +55 -107
- package/dist/src/gateway/hono/routes/update.js.map +1 -1
- package/dist/src/gateway/hono/routes/workflows.js +3 -1
- package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +4 -4
- package/dist/src/gateway/lock.js +3 -3
- package/dist/src/gateway/ports.js +1 -1
- package/dist/src/gateway/server.js +2 -0
- package/dist/src/gateway/server.js.map +1 -1
- package/dist/src/gateway/service/agent-runner.js +2 -2
- package/dist/src/gateway/service/marketplace-service.js +2 -2
- package/dist/src/gateway/service.js +3 -2
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/workspace-fs-file-list.js +1 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/infra/brew.d.ts +4 -0
- package/dist/src/infra/brew.js +20 -0
- package/dist/src/infra/brew.js.map +1 -0
- package/dist/src/infra/package-json.d.ts +2 -0
- package/dist/src/infra/package-json.js +23 -0
- package/dist/src/infra/package-json.js.map +1 -0
- package/dist/src/infra/package-update-steps.d.ts +35 -0
- package/dist/src/infra/package-update-steps.js +304 -0
- package/dist/src/infra/package-update-steps.js.map +1 -0
- package/dist/src/infra/path-env.d.ts +11 -0
- package/dist/src/infra/path-env.js +90 -0
- package/dist/src/infra/path-env.js.map +1 -0
- package/dist/src/infra/path-prepend.d.ts +7 -0
- package/dist/src/infra/path-prepend.js +44 -0
- package/dist/src/infra/path-prepend.js.map +1 -0
- package/dist/src/infra/restart.js +2 -2
- package/dist/src/infra/stable-node-path.d.ts +2 -0
- package/dist/src/infra/stable-node-path.js +28 -0
- package/dist/src/infra/stable-node-path.js.map +1 -0
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/infra/update-global.d.ts +30 -23
- package/dist/src/infra/update-global.js +114 -65
- package/dist/src/infra/update-global.js.map +1 -1
- package/dist/src/infra/update-lock.js +3 -3
- package/dist/src/infra/update-log.d.ts +1 -0
- package/dist/src/infra/update-log.js +12 -0
- package/dist/src/infra/update-log.js.map +1 -0
- package/dist/src/infra/update-restart.d.ts +20 -0
- package/dist/src/infra/update-restart.js +165 -0
- package/dist/src/infra/update-restart.js.map +1 -0
- package/dist/src/infra/update-runner.d.ts +89 -1
- package/dist/src/infra/update-runner.js +604 -173
- package/dist/src/infra/update-runner.js.map +1 -1
- package/dist/src/infra/update-startup.d.ts +3 -0
- package/dist/src/infra/update-startup.js +10 -6
- package/dist/src/infra/update-startup.js.map +1 -1
- package/dist/src/infra/write-file-atomic.js +2 -2
- package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/routing/resolve-route.d.ts +3 -1
- package/dist/src/routing/resolve-route.js.map +1 -1
- package/dist/src/session/config-store.js +2 -2
- package/dist/src/session/init-session-turn.js +2 -2
- package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
- package/dist/src/session/parity/sessions-json-file.js +1 -1
- package/dist/src/session/parity/transcript-file-lock.js +2 -2
- package/dist/src/session/parity/transcript-paths.js +1 -1
- package/dist/src/session/resolve-session.js +4 -4
- package/dist/src/session/search-index-cache.js +1 -1
- package/dist/src/session/search-index.js +1 -1
- package/dist/src/session/session-title.js +2 -2
- package/dist/src/session/store.d.ts +5 -3
- package/dist/src/session/store.js +71 -25
- package/dist/src/session/store.js.map +1 -1
- package/dist/src/share/share-auto.js +2 -2
- package/dist/src/share/share-store.js +3 -3
- package/dist/src/share/share-thumbnail.js +2 -2
- package/dist/src/share/share-zip.js +1 -1
- package/dist/src/share/site-share-store.js +3 -3
- package/dist/src/share/site-static-serve.js +1 -1
- package/dist/src/tui/clipboard-image.js +3 -3
- package/dist/src/tui/theme-manager.js +1 -1
- package/dist/src/tui/tui-keybindings-file.js +1 -1
- package/dist/src/tui/tui-scoped-models.js +2 -2
- package/dist/src/tui/tui-settings.js +1 -1
- package/dist/src/tui/tui.js +3 -3
- package/dist/src/tunnel/frpc-binary.js +3 -3
- package/dist/src/tunnel/frpc-config.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/tunnel-state.js +1 -1
- package/dist/src/utils/logger/audit.js +1 -1
- package/dist/src/utils/logger/log-store.js +1 -1
- package/dist/src/utils/logger/rotation.js +1 -1
- package/dist/src/utils/logger/stats.d.ts +1 -1
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +2 -2
- package/dist/src/workflows/domain/event.d.ts +3 -0
- package/dist/src/workflows/domain/run.d.ts +3 -0
- package/dist/src/workflows/domain/run.js.map +1 -1
- package/dist/src/workflows/engine/projector.js +17 -0
- package/dist/src/workflows/engine/projector.js.map +1 -1
- package/dist/src/workflows/engine/workflow-engine.js +127 -0
- package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
- package/dist/src/workflows/index.js +1 -1
- package/dist/src/workflows/service/run-view-to-snapshot.js +3 -1
- package/dist/src/workflows/service/run-view-to-snapshot.js.map +1 -1
- package/dist/src/workflows/service/workflow-run-service.d.ts +1 -0
- package/dist/src/workflows/service/workflow-run-service.js +4 -1
- package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
- package/dist/src/workflows/service/workflow-session-bridge.js +1 -1
- package/dist/src/workflows/store/event-store.js +1 -1
- package/dist/src/workflows/store/run-store.js +1 -1
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/agents-B6PJB07W.js +0 -222
- package/dist/gateway/static/root/assets/apps-page-BOr0B1wv.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-BelUKggl.js +0 -1
- package/dist/gateway/static/root/assets/cron-api-CjOg-BIj.js +0 -1
- package/dist/gateway/static/root/assets/cron-dreaming-jobs-DueM3rBz.js +0 -2
- package/dist/gateway/static/root/assets/cron-page-DhoZmZXb.js +0 -1
- package/dist/gateway/static/root/assets/dist-6LecgDx5.js +0 -1
- package/dist/gateway/static/root/assets/index-CiN1cQiQ.css +0 -1
- package/dist/gateway/static/root/assets/logs-page-BwWLfqvd.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-DV5WN8uk.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-CfOBRbPX.js +0 -3
- package/dist/gateway/static/root/assets/skills-page-D0H5Kaxg.js +0 -2
- package/dist/gateway/static/root/assets/url-aYn-Rj1C.js +0 -7
- package/dist/gateway/static/root/assets/voice-api-key-field-X2UfnHeq.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-BOPpO3NG.js +0 -27
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { resolveStateDir } from "../../config/paths-state.js";
|
|
2
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
3
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { resolveStateDir } from "../../config/paths-state.js";
|
|
4
4
|
import { init_paths } from "../../config/paths.js";
|
|
5
5
|
import { DEFAULT_USER_FILENAME } from "../context/workspace.js";
|
|
6
6
|
import { createSkillConfigManager } from "../skills/config.js";
|
|
@@ -8,8 +8,8 @@ import { buildTtsSystemPromptHint } from "../../voice/tts/directives.js";
|
|
|
8
8
|
import { mergeTtsConfigFromAppConfig } from "../../voice/tts/merge-config.js";
|
|
9
9
|
import { selectSkillsVisibleInPrompt } from "../skills/format-skills-prompt.js";
|
|
10
10
|
import { buildSystemPrompt } from "./system-prompt.js";
|
|
11
|
-
import { join } from "node:path";
|
|
12
11
|
import { existsSync, readFileSync } from "node:fs";
|
|
12
|
+
import { join } from "node:path";
|
|
13
13
|
//#region src/agent/prompt/service-prompt-builder.ts
|
|
14
14
|
/**
|
|
15
15
|
* System Prompt Builder - Builds the complete system prompt
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { init_agent_scope, resolveAgentProfileDir } from "../agent-scope.js";
|
|
2
2
|
import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
|
|
3
|
-
import { join, resolve } from "node:path";
|
|
4
3
|
import { readFileSync } from "node:fs";
|
|
4
|
+
import { join, resolve } from "node:path";
|
|
5
5
|
//#region src/agent/reply/post-compaction-context.ts
|
|
6
6
|
init_agent_scope();
|
|
7
7
|
const MAX_CONTEXT_CHARS = 1800;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { homedir } from "node:os";
|
|
2
|
-
import { isAbsolute, normalize, resolve, sep } from "node:path";
|
|
3
1
|
import { realpathSync } from "node:fs";
|
|
2
|
+
import { isAbsolute, normalize, resolve, sep } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
4
|
//#region src/agent/sandbox/path-policy.ts
|
|
5
5
|
/**
|
|
6
6
|
* Path safety validation for sandbox isolation.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
|
|
2
1
|
import { init_agent_scope, resolveAgentHomeDir, resolveDefaultAgentId } from "../agent-scope.js";
|
|
2
|
+
import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
|
|
3
3
|
import { extractProfileAgentId } from "../../config/agent-profile.js";
|
|
4
4
|
import { getDefaultModelSync, init_providers } from "../../providers/index.js";
|
|
5
5
|
import { formatInboundFileTextBlock } from "../../channels/attachments/inbound-persist.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { createLogger } from "../utils/logger/index.js";
|
|
2
|
+
import { init_logger } from "../utils/logger.js";
|
|
3
|
+
import { init_agent_scope, resolveAgentHomeDir, resolveAgentProfileDir, resolveDefaultAgentId } from "./agent-scope.js";
|
|
1
4
|
import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
|
|
2
5
|
import { applyConfigOverrides } from "../config/runtime-overrides.js";
|
|
3
|
-
import { init_agent_scope, resolveAgentHomeDir, resolveAgentProfileDir, resolveDefaultAgentId } from "./agent-scope.js";
|
|
4
6
|
import { extractProfileAgentId, resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
5
|
-
import { createLogger } from "../utils/logger/index.js";
|
|
6
|
-
import { init_logger } from "../utils/logger.js";
|
|
7
7
|
import { extractTextContent } from "./context/workspace.js";
|
|
8
8
|
import { onSessionTranscriptUpdate } from "../session/transcript-events.js";
|
|
9
9
|
import { getWorkflowProgressBroker } from "./workflow/progress-broker.js";
|
|
@@ -59,8 +59,8 @@ import { reconcileManagedDreamingCronJobs } from "./service/reconcile-dreaming-c
|
|
|
59
59
|
import { parseOutboundSessionKey } from "./service/parse-outbound-session-key.js";
|
|
60
60
|
import { cleanTrailingErrors } from "./memory/message-sanitizer.js";
|
|
61
61
|
import { tryApplySessionTranscriptHygiene } from "./transcript/transcript-hygiene.js";
|
|
62
|
-
import { join } from "node:path";
|
|
63
62
|
import { existsSync, readFileSync } from "node:fs";
|
|
63
|
+
import { join } from "node:path";
|
|
64
64
|
//#region src/agent/service.ts
|
|
65
65
|
init_schema();
|
|
66
66
|
init_logger();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
|
|
2
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
3
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
|
|
4
4
|
import { resolveEffectiveReasoningLevel, resolveEffectiveThinkingLevel } from "../../session/thinking-resolve.js";
|
|
5
5
|
import { effectiveWorkspacePathForSession } from "../../session/session-workspace.js";
|
|
6
6
|
import "../../session/index.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __toCommonJS } from "../../../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { init_write_file_atomic, writeTextAtomicSync } from "../../infra/write-file-atomic.js";
|
|
2
3
|
import { createLogger } from "../../utils/logger/index.js";
|
|
3
4
|
import { init_logger } from "../../utils/logger.js";
|
|
4
|
-
import { init_write_file_atomic, writeTextAtomicSync } from "../../infra/write-file-atomic.js";
|
|
5
5
|
import { init_installer, installer_exports } from "./installer.js";
|
|
6
6
|
import { join } from "path";
|
|
7
7
|
import { existsSync, readFileSync } from "fs";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { join, relative } from "node:path";
|
|
2
|
-
import { createReadStream, existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
3
1
|
import { createHash } from "node:crypto";
|
|
2
|
+
import { createReadStream, existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
3
|
+
import { join, relative } from "node:path";
|
|
4
4
|
//#region src/agent/skills/hub-hash.ts
|
|
5
5
|
/**
|
|
6
6
|
* Deterministic content hash for a skill directory (for hub lock / drift detection).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { init_paths, resolveSkillsLockPath } from "../../config/paths.js";
|
|
2
1
|
import { init_write_file_atomic, writeTextAtomicSync } from "../../infra/write-file-atomic.js";
|
|
2
|
+
import { init_paths, resolveSkillsLockPath } from "../../config/paths.js";
|
|
3
3
|
import { existsSync, readFileSync } from "node:fs";
|
|
4
4
|
//#region src/agent/skills/hub-lock.ts
|
|
5
5
|
/**
|
|
@@ -4,9 +4,9 @@ import { formatScanSummary, scanSkillDirectory } from "./scanner.js";
|
|
|
4
4
|
import { getSkillsLockEntry, recordSkillsHubInstall } from "./hub-lock.js";
|
|
5
5
|
import { installSkillFromZip, isValidSkillId } from "./managed-store.js";
|
|
6
6
|
import { computeSkillTreeHashSync } from "./hub-hash.js";
|
|
7
|
-
import { tmpdir } from "node:os";
|
|
8
|
-
import { basename, join, normalize, resolve, sep } from "node:path";
|
|
9
7
|
import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
8
|
+
import { basename, join, normalize, resolve, sep } from "node:path";
|
|
9
|
+
import { tmpdir } from "node:os";
|
|
10
10
|
import { execFileSync } from "node:child_process";
|
|
11
11
|
import { fileURLToPath } from "node:url";
|
|
12
12
|
import { fetch } from "undici";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { resolveStateDir } from "../../config/paths-state.js";
|
|
2
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
3
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { resolveStateDir } from "../../config/paths-state.js";
|
|
4
4
|
import { init_paths } from "../../config/paths.js";
|
|
5
5
|
import { parseFrontmatter } from "../../markdown/frontmatter.js";
|
|
6
6
|
import { findInstallSpec, getDefaultInstallerPreferences, hasBinary, init_installer, installSkill } from "./installer.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { init_paths, resolveSkillsDir } from "../../config/paths.js";
|
|
2
2
|
import { parseFrontmatter } from "../../markdown/frontmatter.js";
|
|
3
3
|
import { loadSkillsLock } from "./hub-lock.js";
|
|
4
|
-
import { dirname, join, resolve, sep } from "node:path";
|
|
5
4
|
import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { dirname, join, resolve, sep } from "node:path";
|
|
6
6
|
import AdmZip from "adm-zip";
|
|
7
7
|
//#region src/agent/skills/managed-store.ts
|
|
8
8
|
/**
|
|
@@ -674,25 +674,27 @@ const skillHubMarketplaceAdapter = {
|
|
|
674
674
|
}
|
|
675
675
|
try {
|
|
676
676
|
let skills = [...(await cachedFetchSkillHubCuratedIndex(ecoUrls)).skills].filter((s) => s.slug?.trim());
|
|
677
|
-
if (
|
|
678
|
-
|
|
679
|
-
|
|
677
|
+
if (skills.length > 0) {
|
|
678
|
+
if (params.category?.trim()) {
|
|
679
|
+
const want = params.category.trim();
|
|
680
|
+
skills = skills.filter((s) => (s.categories ?? []).some((x) => String(x).trim() === want));
|
|
681
|
+
}
|
|
682
|
+
if (params.sort === "downloads") skills.sort((a, b) => (b.downloads ?? 0) - (a.downloads ?? 0));
|
|
683
|
+
else if (params.sort === "newest") skills.sort((a, b) => (a.rank ?? 999) - (b.rank ?? 999));
|
|
684
|
+
const rows = curatedSkillsToPackageItems(skills);
|
|
685
|
+
const total = rows.length;
|
|
686
|
+
const start = (page - 1) * pageSize;
|
|
687
|
+
return {
|
|
688
|
+
items: rows.slice(start, start + pageSize),
|
|
689
|
+
meta: {
|
|
690
|
+
page,
|
|
691
|
+
pageSize,
|
|
692
|
+
total,
|
|
693
|
+
totalPages: Math.max(1, Math.ceil(total / pageSize))
|
|
694
|
+
},
|
|
695
|
+
provider: "skillhub"
|
|
696
|
+
};
|
|
680
697
|
}
|
|
681
|
-
if (params.sort === "downloads") skills.sort((a, b) => (b.downloads ?? 0) - (a.downloads ?? 0));
|
|
682
|
-
else if (params.sort === "newest") skills.sort((a, b) => (a.rank ?? 999) - (b.rank ?? 999));
|
|
683
|
-
const rows = curatedSkillsToPackageItems(skills);
|
|
684
|
-
const total = rows.length;
|
|
685
|
-
const start = (page - 1) * pageSize;
|
|
686
|
-
return {
|
|
687
|
-
items: rows.slice(start, start + pageSize),
|
|
688
|
-
meta: {
|
|
689
|
-
page,
|
|
690
|
-
pageSize,
|
|
691
|
-
total,
|
|
692
|
-
totalPages: Math.max(1, Math.ceil(total / pageSize))
|
|
693
|
-
},
|
|
694
|
-
provider: "skillhub"
|
|
695
|
-
};
|
|
696
698
|
} catch {}
|
|
697
699
|
const slugs = await cachedGetDefaultSkillSlugs();
|
|
698
700
|
if (params.category?.trim()) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","names":[],"sources":["../../../../../../../src/agent/skills/marketplace/adapters/skillhub/adapter.ts"],"sourcesContent":["/**\n * SkillHub (skillhub.cn) skills marketplace adapter.\n */\n\nimport { basename } from 'node:path';\n\nimport type { MarketplaceCategoryOption } from '../store/store-api-client.js';\nimport type { SkillsMarketplaceAdapter } from '../../adapter.types.js';\nimport { sortMarketplaceCategories } from '../../marketplace-category-order.js';\nimport { registerMarketplaceAdapter } from '../../registry.js';\n\n// ─── Constants ───────────────────────────────────────────────────────────────\n\nconst SKILLHUB_API_BASE = 'https://api.skillhub.cn';\nconst MAX_SKILL_ZIP_BYTES = 15 * 1024 * 1024;\nconst MAX_SKILLHUB_README_BYTES = 512 * 1024;\nconst SKILL_ID_RE = /^[a-zA-Z0-9]([a-zA-Z0-9._-]{0,62})$/;\nconst REGISTRY_SKILL_BATCH_CHUNK = 80;\n\nconst DEFAULT_SKILLS_INDEX_URL = 'https://skillhub-1388575217.cos.ap-guangzhou.myqcloud.com/skills.json';\nconst DEFAULT_SEARCH_URL = 'https://lightmake.site/api/v1/search';\nconst DEFAULT_PRIMARY_DOWNLOAD_TEMPLATE = 'https://lightmake.site/api/v1/download?slug={slug}';\nconst DEFAULT_FALLBACK_DOWNLOAD_TEMPLATE =\n 'https://skillhub-1388575217.cos.ap-guangzhou.myqcloud.com/skills/{slug}.zip';\nconst DEFAULT_ALLOWED_DOWNLOAD_HOSTS = new Set([\n 'lightmake.site',\n 'api.skillhub.cn',\n 'skillhub-1388575217.cos.ap-guangzhou.myqcloud.com',\n]);\nconst LIGHTMAKE_SEARCH_MAX = 100;\nconst SKILLSET_DISCOVERY_PAGE_CAP = 25;\nconst MAX_DEFAULT_SLUGS = 200;\n\nconst DEFAULT_CACHE_MS = 5 * 60 * 1000;\nconst MAX_BATCH_CACHE_KEYS = 48;\n\n// ─── Inline helpers ──────────────────────────────────────────────────────────\n\nfunction isValidSkillId(id: string): boolean {\n return SKILL_ID_RE.test(id);\n}\n\n// ─── SkillHub registry types ─────────────────────────────────────────────────\n\ninterface SkillHubSkill {\n slug: string;\n displayName: string;\n summary: string;\n summary_zh?: string;\n category: string;\n iconUrl: string | null;\n source: string;\n labels: { requires_api_key?: string };\n stats: {\n downloads: number;\n installs: number;\n stars: number;\n comments: number;\n versions: number;\n };\n createdAt: number;\n updatedAt: number;\n tags: Record<string, string>;\n}\n\ninterface SkillHubSkillDetail {\n skill: SkillHubSkill;\n latestVersion: {\n version: string;\n changelog: string | null;\n createdAt: number;\n securityReports?: {\n keen?: { status: string; statusText: string; reportUrl?: string };\n sanbu?: { status: string; statusText: string; reportUrl?: string };\n };\n };\n owner: { handle: string; displayName: string; image: string | null };\n}\n\ninterface SkillHubFile { path: string; sha256: string; size: number }\n\ninterface SkillHubRegistryCategoryItem {\n key: string;\n name: string;\n nameEn: string;\n sortOrder: number;\n active: boolean;\n}\n\ninterface SkillHubSkillset {\n id: number;\n slug: string;\n displayName: string;\n summary: string;\n scene: string;\n subScene: string;\n content: string;\n skillSlugs: string[];\n skillCount: number;\n createdAt: number;\n updatedAt: number;\n}\n\n// ─── Ecosystem types ─────────────────────────────────────────────────────────\n\ninterface EcosystemUrls {\n skillsIndexUrl: string;\n searchUrl: string;\n primaryDownloadTemplate: string;\n fallbackDownloadTemplate: string;\n}\n\ninterface CuratedIndexSkill {\n rank?: number;\n slug: string;\n name?: string;\n description?: string;\n version?: string;\n homepage?: string;\n downloads?: number;\n stars?: number;\n score?: number;\n categories?: string[];\n}\n\ninterface CuratedIndex {\n total?: number;\n skills: CuratedIndexSkill[];\n}\n\ninterface LightmakeSearchHit {\n slug: string;\n displayName?: string;\n name?: string;\n summary?: string;\n description?: string;\n description_zh?: string;\n version?: string;\n downloads?: number;\n installs?: number;\n stars?: number;\n owner_name?: string;\n category?: string;\n score?: number;\n updatedAt?: number;\n updated_at?: number;\n /** Origin registry label from Lightmake (e.g. clawhub, community). Detail/download still go\n * through api.skillhub.cn for synced skills. */\n source?: string;\n}\n\ninterface PackageListItem {\n id: string;\n name: string;\n type: string;\n description: string;\n downloads: number;\n author: { username: string; avatarUrl: string | null };\n latestVersion?: string;\n updatedAt: string;\n categories?: string[];\n stars?: number;\n sourceLabel?: string;\n}\n\n// ─── Registry HTTP helpers ───────────────────────────────────────────────────\n\nasync function registryFetchJson<T>(url: string, init?: RequestInit): Promise<T> {\n const res = await fetch(url, {\n ...init,\n headers: { Accept: 'application/json', ...(init?.headers as Record<string, string> | undefined) },\n });\n const text = await res.text();\n if (!res.ok) {\n let msg = `SkillHub request failed (${res.status})`;\n try {\n const j = JSON.parse(text) as { message?: string; error?: string };\n if (j.message) msg = j.message;\n else if (j.error) msg = j.error;\n } catch { if (text) msg = text.slice(0, 200); }\n throw new Error(msg);\n }\n try { return JSON.parse(text) as T; }\n catch { throw new Error('SkillHub returned invalid JSON'); }\n}\n\nfunction basenameSkillPath(p: string): string {\n const norm = p.replace(/\\\\/g, '/');\n const parts = norm.split('/');\n return parts[parts.length - 1] || norm;\n}\n\nfunction pickSkillHubDocFilePath(files: SkillHubFile[]): string | null {\n const rows = files.map((f) => ({\n path: f.path.replace(/\\\\/g, '/'),\n base: basenameSkillPath(f.path).toLowerCase(),\n }));\n const firstBase = (name: string) => rows.find((r) => r.base === name.toLowerCase());\n const skillMd = firstBase('SKILL.md') ?? firstBase('skill.md');\n if (skillMd) return skillMd.path;\n const readme = firstBase('README.md') ?? firstBase('readme.md');\n if (readme) return readme.path;\n const how = firstBase('HOW_TO_USE.md');\n if (how) return how.path;\n return null;\n}\n\nfunction assertSkillHubReadmeResponseUrl(finalUrl: string): void {\n let u: URL;\n try { u = new URL(finalUrl); } catch { throw new Error('Invalid SkillHub file response URL'); }\n if (u.protocol !== 'https:') throw new Error('SkillHub file response must use HTTPS');\n const host = u.hostname.toLowerCase();\n if (host === 'api.skillhub.cn') return;\n if (host.endsWith('.myqcloud.com')) return;\n throw new Error('SkillHub file redirect host is not allowlisted');\n}\n\nasync function getSkillHubSkillFileText(slug: string, filePath: string, version?: string): Promise<string> {\n const enc = encodeURIComponent(slug.trim());\n const normPath = filePath.replace(/\\\\/g, '/');\n const sp = new URLSearchParams({ path: normPath });\n if (version?.trim()) sp.set('version', version.trim());\n const url = `${SKILLHUB_API_BASE}/api/v1/skills/${enc}/file?${sp.toString()}`;\n const res = await fetch(url, { redirect: 'follow', headers: { Accept: 'text/markdown,text/plain,*/*' } });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n let msg = `SkillHub file request failed (${res.status})`;\n try {\n const j = JSON.parse(text) as { message?: string; error?: string };\n if (typeof j.message === 'string') msg = j.message;\n else if (typeof j.error === 'string') msg = j.error;\n } catch { if (text) msg = text.slice(0, 200); }\n throw new Error(msg);\n }\n assertSkillHubReadmeResponseUrl(res.url);\n const len = res.headers.get('content-length');\n if (len) {\n const n = Number(len);\n if (Number.isFinite(n) && n > MAX_SKILLHUB_README_BYTES) throw new Error(`SkillHub file exceeds max size`);\n }\n const ab = await res.arrayBuffer();\n if (ab.byteLength > MAX_SKILLHUB_README_BYTES) throw new Error(`SkillHub file exceeds max size`);\n return new TextDecoder('utf-8').decode(ab);\n}\n\nasync function getSkillHubSkill(slug: string): Promise<SkillHubSkillDetail> {\n return registryFetchJson<SkillHubSkillDetail>(`${SKILLHUB_API_BASE}/api/v1/skills/${encodeURIComponent(slug.trim())}`);\n}\n\nasync function getSkillHubSkillFiles(slug: string, version?: string): Promise<{ files: SkillHubFile[]; version: string }> {\n const enc = encodeURIComponent(slug.trim());\n const sp = version ? `?version=${encodeURIComponent(version)}` : '';\n return registryFetchJson<{ files: SkillHubFile[]; version: string }>(`${SKILLHUB_API_BASE}/api/v1/skills/${enc}/files${sp}`);\n}\n\nasync function downloadSkillHubZipBuffer(slug: string, version?: string): Promise<{ buffer: Buffer; version: string }> {\n const enc = encodeURIComponent(slug.trim());\n let url = `${SKILLHUB_API_BASE}/api/v1/download?slug=${enc}`;\n if (version?.trim()) url += `&version=${encodeURIComponent(version.trim())}`;\n const res = await fetch(url, { redirect: 'follow' });\n if (!res.ok) throw new Error(`Failed to download skill archive (${res.status})`);\n const len = res.headers.get('content-length');\n if (len) { const n = Number(len); if (Number.isFinite(n) && n > MAX_SKILL_ZIP_BYTES) throw new Error(`Zip exceeds max size`); }\n const ab = await res.arrayBuffer();\n const buf = Buffer.from(ab);\n if (buf.length > MAX_SKILL_ZIP_BYTES) throw new Error(`Zip exceeds max size`);\n let resolvedVersion = version ?? '1.0.0';\n if (!version?.trim()) {\n try { resolvedVersion = (await getSkillHubSkillFiles(slug)).version; } catch { /* keep default */ }\n }\n return { buffer: buf, version: resolvedVersion };\n}\n\nasync function batchGetSkillHubSkills(slugs: string[]): Promise<SkillHubSkillDetail[]> {\n if (slugs.length === 0) return [];\n const response = await registryFetchJson<{ count: number; items: SkillHubSkillDetail[]; missing: string[] }>(\n `${SKILLHUB_API_BASE}/api/v1/skills/batch`,\n { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ slugs }) },\n );\n return response.items ?? [];\n}\n\nasync function listSkillHubRegistryCategories(): Promise<SkillHubRegistryCategoryItem[]> {\n const raw = await registryFetchJson<{ count?: number; items?: SkillHubRegistryCategoryItem[] }>(\n `${SKILLHUB_API_BASE}/api/v1/categories`,\n );\n const items = Array.isArray(raw.items) ? raw.items : [];\n return items.filter((c) => c && typeof c.key === 'string' && c.key.trim().length > 0 && c.active !== false);\n}\n\nasync function listSkillHubSkillsets(opts: { page?: number; pageSize?: number; keyword?: string; scene?: string } = {}): Promise<{ skillSets: SkillHubSkillset[]; total: number }> {\n const page = opts.page ?? 1;\n const pageSize = opts.pageSize ?? 20;\n const sp = new URLSearchParams({ page: String(page), pageSize: String(pageSize) });\n if (opts.keyword?.trim()) sp.set('keyword', opts.keyword.trim());\n if (opts.scene?.trim()) sp.set('scene', opts.scene.trim());\n return registryFetchJson<{ skillSets: SkillHubSkillset[]; total: number }>(`${SKILLHUB_API_BASE}/api/v1/skillsets?${sp.toString()}`);\n}\n\nasync function getDefaultSkillSlugs(): Promise<string[]> {\n const slugs = new Set<string>();\n let page = 1;\n const pageSize = 50;\n let total = Infinity;\n while (page <= SKILLSET_DISCOVERY_PAGE_CAP && slugs.size < MAX_DEFAULT_SLUGS) {\n const response = await listSkillHubSkillsets({ page, pageSize });\n total = response.total;\n for (const skillset of response.skillSets) {\n for (const slug of skillset.skillSlugs) slugs.add(slug);\n }\n if (page * pageSize >= total) break;\n page += 1;\n }\n return Array.from(slugs).slice(0, MAX_DEFAULT_SLUGS);\n}\n\nasync function searchSkillHubSkills(query: string, maxSlugs = 200): Promise<{ slugs: string[]; total: number }> {\n const keyword = query.trim();\n if (!keyword) return { slugs: [], total: 0 };\n const slugs: string[] = [];\n const seen = new Set<string>();\n let page = 1;\n const batchSize = 50;\n while (page <= SKILLSET_DISCOVERY_PAGE_CAP) {\n const response = await listSkillHubSkillsets({ page, pageSize: batchSize, keyword });\n for (const skillset of response.skillSets) {\n for (const slug of skillset.skillSlugs) {\n if (!seen.has(slug)) { seen.add(slug); slugs.push(slug); }\n }\n }\n if (page * batchSize >= response.total) break;\n page += 1;\n }\n const capped = slugs.slice(0, maxSlugs);\n return { slugs: capped, total: capped.length };\n}\n\n// ─── Ecosystem helpers ───────────────────────────────────────────────────────\n\nfunction templateWithSlug(template: string, slug: string): string {\n const raw = template.trim();\n if (!raw) return '';\n if (raw.includes('{slug}')) return raw.replaceAll('{slug}', encodeURIComponent(slug.trim()));\n const base = raw.replace(/\\/$/, '');\n return `${base}/${encodeURIComponent(slug.trim())}.zip`;\n}\n\nfunction hostFromTemplate(template: string): string | undefined {\n const t = templateWithSlug(template, 'x');\n try { return new URL(t).hostname.toLowerCase(); } catch { return undefined; }\n}\n\nfunction resolveSkillHubEcosystemUrls(): EcosystemUrls {\n return {\n skillsIndexUrl: process.env.XOPC_SKILLHUB_SKILLS_INDEX_URL?.trim() || DEFAULT_SKILLS_INDEX_URL,\n searchUrl: process.env.XOPC_SKILLHUB_SEARCH_URL?.trim() || DEFAULT_SEARCH_URL,\n primaryDownloadTemplate: process.env.XOPC_SKILLHUB_PRIMARY_DOWNLOAD_TEMPLATE?.trim() || DEFAULT_PRIMARY_DOWNLOAD_TEMPLATE,\n fallbackDownloadTemplate: process.env.XOPC_SKILLHUB_FALLBACK_DOWNLOAD_TEMPLATE?.trim() || DEFAULT_FALLBACK_DOWNLOAD_TEMPLATE,\n };\n}\n\nfunction allowedDownloadHosts(urls: EcosystemUrls): Set<string> {\n const hosts = new Set(DEFAULT_ALLOWED_DOWNLOAD_HOSTS);\n for (const h of [hostFromTemplate(urls.primaryDownloadTemplate), hostFromTemplate(urls.fallbackDownloadTemplate)]) { if (h) hosts.add(h); }\n try { hosts.add(new URL(urls.skillsIndexUrl).hostname.toLowerCase()); } catch { /* ignore */ }\n try { hosts.add(new URL(urls.searchUrl).hostname.toLowerCase()); } catch { /* ignore */ }\n return hosts;\n}\n\nfunction assertSkillHubDownloadUrlAllowed(downloadUrl: string, urls: EcosystemUrls): URL {\n let u: URL;\n try { u = new URL(downloadUrl); } catch { throw new Error('Invalid SkillHub download URL'); }\n if (u.protocol !== 'https:') throw new Error('SkillHub download URL must use HTTPS');\n if (!allowedDownloadHosts(urls).has(u.hostname.toLowerCase())) throw new Error('SkillHub download URL host is not allowlisted');\n return u;\n}\n\nasync function ecoFetchJson<T>(url: string, init?: RequestInit): Promise<T> {\n const res = await fetch(url, { ...init, headers: { Accept: 'application/json', ...init?.headers } });\n const text = await res.text();\n if (!res.ok) {\n let msg = `SkillHub ecosystem request failed (${res.status})`;\n try { const j = JSON.parse(text) as { message?: string; error?: string }; if (j.message) msg = j.message; else if (j.error) msg = j.error; } catch { if (text) msg = text.slice(0, 200); }\n throw new Error(msg);\n }\n try { return JSON.parse(text) as T; } catch { throw new Error('SkillHub ecosystem returned invalid JSON'); }\n}\n\nasync function fetchSkillHubCuratedIndex(urls: EcosystemUrls): Promise<CuratedIndex> {\n const raw = await ecoFetchJson<unknown>(urls.skillsIndexUrl);\n if (Array.isArray(raw)) return { skills: raw as CuratedIndexSkill[] };\n if (raw && typeof raw === 'object' && Array.isArray((raw as CuratedIndex).skills)) return raw as CuratedIndex;\n throw new Error('SkillHub index JSON must be an object with a skills array');\n}\n\nfunction sourceLabelFromHomepage(homepage?: string): string | undefined {\n const h = homepage?.trim().toLowerCase() ?? '';\n if (h.includes('clawhub')) return 'ClawHub';\n if (h.includes('skillhub')) return 'SkillHub';\n return undefined;\n}\n\nfunction curatedSkillsToPackageItems(skills: CuratedIndexSkill[]): PackageListItem[] {\n return skills.map((s) => ({\n id: s.slug,\n name: (s.name ?? s.slug).trim() || s.slug,\n type: 'skill',\n description: (s.description ?? '').trim(),\n downloads: typeof s.downloads === 'number' ? s.downloads : 0,\n author: { username: 'skillhub', avatarUrl: null },\n latestVersion: (s.version ?? '').trim() || undefined,\n updatedAt: String(s.rank ?? s.score ?? 0),\n categories: (s.categories ?? []).map((c) => String(c).trim()).filter(Boolean),\n stars: typeof s.stars === 'number' ? s.stars : undefined,\n sourceLabel: sourceLabelFromHomepage(s.homepage),\n }));\n}\n\nasync function findCuratedIndexSkill(slug: string): Promise<CuratedIndexSkill | null> {\n const want = slug.trim();\n if (!want) return null;\n const ecoUrls = resolveSkillHubEcosystemUrls();\n try {\n const idx = await cachedFetchSkillHubCuratedIndex(ecoUrls);\n return idx.skills.find((s) => s.slug?.trim() === want) ?? null;\n } catch {\n return null;\n }\n}\n\nfunction curatedSkillFallbackReadmeMarkdown(skill: CuratedIndexSkill): string {\n const title = (skill.name ?? skill.slug).trim() || skill.slug;\n const desc = (skill.description ?? '').trim() || '_No description._';\n const version = (skill.version ?? '').trim() || '1.0.0';\n return `## ${title}\\n\\n**${skill.slug}** · v${version}\\n\\n${desc}`;\n}\n\nfunction packageDetailFromCuratedSkill(skill: CuratedIndexSkill) {\n const slug = skill.slug.trim();\n const version = (skill.version ?? '').trim() || '1.0.0';\n const categories = (skill.categories ?? []).map((c) => String(c).trim()).filter(Boolean);\n const sourceLabel = sourceLabelFromHomepage(skill.homepage);\n return {\n id: slug,\n name: (skill.name ?? slug).trim() || slug,\n type: 'skill',\n description: (skill.description ?? '').trim(),\n readme: curatedSkillFallbackReadmeMarkdown(skill),\n downloads: typeof skill.downloads === 'number' ? skill.downloads : 0,\n author: {\n username: sourceLabel?.toLowerCase() ?? 'skillhub',\n avatarUrl: null,\n },\n latestVersion: {\n version,\n changelog: null,\n publishedAt: String(skill.rank ?? skill.score ?? 0),\n },\n provider: 'skillhub',\n skillHubInfo: {\n category: categories[0] ?? '',\n installs: 0,\n stars: typeof skill.stars === 'number' ? skill.stars : 0,\n },\n };\n}\n\nfunction lightmakeHitToPackageItem(hit: LightmakeSearchHit): PackageListItem {\n const slug = String(hit.slug || '').trim();\n const desc = (hit.summary ?? hit.description_zh ?? hit.description ?? '').trim() || '';\n const updated = hit.updatedAt ?? hit.updated_at ?? 0;\n const cat = hit.category?.trim();\n return {\n id: slug,\n name: (hit.displayName ?? hit.name ?? slug).trim() || slug,\n type: 'skill',\n description: desc,\n downloads: typeof hit.downloads === 'number' ? hit.downloads : 0,\n author: { username: (hit.owner_name ?? 'skillhub').trim() || 'skillhub', avatarUrl: null },\n latestVersion: (hit.version ?? '').trim() || undefined,\n updatedAt: String(updated),\n categories: cat ? [cat] : [],\n stars: typeof hit.stars === 'number' ? hit.stars : undefined,\n sourceLabel: sourceLabelFromSkillSource(hit.source) ?? 'Lightmake',\n };\n}\n\nasync function searchSkillHubLightmake(urls: EcosystemUrls, query: string, limit: number, timeoutMs = 4000): Promise<PackageListItem[]> {\n const q = query.trim().toLowerCase();\n if (!q) return [];\n const search = new URL(urls.searchUrl);\n if (search.protocol !== 'https:') throw new Error('SkillHub search URL must use HTTPS');\n search.searchParams.set('q', q);\n search.searchParams.set('limit', String(Math.max(1, Math.min(LIGHTMAKE_SEARCH_MAX, limit))));\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const raw = await ecoFetchJson<{ results?: LightmakeSearchHit[] }>(search.toString(), { signal: controller.signal });\n const results = raw.results;\n if (!Array.isArray(results)) return [];\n const out: PackageListItem[] = [];\n for (const item of results) {\n if (!item || typeof item !== 'object') continue;\n const hit = item as LightmakeSearchHit;\n const slug = String(hit.slug ?? '').trim();\n if (!slug) continue;\n out.push(lightmakeHitToPackageItem(hit));\n }\n return out;\n } finally { clearTimeout(timer); }\n}\n\nasync function downloadSkillHubZipFromAllowlistedUrl(urls: EcosystemUrls, downloadUrl: string): Promise<Buffer> {\n const normalized = assertSkillHubDownloadUrlAllowed(downloadUrl, urls);\n const res = await fetch(normalized.toString(), { redirect: 'follow' });\n if (!res.ok) throw new Error(`Failed to download skill archive (${res.status})`);\n const len = res.headers.get('content-length');\n if (len) { const n = Number(len); if (Number.isFinite(n) && n > MAX_SKILL_ZIP_BYTES) throw new Error(`Zip exceeds max size`); }\n const ab = await res.arrayBuffer();\n const buf = Buffer.from(ab);\n if (buf.length > MAX_SKILL_ZIP_BYTES) throw new Error(`Zip exceeds max size`);\n return buf;\n}\n\nasync function downloadSkillHubZipFromEcosystem(urls: EcosystemUrls, slug: string): Promise<Buffer> {\n const primary = templateWithSlug(urls.primaryDownloadTemplate, slug);\n const fallback = templateWithSlug(urls.fallbackDownloadTemplate, slug);\n const candidates = [primary, fallback].filter(Boolean);\n const seen = new Set<string>();\n let lastErr: Error | undefined;\n for (const url of candidates) {\n if (seen.has(url)) continue;\n seen.add(url);\n try { return await downloadSkillHubZipFromAllowlistedUrl(urls, url); }\n catch (e) { lastErr = e instanceof Error ? e : new Error(String(e)); }\n }\n throw lastErr ?? new Error('SkillHub ecosystem download failed');\n}\n\n// ─── In-memory TTL cache ─────────────────────────────────────────────────────\n\ntype CacheEntry<T> = { value: T; expiresAt: number };\n\nfunction cacheTtlMs(): number {\n const raw = process.env.XOPC_SKILLHUB_CACHE_MS?.trim();\n if (raw === '0' || raw === 'false') return 0;\n const n = Number(raw);\n if (!Number.isFinite(n) || n < 0) return DEFAULT_CACHE_MS;\n return n;\n}\n\nfunction getFresh<T>(entry: CacheEntry<T> | undefined): T | undefined {\n if (!entry || entry.expiresAt <= Date.now()) return undefined;\n return entry.value;\n}\n\nconst curatedByIndexUrl = new Map<string, CacheEntry<CuratedIndex>>();\nlet defaultSlugsEntry: CacheEntry<string[]> | undefined;\nlet registryCategoriesEntry: CacheEntry<SkillHubRegistryCategoryItem[]> | undefined;\nconst batchBySlugsKey = new Map<string, CacheEntry<SkillHubSkillDetail[]>>();\nconst lightmakeSearchByQuery = new Map<string, CacheEntry<PackageListItem[]>>();\n\nfunction evictOldestBatchKey(): void {\n const first = batchBySlugsKey.keys().next().value;\n if (first !== undefined) batchBySlugsKey.delete(first);\n}\n\nfunction evictOldestSearchKey(): void {\n const first = lightmakeSearchByQuery.keys().next().value;\n if (first !== undefined) lightmakeSearchByQuery.delete(first);\n}\n\nfunction batchSlugsCacheKey(slugs: string[]): string {\n if (slugs.length === 0) return '';\n return [...slugs].sort().join('\\n');\n}\n\nasync function cachedFetchSkillHubCuratedIndex(urls: EcosystemUrls): Promise<CuratedIndex> {\n const ttl = cacheTtlMs();\n const key = urls.skillsIndexUrl;\n if (ttl > 0) { const hit = getFresh(curatedByIndexUrl.get(key)); if (hit) return hit; }\n const value = await fetchSkillHubCuratedIndex(urls);\n if (ttl > 0) curatedByIndexUrl.set(key, { value, expiresAt: Date.now() + ttl });\n return value;\n}\n\nasync function cachedGetDefaultSkillSlugs(): Promise<string[]> {\n const ttl = cacheTtlMs();\n if (ttl > 0) { const hit = getFresh(defaultSlugsEntry); if (hit) return hit; }\n const value = await getDefaultSkillSlugs();\n if (ttl > 0) defaultSlugsEntry = { value, expiresAt: Date.now() + ttl };\n return value;\n}\n\nasync function cachedListSkillHubRegistryCategories(): Promise<SkillHubRegistryCategoryItem[]> {\n const ttl = cacheTtlMs();\n if (ttl > 0) { const hit = getFresh(registryCategoriesEntry); if (hit) return hit; }\n const value = await listSkillHubRegistryCategories();\n if (ttl > 0) registryCategoriesEntry = { value, expiresAt: Date.now() + ttl };\n return value;\n}\n\nasync function cachedBatchGetSkillHubSkills(slugs: string[]): Promise<SkillHubSkillDetail[]> {\n if (slugs.length === 0) return [];\n const ttl = cacheTtlMs();\n const key = batchSlugsCacheKey(slugs);\n if (ttl > 0) { const hit = getFresh(batchBySlugsKey.get(key)); if (hit) return hit; }\n const value = await batchGetSkillHubSkills(slugs);\n if (ttl > 0) {\n while (batchBySlugsKey.size >= MAX_BATCH_CACHE_KEYS) evictOldestBatchKey();\n batchBySlugsKey.set(key, { value, expiresAt: Date.now() + ttl });\n }\n return value;\n}\n\nasync function cachedSearchSkillHubLightmake(\n urls: EcosystemUrls,\n query: string,\n limit: number,\n): Promise<PackageListItem[]> {\n const q = query.trim().toLowerCase();\n if (!q) return [];\n const ttl = cacheTtlMs();\n const key = `${urls.searchUrl}|${q}|${limit}`;\n if (ttl > 0) { const hit = getFresh(lightmakeSearchByQuery.get(key)); if (hit) return hit; }\n const value = await searchSkillHubLightmake(urls, q, limit);\n if (ttl > 0) {\n while (lightmakeSearchByQuery.size >= MAX_BATCH_CACHE_KEYS) evictOldestSearchKey();\n lightmakeSearchByQuery.set(key, { value, expiresAt: Date.now() + ttl });\n }\n return value;\n}\n\n// ─── Adapter conversion helpers ──────────────────────────────────────────────\n\nfunction humanizeRegistryCategoryKey(slug: string): string {\n return slug.replace(/_/g, '-').split('-').filter(Boolean)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join(' ');\n}\n\nfunction sourceLabelFromSkillSource(source: string | undefined): string | undefined {\n const s = source?.trim();\n if (!s) return undefined;\n const lower = s.toLowerCase();\n if (lower === 'clawhub') return 'ClawHub';\n if (lower === 'lightmake') return 'Lightmake';\n if (lower === 'skillhub') return 'SkillHub';\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nfunction filterByCategory(rows: PackageListItem[], category?: string): PackageListItem[] {\n const want = category?.trim();\n if (!want) return rows;\n return rows.filter((r) => (r.categories ?? []).includes(want));\n}\n\nasync function collectRegistryCategoryKeysFromSlugs(slugs: string[]): Promise<Set<string>> {\n const used = new Set<string>();\n for (let i = 0; i < slugs.length; i += REGISTRY_SKILL_BATCH_CHUNK) {\n const chunk = slugs.slice(i, i + REGISTRY_SKILL_BATCH_CHUNK);\n const details = await cachedBatchGetSkillHubSkills(chunk);\n for (const d of details) {\n const k = d.skill.category?.trim();\n if (k) used.add(k);\n }\n }\n return used;\n}\n\nfunction isPipelineOnlyChangelog(text: string | null | undefined): boolean {\n if (!text?.trim()) return true;\n return /^synced by skillhub pipeline\\.?$/i.test(text.trim());\n}\n\nfunction skillHubFallbackReadmeMarkdown(detail: { skill: SkillHubSkill; latestVersion: { version: string } }): string {\n const s = detail.skill;\n const title = s.displayName?.trim() || s.slug;\n const zh = s.summary_zh?.trim();\n const en = s.summary?.trim();\n const body = zh && en && zh !== en ? `${zh}\\n\\n${en}` : zh || en || '_No description._';\n return `## ${title}\\n\\n**${s.slug}** · v${detail.latestVersion.version}\\n\\n${body}`;\n}\n\nfunction convertSkillHubToPackageListItem(detail: SkillHubSkill): PackageListItem {\n const cat = detail.category?.trim();\n return {\n id: detail.slug,\n name: detail.displayName?.trim() || detail.slug,\n type: 'skill',\n description: detail.summary_zh || detail.summary,\n downloads: detail.stats.downloads,\n author: { username: detail.source || 'skillhub', avatarUrl: null },\n latestVersion: detail.tags.latest || '1.0.0',\n updatedAt: String(detail.updatedAt),\n categories: cat ? [cat] : [],\n stars: detail.stats.stars,\n sourceLabel: sourceLabelFromSkillSource(detail.source),\n };\n}\n\nexport const skillHubMarketplaceAdapter: SkillsMarketplaceAdapter = {\n id: 'skillhub',\n\n async listCategories(_config) {\n const sortByLabel = (a: MarketplaceCategoryOption, b: MarketplaceCategoryOption) =>\n a.label.localeCompare(b.label, 'zh-Hans-CN', { sensitivity: 'base' });\n const ecoUrls = resolveSkillHubEcosystemUrls();\n try {\n const idx = await cachedFetchSkillHubCuratedIndex(ecoUrls);\n if (idx.skills?.length) {\n const map = new Map<string, MarketplaceCategoryOption>();\n for (const s of idx.skills) {\n for (const raw of s.categories ?? []) {\n const label = String(raw).trim();\n if (label) map.set(label, { id: label, label });\n }\n }\n return sortMarketplaceCategories(\n Array.from(map.values()).filter((c) => c.id.trim() && c.label.trim()),\n sortByLabel,\n );\n }\n } catch { /* fall through: registry-backed catalog */ }\n try {\n const [taxonomy, slugs] = await Promise.all([\n cachedListSkillHubRegistryCategories(),\n cachedGetDefaultSkillSlugs(),\n ]);\n const usedKeys = await collectRegistryCategoryKeysFromSlugs(slugs);\n const taxByKey = new Map(taxonomy.map((t) => [t.key, t] as const));\n const options: MarketplaceCategoryOption[] = [];\n for (const key of usedKeys) {\n const t = taxByKey.get(key);\n const label = t?.name?.trim() || t?.nameEn?.trim() || humanizeRegistryCategoryKey(key).trim();\n if (!label) continue;\n options.push({ id: key, label });\n }\n return sortMarketplaceCategories(options, (a, b) => {\n const oa = taxByKey.get(a.id)?.sortOrder ?? 999;\n const ob = taxByKey.get(b.id)?.sortOrder ?? 999;\n if (oa !== ob) return oa - ob;\n return sortByLabel(a, b);\n });\n } catch { return []; }\n },\n\n async listPackages(_config, params) {\n const pageSize = params.pageSize ?? 20;\n const page = params.page ?? 1;\n const ecoUrls = resolveSkillHubEcosystemUrls();\n\n if (params.q?.trim()) {\n const q = params.q.trim();\n let rows: PackageListItem[] = [];\n try {\n rows = await cachedSearchSkillHubLightmake(ecoUrls, q, 100);\n } catch {\n // Lightmake unavailable — fall back to the registry skillset scan. We do NOT run this\n // when Lightmake returned zero hits: that would queue ~40 sequential HTTP calls just to\n // confirm \"no results\", and the empty state UI is the better answer for the user.\n try {\n const searchResult = await searchSkillHubSkills(q, 200);\n const details = await cachedBatchGetSkillHubSkills(searchResult.slugs);\n rows = details.map((d) => convertSkillHubToPackageListItem(d.skill));\n } catch {\n rows = [];\n }\n }\n rows = filterByCategory(rows, params.category);\n if (params.sort === 'downloads') rows = [...rows].sort((a, b) => b.downloads - a.downloads);\n else if (params.sort === 'newest') rows = [...rows].sort((a, b) => Number(b.updatedAt) - Number(a.updatedAt));\n const total = rows.length;\n const start = (page - 1) * pageSize;\n const items = rows.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'skillhub' };\n }\n\n try {\n const idx = await cachedFetchSkillHubCuratedIndex(ecoUrls);\n let skills = [...idx.skills].filter((s) => s.slug?.trim());\n if (params.category?.trim()) {\n const want = params.category.trim();\n skills = skills.filter((s) => (s.categories ?? []).some((x) => String(x).trim() === want));\n }\n if (params.sort === 'downloads') skills.sort((a, b) => (b.downloads ?? 0) - (a.downloads ?? 0));\n else if (params.sort === 'newest') skills.sort((a, b) => (a.rank ?? 999) - (b.rank ?? 999));\n const rows = curatedSkillsToPackageItems(skills);\n const total = rows.length;\n const start = (page - 1) * pageSize;\n const items = rows.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'skillhub' };\n } catch { /* fall through */ }\n\n const slugs = await cachedGetDefaultSkillSlugs();\n if (params.category?.trim()) {\n const details = await cachedBatchGetSkillHubSkills(slugs);\n let allItems = details.map((d) => convertSkillHubToPackageListItem(d.skill));\n allItems = filterByCategory(allItems, params.category);\n if (params.sort === 'downloads') allItems = [...allItems].sort((a, b) => b.downloads - a.downloads);\n else if (params.sort === 'newest') allItems = [...allItems].sort((a, b) => Number(b.updatedAt) - Number(a.updatedAt));\n const total = allItems.length;\n const start = (page - 1) * pageSize;\n const items = allItems.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'skillhub' };\n }\n\n const total = slugs.length;\n const start = (page - 1) * pageSize;\n const paginatedSlugs = slugs.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n const details = await cachedBatchGetSkillHubSkills(paginatedSlugs);\n const items = details.map((d) => convertSkillHubToPackageListItem(d.skill));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'skillhub' };\n },\n\n async getPackageDetail(_config, packageName) {\n const slug = packageName.trim();\n let detail: SkillHubSkillDetail;\n try {\n detail = await getSkillHubSkill(slug);\n } catch (registryErr) {\n const curated = await findCuratedIndexSkill(slug);\n if (curated) return packageDetailFromCuratedSkill(curated);\n throw registryErr;\n }\n const version = detail.latestVersion.version;\n const changelog = detail.latestVersion.changelog;\n\n let readme: string | null = null;\n let docPath: string | null = null;\n try {\n const { files } = await getSkillHubSkillFiles(slug, version);\n docPath = pickSkillHubDocFilePath(files);\n if (docPath) readme = await getSkillHubSkillFileText(slug, docPath, version);\n } catch { readme = null; }\n\n const trimmed = readme?.trim() ?? '';\n const docBase = docPath ? basename(docPath.replace(/\\\\/g, '/')).toLowerCase() : '';\n const isSkillMd = docBase === 'skill.md';\n\n if (!trimmed) {\n readme = skillHubFallbackReadmeMarkdown(detail);\n } else if (isSkillMd) {\n readme = trimmed;\n if (changelog?.trim() && !isPipelineOnlyChangelog(changelog)) {\n readme = `${trimmed}\\n\\n---\\n\\n## Changelog\\n\\n${changelog.trim()}`;\n }\n } else {\n readme = trimmed;\n if (changelog?.trim() && !isPipelineOnlyChangelog(changelog)) {\n readme = `${trimmed}\\n\\n---\\n\\n## Changelog\\n\\n${changelog.trim()}`;\n }\n }\n\n return {\n id: detail.skill.slug,\n name: detail.skill.slug,\n type: 'skill',\n description: detail.skill.summary_zh || detail.skill.summary,\n readme,\n downloads: detail.skill.stats.downloads,\n author: {\n username: detail.owner.handle,\n avatarUrl: detail.owner.image,\n },\n latestVersion: {\n version: detail.latestVersion.version,\n changelog: detail.latestVersion.changelog,\n publishedAt: String(detail.latestVersion.createdAt),\n },\n provider: 'skillhub',\n skillHubInfo: {\n category: detail.skill.category,\n installs: detail.skill.stats.installs,\n stars: detail.skill.stats.stars,\n securityReports: detail.latestVersion.securityReports,\n },\n };\n },\n\n async downloadPackage(_config, packageName, version) {\n const slug = packageName.trim();\n if (version?.trim()) {\n const { buffer, version: resolvedVersion } = await downloadSkillHubZipBuffer(slug, version);\n return { buffer, skillId: isValidSkillId(slug) ? slug : 'unknown', version: resolvedVersion };\n }\n const ecoUrls = resolveSkillHubEcosystemUrls();\n try {\n const buffer = await downloadSkillHubZipFromEcosystem(ecoUrls, slug);\n let resolvedVersion = '1.0.0';\n try { resolvedVersion = (await getSkillHubSkillFiles(slug)).version; } catch { /* keep default */ }\n return { buffer, skillId: isValidSkillId(slug) ? slug : 'unknown', version: resolvedVersion };\n } catch {\n const { buffer, version: resolvedVersion } = await downloadSkillHubZipBuffer(slug);\n return { buffer, skillId: isValidSkillId(slug) ? slug : 'unknown', version: resolvedVersion };\n }\n },\n};\n\nregisterMarketplaceAdapter({\n adapter: skillHubMarketplaceAdapter,\n displayName: 'SkillHub',\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"adapter.js","names":[],"sources":["../../../../../../../src/agent/skills/marketplace/adapters/skillhub/adapter.ts"],"sourcesContent":["/**\n * SkillHub (skillhub.cn) skills marketplace adapter.\n */\n\nimport { basename } from 'node:path';\n\nimport type { MarketplaceCategoryOption } from '../store/store-api-client.js';\nimport type { SkillsMarketplaceAdapter } from '../../adapter.types.js';\nimport { sortMarketplaceCategories } from '../../marketplace-category-order.js';\nimport { registerMarketplaceAdapter } from '../../registry.js';\n\n// ─── Constants ───────────────────────────────────────────────────────────────\n\nconst SKILLHUB_API_BASE = 'https://api.skillhub.cn';\nconst MAX_SKILL_ZIP_BYTES = 15 * 1024 * 1024;\nconst MAX_SKILLHUB_README_BYTES = 512 * 1024;\nconst SKILL_ID_RE = /^[a-zA-Z0-9]([a-zA-Z0-9._-]{0,62})$/;\nconst REGISTRY_SKILL_BATCH_CHUNK = 80;\n\nconst DEFAULT_SKILLS_INDEX_URL = 'https://skillhub-1388575217.cos.ap-guangzhou.myqcloud.com/skills.json';\nconst DEFAULT_SEARCH_URL = 'https://lightmake.site/api/v1/search';\nconst DEFAULT_PRIMARY_DOWNLOAD_TEMPLATE = 'https://lightmake.site/api/v1/download?slug={slug}';\nconst DEFAULT_FALLBACK_DOWNLOAD_TEMPLATE =\n 'https://skillhub-1388575217.cos.ap-guangzhou.myqcloud.com/skills/{slug}.zip';\nconst DEFAULT_ALLOWED_DOWNLOAD_HOSTS = new Set([\n 'lightmake.site',\n 'api.skillhub.cn',\n 'skillhub-1388575217.cos.ap-guangzhou.myqcloud.com',\n]);\nconst LIGHTMAKE_SEARCH_MAX = 100;\nconst SKILLSET_DISCOVERY_PAGE_CAP = 25;\nconst MAX_DEFAULT_SLUGS = 200;\n\nconst DEFAULT_CACHE_MS = 5 * 60 * 1000;\nconst MAX_BATCH_CACHE_KEYS = 48;\n\n// ─── Inline helpers ──────────────────────────────────────────────────────────\n\nfunction isValidSkillId(id: string): boolean {\n return SKILL_ID_RE.test(id);\n}\n\n// ─── SkillHub registry types ─────────────────────────────────────────────────\n\ninterface SkillHubSkill {\n slug: string;\n displayName: string;\n summary: string;\n summary_zh?: string;\n category: string;\n iconUrl: string | null;\n source: string;\n labels: { requires_api_key?: string };\n stats: {\n downloads: number;\n installs: number;\n stars: number;\n comments: number;\n versions: number;\n };\n createdAt: number;\n updatedAt: number;\n tags: Record<string, string>;\n}\n\ninterface SkillHubSkillDetail {\n skill: SkillHubSkill;\n latestVersion: {\n version: string;\n changelog: string | null;\n createdAt: number;\n securityReports?: {\n keen?: { status: string; statusText: string; reportUrl?: string };\n sanbu?: { status: string; statusText: string; reportUrl?: string };\n };\n };\n owner: { handle: string; displayName: string; image: string | null };\n}\n\ninterface SkillHubFile { path: string; sha256: string; size: number }\n\ninterface SkillHubRegistryCategoryItem {\n key: string;\n name: string;\n nameEn: string;\n sortOrder: number;\n active: boolean;\n}\n\ninterface SkillHubSkillset {\n id: number;\n slug: string;\n displayName: string;\n summary: string;\n scene: string;\n subScene: string;\n content: string;\n skillSlugs: string[];\n skillCount: number;\n createdAt: number;\n updatedAt: number;\n}\n\n// ─── Ecosystem types ─────────────────────────────────────────────────────────\n\ninterface EcosystemUrls {\n skillsIndexUrl: string;\n searchUrl: string;\n primaryDownloadTemplate: string;\n fallbackDownloadTemplate: string;\n}\n\ninterface CuratedIndexSkill {\n rank?: number;\n slug: string;\n name?: string;\n description?: string;\n version?: string;\n homepage?: string;\n downloads?: number;\n stars?: number;\n score?: number;\n categories?: string[];\n}\n\ninterface CuratedIndex {\n total?: number;\n skills: CuratedIndexSkill[];\n}\n\ninterface LightmakeSearchHit {\n slug: string;\n displayName?: string;\n name?: string;\n summary?: string;\n description?: string;\n description_zh?: string;\n version?: string;\n downloads?: number;\n installs?: number;\n stars?: number;\n owner_name?: string;\n category?: string;\n score?: number;\n updatedAt?: number;\n updated_at?: number;\n /** Origin registry label from Lightmake (e.g. clawhub, community). Detail/download still go\n * through api.skillhub.cn for synced skills. */\n source?: string;\n}\n\ninterface PackageListItem {\n id: string;\n name: string;\n type: string;\n description: string;\n downloads: number;\n author: { username: string; avatarUrl: string | null };\n latestVersion?: string;\n updatedAt: string;\n categories?: string[];\n stars?: number;\n sourceLabel?: string;\n}\n\n// ─── Registry HTTP helpers ───────────────────────────────────────────────────\n\nasync function registryFetchJson<T>(url: string, init?: RequestInit): Promise<T> {\n const res = await fetch(url, {\n ...init,\n headers: { Accept: 'application/json', ...(init?.headers as Record<string, string> | undefined) },\n });\n const text = await res.text();\n if (!res.ok) {\n let msg = `SkillHub request failed (${res.status})`;\n try {\n const j = JSON.parse(text) as { message?: string; error?: string };\n if (j.message) msg = j.message;\n else if (j.error) msg = j.error;\n } catch { if (text) msg = text.slice(0, 200); }\n throw new Error(msg);\n }\n try { return JSON.parse(text) as T; }\n catch { throw new Error('SkillHub returned invalid JSON'); }\n}\n\nfunction basenameSkillPath(p: string): string {\n const norm = p.replace(/\\\\/g, '/');\n const parts = norm.split('/');\n return parts[parts.length - 1] || norm;\n}\n\nfunction pickSkillHubDocFilePath(files: SkillHubFile[]): string | null {\n const rows = files.map((f) => ({\n path: f.path.replace(/\\\\/g, '/'),\n base: basenameSkillPath(f.path).toLowerCase(),\n }));\n const firstBase = (name: string) => rows.find((r) => r.base === name.toLowerCase());\n const skillMd = firstBase('SKILL.md') ?? firstBase('skill.md');\n if (skillMd) return skillMd.path;\n const readme = firstBase('README.md') ?? firstBase('readme.md');\n if (readme) return readme.path;\n const how = firstBase('HOW_TO_USE.md');\n if (how) return how.path;\n return null;\n}\n\nfunction assertSkillHubReadmeResponseUrl(finalUrl: string): void {\n let u: URL;\n try { u = new URL(finalUrl); } catch { throw new Error('Invalid SkillHub file response URL'); }\n if (u.protocol !== 'https:') throw new Error('SkillHub file response must use HTTPS');\n const host = u.hostname.toLowerCase();\n if (host === 'api.skillhub.cn') return;\n if (host.endsWith('.myqcloud.com')) return;\n throw new Error('SkillHub file redirect host is not allowlisted');\n}\n\nasync function getSkillHubSkillFileText(slug: string, filePath: string, version?: string): Promise<string> {\n const enc = encodeURIComponent(slug.trim());\n const normPath = filePath.replace(/\\\\/g, '/');\n const sp = new URLSearchParams({ path: normPath });\n if (version?.trim()) sp.set('version', version.trim());\n const url = `${SKILLHUB_API_BASE}/api/v1/skills/${enc}/file?${sp.toString()}`;\n const res = await fetch(url, { redirect: 'follow', headers: { Accept: 'text/markdown,text/plain,*/*' } });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n let msg = `SkillHub file request failed (${res.status})`;\n try {\n const j = JSON.parse(text) as { message?: string; error?: string };\n if (typeof j.message === 'string') msg = j.message;\n else if (typeof j.error === 'string') msg = j.error;\n } catch { if (text) msg = text.slice(0, 200); }\n throw new Error(msg);\n }\n assertSkillHubReadmeResponseUrl(res.url);\n const len = res.headers.get('content-length');\n if (len) {\n const n = Number(len);\n if (Number.isFinite(n) && n > MAX_SKILLHUB_README_BYTES) throw new Error(`SkillHub file exceeds max size`);\n }\n const ab = await res.arrayBuffer();\n if (ab.byteLength > MAX_SKILLHUB_README_BYTES) throw new Error(`SkillHub file exceeds max size`);\n return new TextDecoder('utf-8').decode(ab);\n}\n\nasync function getSkillHubSkill(slug: string): Promise<SkillHubSkillDetail> {\n return registryFetchJson<SkillHubSkillDetail>(`${SKILLHUB_API_BASE}/api/v1/skills/${encodeURIComponent(slug.trim())}`);\n}\n\nasync function getSkillHubSkillFiles(slug: string, version?: string): Promise<{ files: SkillHubFile[]; version: string }> {\n const enc = encodeURIComponent(slug.trim());\n const sp = version ? `?version=${encodeURIComponent(version)}` : '';\n return registryFetchJson<{ files: SkillHubFile[]; version: string }>(`${SKILLHUB_API_BASE}/api/v1/skills/${enc}/files${sp}`);\n}\n\nasync function downloadSkillHubZipBuffer(slug: string, version?: string): Promise<{ buffer: Buffer; version: string }> {\n const enc = encodeURIComponent(slug.trim());\n let url = `${SKILLHUB_API_BASE}/api/v1/download?slug=${enc}`;\n if (version?.trim()) url += `&version=${encodeURIComponent(version.trim())}`;\n const res = await fetch(url, { redirect: 'follow' });\n if (!res.ok) throw new Error(`Failed to download skill archive (${res.status})`);\n const len = res.headers.get('content-length');\n if (len) { const n = Number(len); if (Number.isFinite(n) && n > MAX_SKILL_ZIP_BYTES) throw new Error(`Zip exceeds max size`); }\n const ab = await res.arrayBuffer();\n const buf = Buffer.from(ab);\n if (buf.length > MAX_SKILL_ZIP_BYTES) throw new Error(`Zip exceeds max size`);\n let resolvedVersion = version ?? '1.0.0';\n if (!version?.trim()) {\n try { resolvedVersion = (await getSkillHubSkillFiles(slug)).version; } catch { /* keep default */ }\n }\n return { buffer: buf, version: resolvedVersion };\n}\n\nasync function batchGetSkillHubSkills(slugs: string[]): Promise<SkillHubSkillDetail[]> {\n if (slugs.length === 0) return [];\n const response = await registryFetchJson<{ count: number; items: SkillHubSkillDetail[]; missing: string[] }>(\n `${SKILLHUB_API_BASE}/api/v1/skills/batch`,\n { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ slugs }) },\n );\n return response.items ?? [];\n}\n\nasync function listSkillHubRegistryCategories(): Promise<SkillHubRegistryCategoryItem[]> {\n const raw = await registryFetchJson<{ count?: number; items?: SkillHubRegistryCategoryItem[] }>(\n `${SKILLHUB_API_BASE}/api/v1/categories`,\n );\n const items = Array.isArray(raw.items) ? raw.items : [];\n return items.filter((c) => c && typeof c.key === 'string' && c.key.trim().length > 0 && c.active !== false);\n}\n\nasync function listSkillHubSkillsets(opts: { page?: number; pageSize?: number; keyword?: string; scene?: string } = {}): Promise<{ skillSets: SkillHubSkillset[]; total: number }> {\n const page = opts.page ?? 1;\n const pageSize = opts.pageSize ?? 20;\n const sp = new URLSearchParams({ page: String(page), pageSize: String(pageSize) });\n if (opts.keyword?.trim()) sp.set('keyword', opts.keyword.trim());\n if (opts.scene?.trim()) sp.set('scene', opts.scene.trim());\n return registryFetchJson<{ skillSets: SkillHubSkillset[]; total: number }>(`${SKILLHUB_API_BASE}/api/v1/skillsets?${sp.toString()}`);\n}\n\nasync function getDefaultSkillSlugs(): Promise<string[]> {\n const slugs = new Set<string>();\n let page = 1;\n const pageSize = 50;\n let total = Infinity;\n while (page <= SKILLSET_DISCOVERY_PAGE_CAP && slugs.size < MAX_DEFAULT_SLUGS) {\n const response = await listSkillHubSkillsets({ page, pageSize });\n total = response.total;\n for (const skillset of response.skillSets) {\n for (const slug of skillset.skillSlugs) slugs.add(slug);\n }\n if (page * pageSize >= total) break;\n page += 1;\n }\n return Array.from(slugs).slice(0, MAX_DEFAULT_SLUGS);\n}\n\nasync function searchSkillHubSkills(query: string, maxSlugs = 200): Promise<{ slugs: string[]; total: number }> {\n const keyword = query.trim();\n if (!keyword) return { slugs: [], total: 0 };\n const slugs: string[] = [];\n const seen = new Set<string>();\n let page = 1;\n const batchSize = 50;\n while (page <= SKILLSET_DISCOVERY_PAGE_CAP) {\n const response = await listSkillHubSkillsets({ page, pageSize: batchSize, keyword });\n for (const skillset of response.skillSets) {\n for (const slug of skillset.skillSlugs) {\n if (!seen.has(slug)) { seen.add(slug); slugs.push(slug); }\n }\n }\n if (page * batchSize >= response.total) break;\n page += 1;\n }\n const capped = slugs.slice(0, maxSlugs);\n return { slugs: capped, total: capped.length };\n}\n\n// ─── Ecosystem helpers ───────────────────────────────────────────────────────\n\nfunction templateWithSlug(template: string, slug: string): string {\n const raw = template.trim();\n if (!raw) return '';\n if (raw.includes('{slug}')) return raw.replaceAll('{slug}', encodeURIComponent(slug.trim()));\n const base = raw.replace(/\\/$/, '');\n return `${base}/${encodeURIComponent(slug.trim())}.zip`;\n}\n\nfunction hostFromTemplate(template: string): string | undefined {\n const t = templateWithSlug(template, 'x');\n try { return new URL(t).hostname.toLowerCase(); } catch { return undefined; }\n}\n\nfunction resolveSkillHubEcosystemUrls(): EcosystemUrls {\n return {\n skillsIndexUrl: process.env.XOPC_SKILLHUB_SKILLS_INDEX_URL?.trim() || DEFAULT_SKILLS_INDEX_URL,\n searchUrl: process.env.XOPC_SKILLHUB_SEARCH_URL?.trim() || DEFAULT_SEARCH_URL,\n primaryDownloadTemplate: process.env.XOPC_SKILLHUB_PRIMARY_DOWNLOAD_TEMPLATE?.trim() || DEFAULT_PRIMARY_DOWNLOAD_TEMPLATE,\n fallbackDownloadTemplate: process.env.XOPC_SKILLHUB_FALLBACK_DOWNLOAD_TEMPLATE?.trim() || DEFAULT_FALLBACK_DOWNLOAD_TEMPLATE,\n };\n}\n\nfunction allowedDownloadHosts(urls: EcosystemUrls): Set<string> {\n const hosts = new Set(DEFAULT_ALLOWED_DOWNLOAD_HOSTS);\n for (const h of [hostFromTemplate(urls.primaryDownloadTemplate), hostFromTemplate(urls.fallbackDownloadTemplate)]) { if (h) hosts.add(h); }\n try { hosts.add(new URL(urls.skillsIndexUrl).hostname.toLowerCase()); } catch { /* ignore */ }\n try { hosts.add(new URL(urls.searchUrl).hostname.toLowerCase()); } catch { /* ignore */ }\n return hosts;\n}\n\nfunction assertSkillHubDownloadUrlAllowed(downloadUrl: string, urls: EcosystemUrls): URL {\n let u: URL;\n try { u = new URL(downloadUrl); } catch { throw new Error('Invalid SkillHub download URL'); }\n if (u.protocol !== 'https:') throw new Error('SkillHub download URL must use HTTPS');\n if (!allowedDownloadHosts(urls).has(u.hostname.toLowerCase())) throw new Error('SkillHub download URL host is not allowlisted');\n return u;\n}\n\nasync function ecoFetchJson<T>(url: string, init?: RequestInit): Promise<T> {\n const res = await fetch(url, { ...init, headers: { Accept: 'application/json', ...init?.headers } });\n const text = await res.text();\n if (!res.ok) {\n let msg = `SkillHub ecosystem request failed (${res.status})`;\n try { const j = JSON.parse(text) as { message?: string; error?: string }; if (j.message) msg = j.message; else if (j.error) msg = j.error; } catch { if (text) msg = text.slice(0, 200); }\n throw new Error(msg);\n }\n try { return JSON.parse(text) as T; } catch { throw new Error('SkillHub ecosystem returned invalid JSON'); }\n}\n\nasync function fetchSkillHubCuratedIndex(urls: EcosystemUrls): Promise<CuratedIndex> {\n const raw = await ecoFetchJson<unknown>(urls.skillsIndexUrl);\n if (Array.isArray(raw)) return { skills: raw as CuratedIndexSkill[] };\n if (raw && typeof raw === 'object' && Array.isArray((raw as CuratedIndex).skills)) return raw as CuratedIndex;\n throw new Error('SkillHub index JSON must be an object with a skills array');\n}\n\nfunction sourceLabelFromHomepage(homepage?: string): string | undefined {\n const h = homepage?.trim().toLowerCase() ?? '';\n if (h.includes('clawhub')) return 'ClawHub';\n if (h.includes('skillhub')) return 'SkillHub';\n return undefined;\n}\n\nfunction curatedSkillsToPackageItems(skills: CuratedIndexSkill[]): PackageListItem[] {\n return skills.map((s) => ({\n id: s.slug,\n name: (s.name ?? s.slug).trim() || s.slug,\n type: 'skill',\n description: (s.description ?? '').trim(),\n downloads: typeof s.downloads === 'number' ? s.downloads : 0,\n author: { username: 'skillhub', avatarUrl: null },\n latestVersion: (s.version ?? '').trim() || undefined,\n updatedAt: String(s.rank ?? s.score ?? 0),\n categories: (s.categories ?? []).map((c) => String(c).trim()).filter(Boolean),\n stars: typeof s.stars === 'number' ? s.stars : undefined,\n sourceLabel: sourceLabelFromHomepage(s.homepage),\n }));\n}\n\nasync function findCuratedIndexSkill(slug: string): Promise<CuratedIndexSkill | null> {\n const want = slug.trim();\n if (!want) return null;\n const ecoUrls = resolveSkillHubEcosystemUrls();\n try {\n const idx = await cachedFetchSkillHubCuratedIndex(ecoUrls);\n return idx.skills.find((s) => s.slug?.trim() === want) ?? null;\n } catch {\n return null;\n }\n}\n\nfunction curatedSkillFallbackReadmeMarkdown(skill: CuratedIndexSkill): string {\n const title = (skill.name ?? skill.slug).trim() || skill.slug;\n const desc = (skill.description ?? '').trim() || '_No description._';\n const version = (skill.version ?? '').trim() || '1.0.0';\n return `## ${title}\\n\\n**${skill.slug}** · v${version}\\n\\n${desc}`;\n}\n\nfunction packageDetailFromCuratedSkill(skill: CuratedIndexSkill) {\n const slug = skill.slug.trim();\n const version = (skill.version ?? '').trim() || '1.0.0';\n const categories = (skill.categories ?? []).map((c) => String(c).trim()).filter(Boolean);\n const sourceLabel = sourceLabelFromHomepage(skill.homepage);\n return {\n id: slug,\n name: (skill.name ?? slug).trim() || slug,\n type: 'skill',\n description: (skill.description ?? '').trim(),\n readme: curatedSkillFallbackReadmeMarkdown(skill),\n downloads: typeof skill.downloads === 'number' ? skill.downloads : 0,\n author: {\n username: sourceLabel?.toLowerCase() ?? 'skillhub',\n avatarUrl: null,\n },\n latestVersion: {\n version,\n changelog: null,\n publishedAt: String(skill.rank ?? skill.score ?? 0),\n },\n provider: 'skillhub',\n skillHubInfo: {\n category: categories[0] ?? '',\n installs: 0,\n stars: typeof skill.stars === 'number' ? skill.stars : 0,\n },\n };\n}\n\nfunction lightmakeHitToPackageItem(hit: LightmakeSearchHit): PackageListItem {\n const slug = String(hit.slug || '').trim();\n const desc = (hit.summary ?? hit.description_zh ?? hit.description ?? '').trim() || '';\n const updated = hit.updatedAt ?? hit.updated_at ?? 0;\n const cat = hit.category?.trim();\n return {\n id: slug,\n name: (hit.displayName ?? hit.name ?? slug).trim() || slug,\n type: 'skill',\n description: desc,\n downloads: typeof hit.downloads === 'number' ? hit.downloads : 0,\n author: { username: (hit.owner_name ?? 'skillhub').trim() || 'skillhub', avatarUrl: null },\n latestVersion: (hit.version ?? '').trim() || undefined,\n updatedAt: String(updated),\n categories: cat ? [cat] : [],\n stars: typeof hit.stars === 'number' ? hit.stars : undefined,\n sourceLabel: sourceLabelFromSkillSource(hit.source) ?? 'Lightmake',\n };\n}\n\nasync function searchSkillHubLightmake(urls: EcosystemUrls, query: string, limit: number, timeoutMs = 4000): Promise<PackageListItem[]> {\n const q = query.trim().toLowerCase();\n if (!q) return [];\n const search = new URL(urls.searchUrl);\n if (search.protocol !== 'https:') throw new Error('SkillHub search URL must use HTTPS');\n search.searchParams.set('q', q);\n search.searchParams.set('limit', String(Math.max(1, Math.min(LIGHTMAKE_SEARCH_MAX, limit))));\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const raw = await ecoFetchJson<{ results?: LightmakeSearchHit[] }>(search.toString(), { signal: controller.signal });\n const results = raw.results;\n if (!Array.isArray(results)) return [];\n const out: PackageListItem[] = [];\n for (const item of results) {\n if (!item || typeof item !== 'object') continue;\n const hit = item as LightmakeSearchHit;\n const slug = String(hit.slug ?? '').trim();\n if (!slug) continue;\n out.push(lightmakeHitToPackageItem(hit));\n }\n return out;\n } finally { clearTimeout(timer); }\n}\n\nasync function downloadSkillHubZipFromAllowlistedUrl(urls: EcosystemUrls, downloadUrl: string): Promise<Buffer> {\n const normalized = assertSkillHubDownloadUrlAllowed(downloadUrl, urls);\n const res = await fetch(normalized.toString(), { redirect: 'follow' });\n if (!res.ok) throw new Error(`Failed to download skill archive (${res.status})`);\n const len = res.headers.get('content-length');\n if (len) { const n = Number(len); if (Number.isFinite(n) && n > MAX_SKILL_ZIP_BYTES) throw new Error(`Zip exceeds max size`); }\n const ab = await res.arrayBuffer();\n const buf = Buffer.from(ab);\n if (buf.length > MAX_SKILL_ZIP_BYTES) throw new Error(`Zip exceeds max size`);\n return buf;\n}\n\nasync function downloadSkillHubZipFromEcosystem(urls: EcosystemUrls, slug: string): Promise<Buffer> {\n const primary = templateWithSlug(urls.primaryDownloadTemplate, slug);\n const fallback = templateWithSlug(urls.fallbackDownloadTemplate, slug);\n const candidates = [primary, fallback].filter(Boolean);\n const seen = new Set<string>();\n let lastErr: Error | undefined;\n for (const url of candidates) {\n if (seen.has(url)) continue;\n seen.add(url);\n try { return await downloadSkillHubZipFromAllowlistedUrl(urls, url); }\n catch (e) { lastErr = e instanceof Error ? e : new Error(String(e)); }\n }\n throw lastErr ?? new Error('SkillHub ecosystem download failed');\n}\n\n// ─── In-memory TTL cache ─────────────────────────────────────────────────────\n\ntype CacheEntry<T> = { value: T; expiresAt: number };\n\nfunction cacheTtlMs(): number {\n const raw = process.env.XOPC_SKILLHUB_CACHE_MS?.trim();\n if (raw === '0' || raw === 'false') return 0;\n const n = Number(raw);\n if (!Number.isFinite(n) || n < 0) return DEFAULT_CACHE_MS;\n return n;\n}\n\nfunction getFresh<T>(entry: CacheEntry<T> | undefined): T | undefined {\n if (!entry || entry.expiresAt <= Date.now()) return undefined;\n return entry.value;\n}\n\nconst curatedByIndexUrl = new Map<string, CacheEntry<CuratedIndex>>();\nlet defaultSlugsEntry: CacheEntry<string[]> | undefined;\nlet registryCategoriesEntry: CacheEntry<SkillHubRegistryCategoryItem[]> | undefined;\nconst batchBySlugsKey = new Map<string, CacheEntry<SkillHubSkillDetail[]>>();\nconst lightmakeSearchByQuery = new Map<string, CacheEntry<PackageListItem[]>>();\n\nfunction evictOldestBatchKey(): void {\n const first = batchBySlugsKey.keys().next().value;\n if (first !== undefined) batchBySlugsKey.delete(first);\n}\n\nfunction evictOldestSearchKey(): void {\n const first = lightmakeSearchByQuery.keys().next().value;\n if (first !== undefined) lightmakeSearchByQuery.delete(first);\n}\n\nfunction batchSlugsCacheKey(slugs: string[]): string {\n if (slugs.length === 0) return '';\n return [...slugs].sort().join('\\n');\n}\n\nasync function cachedFetchSkillHubCuratedIndex(urls: EcosystemUrls): Promise<CuratedIndex> {\n const ttl = cacheTtlMs();\n const key = urls.skillsIndexUrl;\n if (ttl > 0) { const hit = getFresh(curatedByIndexUrl.get(key)); if (hit) return hit; }\n const value = await fetchSkillHubCuratedIndex(urls);\n if (ttl > 0) curatedByIndexUrl.set(key, { value, expiresAt: Date.now() + ttl });\n return value;\n}\n\nasync function cachedGetDefaultSkillSlugs(): Promise<string[]> {\n const ttl = cacheTtlMs();\n if (ttl > 0) { const hit = getFresh(defaultSlugsEntry); if (hit) return hit; }\n const value = await getDefaultSkillSlugs();\n if (ttl > 0) defaultSlugsEntry = { value, expiresAt: Date.now() + ttl };\n return value;\n}\n\nasync function cachedListSkillHubRegistryCategories(): Promise<SkillHubRegistryCategoryItem[]> {\n const ttl = cacheTtlMs();\n if (ttl > 0) { const hit = getFresh(registryCategoriesEntry); if (hit) return hit; }\n const value = await listSkillHubRegistryCategories();\n if (ttl > 0) registryCategoriesEntry = { value, expiresAt: Date.now() + ttl };\n return value;\n}\n\nasync function cachedBatchGetSkillHubSkills(slugs: string[]): Promise<SkillHubSkillDetail[]> {\n if (slugs.length === 0) return [];\n const ttl = cacheTtlMs();\n const key = batchSlugsCacheKey(slugs);\n if (ttl > 0) { const hit = getFresh(batchBySlugsKey.get(key)); if (hit) return hit; }\n const value = await batchGetSkillHubSkills(slugs);\n if (ttl > 0) {\n while (batchBySlugsKey.size >= MAX_BATCH_CACHE_KEYS) evictOldestBatchKey();\n batchBySlugsKey.set(key, { value, expiresAt: Date.now() + ttl });\n }\n return value;\n}\n\nasync function cachedSearchSkillHubLightmake(\n urls: EcosystemUrls,\n query: string,\n limit: number,\n): Promise<PackageListItem[]> {\n const q = query.trim().toLowerCase();\n if (!q) return [];\n const ttl = cacheTtlMs();\n const key = `${urls.searchUrl}|${q}|${limit}`;\n if (ttl > 0) { const hit = getFresh(lightmakeSearchByQuery.get(key)); if (hit) return hit; }\n const value = await searchSkillHubLightmake(urls, q, limit);\n if (ttl > 0) {\n while (lightmakeSearchByQuery.size >= MAX_BATCH_CACHE_KEYS) evictOldestSearchKey();\n lightmakeSearchByQuery.set(key, { value, expiresAt: Date.now() + ttl });\n }\n return value;\n}\n\n// ─── Adapter conversion helpers ──────────────────────────────────────────────\n\nfunction humanizeRegistryCategoryKey(slug: string): string {\n return slug.replace(/_/g, '-').split('-').filter(Boolean)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join(' ');\n}\n\nfunction sourceLabelFromSkillSource(source: string | undefined): string | undefined {\n const s = source?.trim();\n if (!s) return undefined;\n const lower = s.toLowerCase();\n if (lower === 'clawhub') return 'ClawHub';\n if (lower === 'lightmake') return 'Lightmake';\n if (lower === 'skillhub') return 'SkillHub';\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nfunction filterByCategory(rows: PackageListItem[], category?: string): PackageListItem[] {\n const want = category?.trim();\n if (!want) return rows;\n return rows.filter((r) => (r.categories ?? []).includes(want));\n}\n\nasync function collectRegistryCategoryKeysFromSlugs(slugs: string[]): Promise<Set<string>> {\n const used = new Set<string>();\n for (let i = 0; i < slugs.length; i += REGISTRY_SKILL_BATCH_CHUNK) {\n const chunk = slugs.slice(i, i + REGISTRY_SKILL_BATCH_CHUNK);\n const details = await cachedBatchGetSkillHubSkills(chunk);\n for (const d of details) {\n const k = d.skill.category?.trim();\n if (k) used.add(k);\n }\n }\n return used;\n}\n\nfunction isPipelineOnlyChangelog(text: string | null | undefined): boolean {\n if (!text?.trim()) return true;\n return /^synced by skillhub pipeline\\.?$/i.test(text.trim());\n}\n\nfunction skillHubFallbackReadmeMarkdown(detail: { skill: SkillHubSkill; latestVersion: { version: string } }): string {\n const s = detail.skill;\n const title = s.displayName?.trim() || s.slug;\n const zh = s.summary_zh?.trim();\n const en = s.summary?.trim();\n const body = zh && en && zh !== en ? `${zh}\\n\\n${en}` : zh || en || '_No description._';\n return `## ${title}\\n\\n**${s.slug}** · v${detail.latestVersion.version}\\n\\n${body}`;\n}\n\nfunction convertSkillHubToPackageListItem(detail: SkillHubSkill): PackageListItem {\n const cat = detail.category?.trim();\n return {\n id: detail.slug,\n name: detail.displayName?.trim() || detail.slug,\n type: 'skill',\n description: detail.summary_zh || detail.summary,\n downloads: detail.stats.downloads,\n author: { username: detail.source || 'skillhub', avatarUrl: null },\n latestVersion: detail.tags.latest || '1.0.0',\n updatedAt: String(detail.updatedAt),\n categories: cat ? [cat] : [],\n stars: detail.stats.stars,\n sourceLabel: sourceLabelFromSkillSource(detail.source),\n };\n}\n\nexport const skillHubMarketplaceAdapter: SkillsMarketplaceAdapter = {\n id: 'skillhub',\n\n async listCategories(_config) {\n const sortByLabel = (a: MarketplaceCategoryOption, b: MarketplaceCategoryOption) =>\n a.label.localeCompare(b.label, 'zh-Hans-CN', { sensitivity: 'base' });\n const ecoUrls = resolveSkillHubEcosystemUrls();\n try {\n const idx = await cachedFetchSkillHubCuratedIndex(ecoUrls);\n if (idx.skills?.length) {\n const map = new Map<string, MarketplaceCategoryOption>();\n for (const s of idx.skills) {\n for (const raw of s.categories ?? []) {\n const label = String(raw).trim();\n if (label) map.set(label, { id: label, label });\n }\n }\n return sortMarketplaceCategories(\n Array.from(map.values()).filter((c) => c.id.trim() && c.label.trim()),\n sortByLabel,\n );\n }\n } catch { /* fall through: registry-backed catalog */ }\n try {\n const [taxonomy, slugs] = await Promise.all([\n cachedListSkillHubRegistryCategories(),\n cachedGetDefaultSkillSlugs(),\n ]);\n const usedKeys = await collectRegistryCategoryKeysFromSlugs(slugs);\n const taxByKey = new Map(taxonomy.map((t) => [t.key, t] as const));\n const options: MarketplaceCategoryOption[] = [];\n for (const key of usedKeys) {\n const t = taxByKey.get(key);\n const label = t?.name?.trim() || t?.nameEn?.trim() || humanizeRegistryCategoryKey(key).trim();\n if (!label) continue;\n options.push({ id: key, label });\n }\n return sortMarketplaceCategories(options, (a, b) => {\n const oa = taxByKey.get(a.id)?.sortOrder ?? 999;\n const ob = taxByKey.get(b.id)?.sortOrder ?? 999;\n if (oa !== ob) return oa - ob;\n return sortByLabel(a, b);\n });\n } catch { return []; }\n },\n\n async listPackages(_config, params) {\n const pageSize = params.pageSize ?? 20;\n const page = params.page ?? 1;\n const ecoUrls = resolveSkillHubEcosystemUrls();\n\n if (params.q?.trim()) {\n const q = params.q.trim();\n let rows: PackageListItem[] = [];\n try {\n rows = await cachedSearchSkillHubLightmake(ecoUrls, q, 100);\n } catch {\n // Lightmake unavailable — fall back to the registry skillset scan. We do NOT run this\n // when Lightmake returned zero hits: that would queue ~40 sequential HTTP calls just to\n // confirm \"no results\", and the empty state UI is the better answer for the user.\n try {\n const searchResult = await searchSkillHubSkills(q, 200);\n const details = await cachedBatchGetSkillHubSkills(searchResult.slugs);\n rows = details.map((d) => convertSkillHubToPackageListItem(d.skill));\n } catch {\n rows = [];\n }\n }\n rows = filterByCategory(rows, params.category);\n if (params.sort === 'downloads') rows = [...rows].sort((a, b) => b.downloads - a.downloads);\n else if (params.sort === 'newest') rows = [...rows].sort((a, b) => Number(b.updatedAt) - Number(a.updatedAt));\n const total = rows.length;\n const start = (page - 1) * pageSize;\n const items = rows.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'skillhub' };\n }\n\n try {\n const idx = await cachedFetchSkillHubCuratedIndex(ecoUrls);\n let skills = [...idx.skills].filter((s) => s.slug?.trim());\n if (skills.length > 0) {\n if (params.category?.trim()) {\n const want = params.category.trim();\n skills = skills.filter((s) => (s.categories ?? []).some((x) => String(x).trim() === want));\n }\n if (params.sort === 'downloads') skills.sort((a, b) => (b.downloads ?? 0) - (a.downloads ?? 0));\n else if (params.sort === 'newest') skills.sort((a, b) => (a.rank ?? 999) - (b.rank ?? 999));\n const rows = curatedSkillsToPackageItems(skills);\n const total = rows.length;\n const start = (page - 1) * pageSize;\n const items = rows.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'skillhub' };\n }\n } catch { /* fall through */ }\n\n const slugs = await cachedGetDefaultSkillSlugs();\n if (params.category?.trim()) {\n const details = await cachedBatchGetSkillHubSkills(slugs);\n let allItems = details.map((d) => convertSkillHubToPackageListItem(d.skill));\n allItems = filterByCategory(allItems, params.category);\n if (params.sort === 'downloads') allItems = [...allItems].sort((a, b) => b.downloads - a.downloads);\n else if (params.sort === 'newest') allItems = [...allItems].sort((a, b) => Number(b.updatedAt) - Number(a.updatedAt));\n const total = allItems.length;\n const start = (page - 1) * pageSize;\n const items = allItems.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'skillhub' };\n }\n\n const total = slugs.length;\n const start = (page - 1) * pageSize;\n const paginatedSlugs = slugs.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n const details = await cachedBatchGetSkillHubSkills(paginatedSlugs);\n const items = details.map((d) => convertSkillHubToPackageListItem(d.skill));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'skillhub' };\n },\n\n async getPackageDetail(_config, packageName) {\n const slug = packageName.trim();\n let detail: SkillHubSkillDetail;\n try {\n detail = await getSkillHubSkill(slug);\n } catch (registryErr) {\n const curated = await findCuratedIndexSkill(slug);\n if (curated) return packageDetailFromCuratedSkill(curated);\n throw registryErr;\n }\n const version = detail.latestVersion.version;\n const changelog = detail.latestVersion.changelog;\n\n let readme: string | null = null;\n let docPath: string | null = null;\n try {\n const { files } = await getSkillHubSkillFiles(slug, version);\n docPath = pickSkillHubDocFilePath(files);\n if (docPath) readme = await getSkillHubSkillFileText(slug, docPath, version);\n } catch { readme = null; }\n\n const trimmed = readme?.trim() ?? '';\n const docBase = docPath ? basename(docPath.replace(/\\\\/g, '/')).toLowerCase() : '';\n const isSkillMd = docBase === 'skill.md';\n\n if (!trimmed) {\n readme = skillHubFallbackReadmeMarkdown(detail);\n } else if (isSkillMd) {\n readme = trimmed;\n if (changelog?.trim() && !isPipelineOnlyChangelog(changelog)) {\n readme = `${trimmed}\\n\\n---\\n\\n## Changelog\\n\\n${changelog.trim()}`;\n }\n } else {\n readme = trimmed;\n if (changelog?.trim() && !isPipelineOnlyChangelog(changelog)) {\n readme = `${trimmed}\\n\\n---\\n\\n## Changelog\\n\\n${changelog.trim()}`;\n }\n }\n\n return {\n id: detail.skill.slug,\n name: detail.skill.slug,\n type: 'skill',\n description: detail.skill.summary_zh || detail.skill.summary,\n readme,\n downloads: detail.skill.stats.downloads,\n author: {\n username: detail.owner.handle,\n avatarUrl: detail.owner.image,\n },\n latestVersion: {\n version: detail.latestVersion.version,\n changelog: detail.latestVersion.changelog,\n publishedAt: String(detail.latestVersion.createdAt),\n },\n provider: 'skillhub',\n skillHubInfo: {\n category: detail.skill.category,\n installs: detail.skill.stats.installs,\n stars: detail.skill.stats.stars,\n securityReports: detail.latestVersion.securityReports,\n },\n };\n },\n\n async downloadPackage(_config, packageName, version) {\n const slug = packageName.trim();\n if (version?.trim()) {\n const { buffer, version: resolvedVersion } = await downloadSkillHubZipBuffer(slug, version);\n return { buffer, skillId: isValidSkillId(slug) ? slug : 'unknown', version: resolvedVersion };\n }\n const ecoUrls = resolveSkillHubEcosystemUrls();\n try {\n const buffer = await downloadSkillHubZipFromEcosystem(ecoUrls, slug);\n let resolvedVersion = '1.0.0';\n try { resolvedVersion = (await getSkillHubSkillFiles(slug)).version; } catch { /* keep default */ }\n return { buffer, skillId: isValidSkillId(slug) ? slug : 'unknown', version: resolvedVersion };\n } catch {\n const { buffer, version: resolvedVersion } = await downloadSkillHubZipBuffer(slug);\n return { buffer, skillId: isValidSkillId(slug) ? slug : 'unknown', version: resolvedVersion };\n }\n },\n};\n\nregisterMarketplaceAdapter({\n adapter: skillHubMarketplaceAdapter,\n displayName: 'SkillHub',\n});\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { join } from "path";
|
|
4
3
|
import { readFile, readdir } from "fs/promises";
|
|
4
|
+
import { join } from "path";
|
|
5
5
|
//#region src/agent/skills/scanner.ts
|
|
6
6
|
/**
|
|
7
7
|
* Skill security scanner — scans skill directories for potentially dangerous code patterns.
|
|
@@ -2,9 +2,9 @@ import { init_paths, resolveSkillsDir } from "../../config/paths.js";
|
|
|
2
2
|
import { parseFrontmatter } from "../../markdown/frontmatter.js";
|
|
3
3
|
import { fuzzyFindText, normalizeForFuzzyMatch, normalizeToLF, restoreLineEndings } from "../tools/edit-diff.js";
|
|
4
4
|
import { formatScanSummary, scanSkillDirectory } from "./scanner.js";
|
|
5
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
5
6
|
import { join, resolve, sep } from "path";
|
|
6
7
|
import { existsSync, realpathSync } from "fs";
|
|
7
|
-
import { mkdir, writeFile } from "fs/promises";
|
|
8
8
|
//#region src/agent/skills/skill-manage-ops.ts
|
|
9
9
|
/**
|
|
10
10
|
* Shared logic for the skill_manage agent tool (create / edit / patch / delete / write_file / remove_file).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { resolveStateDir } from "../../config/paths-state.js";
|
|
2
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
3
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { resolveStateDir } from "../../config/paths-state.js";
|
|
4
4
|
import { init_paths, resolveBundledSkillsDir } from "../../config/paths.js";
|
|
5
5
|
import { createSkillConfigManager, isSkillEnabled } from "./config.js";
|
|
6
6
|
import { formatSkillsForPrompt, selectSkillsVisibleInPrompt } from "./format-skills-prompt.js";
|
|
@@ -6,6 +6,12 @@ export type CronjobToolParams = {
|
|
|
6
6
|
name?: string;
|
|
7
7
|
schedule?: string;
|
|
8
8
|
message?: string;
|
|
9
|
+
workflowDefinitionId?: string;
|
|
10
|
+
workflowGoal?: string;
|
|
11
|
+
workflowInputJson?: string;
|
|
12
|
+
waitForCompletion?: boolean;
|
|
13
|
+
deliveryChannel?: string;
|
|
14
|
+
deliveryTo?: string;
|
|
9
15
|
timezone?: string;
|
|
10
16
|
sessionTarget?: 'main' | 'isolated';
|
|
11
17
|
agentId?: string;
|