@xopcai/xopc 0.0.82 → 0.0.84
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/README.md +3 -1
- package/README.zh-CN.md +3 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +2 -3
- package/dist/extensions/feishu/src/outbound/media-load.js.map +1 -1
- package/dist/extensions/feishu/src/schema/config-schema.d.ts +6 -6
- package/dist/extensions/telegram/src/config-schema.d.ts +6 -6
- package/dist/extensions/telegram/src/plugin.d.ts +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/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/api/api.js +3 -3
- 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/config-schema.d.ts +3 -3
- 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/gateway/static/root/assets/agents-tR-nNP04.js +222 -0
- package/dist/gateway/static/root/assets/{apps-page-pJ27dsqn.js → apps-page-BDw6SP-d.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-DEFd-jj1.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-D1KYmOmi.js → channels-status-swr-DI5FHdGe.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-api-Y2wfSJVI.js → cron-api-BSqY8LwW.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-page-B97KU_RG.js → cron-page-D7lVDjcR.js} +1 -1
- package/dist/gateway/static/root/assets/{dist-CboA_Css.js → dist-CqNMNhJM.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DN_zNmpo.js → extension-debug-page-gf2L0kY_.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BUXtOzv5.js → extension-page-CQo2Xsmg.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-C2dX4KCW.js → extension-settings-page-CZf0WoZg.js} +1 -1
- package/dist/gateway/static/root/assets/fetch-2iRFmd3n.js +3 -0
- package/dist/gateway/static/root/assets/{field-primitives-B9rOLqdm.js → field-primitives-DTtlp-l8.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-DvfiRVrc.js → heartbeat-config-api-B0drdQEJ.js} +1 -1
- package/dist/gateway/static/root/assets/{index-DQuaMye9.js → index-0Gt3TG4j.js} +94 -85
- package/dist/gateway/static/root/assets/index-BuFldCsB.css +1 -0
- package/dist/gateway/static/root/assets/{logs-page-BQuBpHcc.js → logs-page-DMuORLfC.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-_UO8g6NN.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-2Yu-FASs.js → settings-form-section-DkmHkknc.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-Cz8FoW_A.js +3 -0
- package/dist/gateway/static/root/assets/skills-page-HrUOxF7H.js +2 -0
- package/dist/gateway/static/root/assets/{theme-store-DnwYutiX.js → theme-store-D01dJt95.js} +1 -1
- package/dist/gateway/static/root/assets/{utils-D2Gn2qod.js → utils-BFwcR6pL.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-JF8-aqc5.js +1 -0
- package/dist/gateway/static/root/index.html +4 -4
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-instance-gateway.d.ts +50 -0
- package/dist/src/agent/agent-instance-gateway.js +1 -0
- package/dist/src/agent/agent-manager.d.ts +20 -14
- package/dist/src/agent/agent-manager.js +74 -186
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/background-review/coordinator.d.ts +61 -0
- package/dist/src/agent/background-review/coordinator.js +120 -0
- package/dist/src/agent/background-review/coordinator.js.map +1 -0
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
- package/dist/src/agent/child-agent-factory.d.ts +14 -0
- package/dist/src/agent/child-agent-factory.js +2 -8
- package/dist/src/agent/child-agent-factory.js.map +1 -1
- package/dist/src/agent/context/workspace-seed.js +3 -3
- package/dist/src/agent/embedded/index.d.ts +1 -2
- package/dist/src/agent/embedded/index.js +2 -3
- package/dist/src/agent/embedded/run-for-session.d.ts +2 -2
- package/dist/src/agent/embedded/run-for-session.js.map +1 -1
- package/dist/src/agent/embedded/runs.d.ts +32 -0
- package/dist/src/agent/embedded/runs.js +79 -19
- package/dist/src/agent/embedded/runs.js.map +1 -1
- package/dist/src/agent/embedded/session-manager-cache.d.ts +14 -0
- package/dist/src/agent/embedded/session-manager-cache.js +32 -11
- package/dist/src/agent/embedded/session-manager-cache.js.map +1 -1
- package/dist/src/agent/embedded/session-runner.d.ts +37 -7
- package/dist/src/agent/embedded/session-runner.js +184 -153
- package/dist/src/agent/embedded/session-runner.js.map +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.d.ts +57 -9
- package/dist/src/agent/embedded/session-tool-result-guard.js +159 -67
- package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
- package/dist/src/agent/goals/goal-run-store.js +4 -4
- package/dist/src/agent/goals/persistent-goal-service.d.ts +84 -0
- package/dist/src/agent/goals/persistent-goal-service.js +139 -0
- package/dist/src/agent/goals/persistent-goal-service.js.map +1 -0
- package/dist/src/agent/goals/post-turn.js +2 -2
- package/dist/src/agent/goals/state.d.ts +1 -1
- package/dist/src/agent/goals/state.js.map +1 -1
- package/dist/src/agent/image/load-image-media.js +1 -1
- package/dist/src/agent/inbound/inbound-loop.d.ts +77 -0
- package/dist/src/agent/inbound/inbound-loop.js +226 -0
- package/dist/src/agent/inbound/inbound-loop.js.map +1 -0
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +80 -0
- package/dist/src/agent/inbound/turn-dispatcher.js +138 -0
- package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -0
- 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/lifecycle/handlers/compaction.d.ts +1 -1
- package/dist/src/agent/lifecycle/handlers/compaction.js.map +1 -1
- package/dist/src/agent/lifecycle/manager.d.ts +1 -1
- package/dist/src/agent/lifecycle/manager.js.map +1 -1
- package/dist/src/agent/lifecycle/types.d.ts +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.d.ts +12 -2
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js.map +1 -1
- package/dist/src/agent/memory/index.js +3 -3
- package/dist/src/agent/memory/plugin-discovery.js +1 -1
- package/dist/src/agent/memory/prefetch-coordinator.d.ts +37 -0
- package/dist/src/agent/memory/prefetch-coordinator.js +45 -0
- package/dist/src/agent/memory/prefetch-coordinator.js.map +1 -0
- package/dist/src/agent/messaging/command-handler.d.ts +5 -1
- package/dist/src/agent/messaging/command-handler.js +24 -96
- package/dist/src/agent/messaging/command-handler.js.map +1 -1
- package/dist/src/agent/messaging/index.d.ts +1 -0
- package/dist/src/agent/messaging/index.js +2 -1
- package/dist/src/agent/messaging/message-router.d.ts +1 -1
- package/dist/src/agent/messaging/message-router.js.map +1 -1
- package/dist/src/agent/messaging/outbound-coordinator.d.ts +82 -0
- package/dist/src/agent/messaging/outbound-coordinator.js +123 -0
- package/dist/src/agent/messaging/outbound-coordinator.js.map +1 -0
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/orchestration/agent-event-handler.d.ts +36 -33
- package/dist/src/agent/orchestration/agent-event-handler.js +212 -174
- package/dist/src/agent/orchestration/agent-event-handler.js.map +1 -1
- package/dist/src/agent/orchestration/agent-orchestrator.d.ts +4 -4
- package/dist/src/agent/orchestration/agent-orchestrator.js +4 -8
- package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
- package/dist/src/agent/orchestration/index.d.ts +1 -1
- package/dist/src/agent/orchestration/index.js +2 -2
- package/dist/src/agent/prompt/service-prompt-builder.js +4 -4
- 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 +1 -1
- package/dist/src/agent/service/async-queue.d.ts +20 -0
- package/dist/src/agent/service/async-queue.js +53 -0
- package/dist/src/agent/service/async-queue.js.map +1 -0
- package/dist/src/agent/service/build-direct-message-content.d.ts +2 -2
- package/dist/src/agent/service/build-direct-message-content.js.map +1 -1
- package/dist/src/agent/service/direct-turn-helpers.d.ts +70 -0
- package/dist/src/agent/service/direct-turn-helpers.js +90 -0
- package/dist/src/agent/service/direct-turn-helpers.js.map +1 -0
- package/dist/src/agent/service/process-direct-one-shot.d.ts +3 -3
- package/dist/src/agent/service/process-direct-one-shot.js +17 -34
- package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.d.ts +2 -2
- package/dist/src/agent/service/process-direct-streaming.js +122 -168
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service/webchat-tts.d.ts +2 -2
- package/dist/src/agent/service/webchat-tts.js +1 -1
- package/dist/src/agent/service/webchat-tts.js.map +1 -1
- package/dist/src/agent/service.d.ts +62 -167
- package/dist/src/agent/service.js +177 -786
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/session/index.d.ts +4 -0
- package/dist/src/agent/session/index.js +5 -1
- package/dist/src/agent/session/session-config-service.d.ts +68 -0
- package/dist/src/agent/session/session-config-service.js +172 -0
- package/dist/src/agent/session/session-config-service.js.map +1 -0
- package/dist/src/agent/session/session-context.d.ts +27 -19
- package/dist/src/agent/session/session-context.js +39 -24
- package/dist/src/agent/session/session-context.js.map +1 -1
- package/dist/src/agent/session/session-hydrator.d.ts +42 -0
- package/dist/src/agent/session/session-hydrator.js +66 -0
- package/dist/src/agent/session/session-hydrator.js.map +1 -0
- package/dist/src/agent/session/session-inspector.d.ts +80 -0
- package/dist/src/agent/session/session-inspector.js +119 -0
- package/dist/src/agent/session/session-inspector.js.map +1 -0
- package/dist/src/agent/session/session-state-bag.d.ts +83 -0
- package/dist/src/agent/session/session-state-bag.js +192 -0
- package/dist/src/agent/session/session-state-bag.js.map +1 -0
- 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.d.ts +0 -2
- package/dist/src/agent/skills/index.js +3 -5
- package/dist/src/agent/skills/index.js.map +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js +11 -6
- package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js.map +1 -1
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js +35 -7
- 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 +2 -2
- package/dist/src/agent/skills/skill-manager.js +1 -1
- package/dist/src/agent/tools/browser/tool/browser-use-tool.d.ts +7 -0
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js +37 -0
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
- package/dist/src/agent/tools/delegate-tool.d.ts +7 -0
- package/dist/src/agent/tools/delegate-tool.js +2 -1
- package/dist/src/agent/tools/delegate-tool.js.map +1 -1
- package/dist/src/agent/tools/dreaming-tool.js +1 -1
- package/dist/src/agent/tools/executor.d.ts +34 -15
- package/dist/src/agent/tools/executor.js +44 -79
- package/dist/src/agent/tools/executor.js.map +1 -1
- package/dist/src/agent/tools/factory.d.ts +6 -0
- package/dist/src/agent/tools/factory.js +63 -4
- 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/skills-tools.js +1 -1
- package/dist/src/agent/tools/tts-tool.js +1 -1
- package/dist/src/agent/tools/write.js +1 -1
- package/dist/src/agent/workspace-runtime/registry.d.ts +48 -0
- package/dist/src/agent/workspace-runtime/registry.js +59 -0
- package/dist/src/agent/workspace-runtime/registry.js.map +1 -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/cdp-local-launcher.js +4 -3
- package/dist/src/browser/cdp-local-launcher.js.map +1 -1
- package/dist/src/browser/index.d.ts +1 -0
- package/dist/src/browser/index.js +2 -1
- package/dist/src/browser/manager.js +3 -2
- package/dist/src/browser/manager.js.map +1 -1
- package/dist/src/browser/providers/browser-ext-install.js +4 -4
- package/dist/src/browser/providers/browser-use.js +2 -1
- package/dist/src/browser/providers/browser-use.js.map +1 -1
- package/dist/src/browser/providers/browserbase.js +2 -1
- package/dist/src/browser/providers/browserbase.js.map +1 -1
- package/dist/src/browser/providers/cloakbrowser.js +7 -6
- package/dist/src/browser/providers/cloakbrowser.js.map +1 -1
- package/dist/src/browser/providers/playwright-doctor.d.ts +2 -0
- package/dist/src/browser/providers/playwright-doctor.js +7 -3
- package/dist/src/browser/providers/playwright-doctor.js.map +1 -1
- package/dist/src/browser/readiness.d.ts +33 -0
- package/dist/src/browser/readiness.js +138 -0
- package/dist/src/browser/readiness.js.map +1 -0
- package/dist/src/browser/stealth.js +2 -2
- 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/channel-domain.d.ts +1 -1
- package/dist/src/channels/config-helpers.d.ts +1 -1
- package/dist/src/channels/config-helpers.js.map +1 -1
- package/dist/src/channels/heartbeat-scheduler.d.ts +40 -0
- package/dist/src/channels/heartbeat-scheduler.js +94 -0
- package/dist/src/channels/heartbeat-scheduler.js.map +1 -0
- package/dist/src/channels/lifecycle-supervisor.d.ts +81 -0
- package/dist/src/channels/lifecycle-supervisor.js +263 -0
- package/dist/src/channels/lifecycle-supervisor.js.map +1 -0
- package/dist/src/channels/manager.d.ts +34 -68
- package/dist/src/channels/manager.js +107 -477
- package/dist/src/channels/manager.js.map +1 -1
- package/dist/src/channels/outbound/deliver.d.ts +1 -1
- package/dist/src/channels/outbound/deliver.js.map +1 -1
- package/dist/src/channels/outbound/persist-store.js +1 -1
- package/dist/src/channels/outbound-sender.d.ts +51 -0
- package/dist/src/channels/outbound-sender.js +125 -0
- package/dist/src/channels/outbound-sender.js.map +1 -0
- package/dist/src/channels/pairing/allow-from-file.js +1 -1
- package/dist/src/channels/pairing/pairing-service.d.ts +3 -10
- package/dist/src/channels/pairing/pairing-service.js.map +1 -1
- package/dist/src/channels/pairing/pairing-store.js +2 -2
- package/dist/src/channels/pairing/pairing-types.d.ts +15 -0
- package/dist/src/channels/pairing/pairing-types.js +1 -0
- package/dist/src/channels/plugin-registry.d.ts +22 -0
- package/dist/src/channels/plugin-registry.js +44 -0
- package/dist/src/channels/plugin-registry.js.map +1 -0
- package/dist/src/channels/plugin-types.d.ts +1 -1
- package/dist/src/channels/plugins/types.adapters.d.ts +2 -2
- package/dist/src/channels/security-helpers.d.ts +1 -1
- package/dist/src/channels/security-helpers.js.map +1 -1
- package/dist/src/channels/setup-wizard.d.ts +1 -1
- package/dist/src/chat-commands/builtins/config.js +2 -2
- package/dist/src/chat-commands/context.js +1 -1
- package/dist/src/cli/command-catalog.js +110 -8
- package/dist/src/cli/command-catalog.js.map +1 -1
- package/dist/src/cli/command-loaders.js +2 -0
- package/dist/src/cli/command-loaders.js.map +1 -1
- package/dist/src/cli/command-manifest.js +9 -1
- package/dist/src/cli/command-manifest.js.map +1 -1
- package/dist/src/cli/commands/agent/stream-renderer.js +1 -1
- package/dist/src/cli/commands/agent/stream-renderer.js.map +1 -1
- package/dist/src/cli/commands/agent.js +4 -4
- package/dist/src/cli/commands/agent.js.map +1 -1
- package/dist/src/cli/commands/browser-cli-helpers.js +2 -1
- package/dist/src/cli/commands/browser-cli-helpers.js.map +1 -1
- package/dist/src/cli/commands/config.js +70 -19
- package/dist/src/cli/commands/config.js.map +1 -1
- package/dist/src/cli/commands/cron-cli.d.ts +2 -0
- package/dist/src/cli/commands/cron-cli.js +15 -0
- package/dist/src/cli/commands/cron-cli.js.map +1 -0
- package/dist/src/cli/commands/cron.d.ts +4 -1
- package/dist/src/cli/commands/cron.js +76 -41
- package/dist/src/cli/commands/cron.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/channel-config.js +1 -1
- package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/config-health.js +2 -2
- package/dist/src/cli/commands/doctor/checks/config-health.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/cron-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/cron-health.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/gateway-health.js +2 -2
- package/dist/src/cli/commands/doctor/checks/gateway-health.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/gateway-service.js +2 -2
- package/dist/src/cli/commands/doctor/checks/gateway-service.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +2 -2
- package/dist/src/cli/commands/doctor/checks/state-integrity.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +4 -4
- package/dist/src/cli/commands/doctor/checks/workspace-status.js.map +1 -1
- package/dist/src/cli/commands/extension-dev.js +2 -2
- package/dist/src/cli/commands/extension-dev.js.map +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +2 -2
- package/dist/src/cli/commands/extension-marketplace.js.map +1 -1
- package/dist/src/cli/commands/extension-pack.js +1 -1
- package/dist/src/cli/commands/gateway/call.js +1 -1
- package/dist/src/cli/commands/gateway/call.js.map +1 -1
- package/dist/src/cli/commands/gateway/health.js +1 -1
- package/dist/src/cli/commands/gateway/health.js.map +1 -1
- package/dist/src/cli/commands/gateway/index.d.ts +1 -1
- package/dist/src/cli/commands/gateway/index.js +2 -2
- package/dist/src/cli/commands/gateway/lifecycle-core.d.ts +31 -12
- package/dist/src/cli/commands/gateway/lifecycle-core.js +167 -116
- package/dist/src/cli/commands/gateway/lifecycle-core.js.map +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.d.ts +11 -0
- package/dist/src/cli/commands/gateway/lifecycle.js +102 -0
- package/dist/src/cli/commands/gateway/lifecycle.js.map +1 -0
- package/dist/src/cli/commands/gateway/logs.js +1 -1
- package/dist/src/cli/commands/gateway/logs.js.map +1 -1
- package/dist/src/cli/commands/gateway/probe.js +1 -1
- package/dist/src/cli/commands/gateway/probe.js.map +1 -1
- package/dist/src/cli/commands/gateway/restart-health.d.ts +12 -0
- package/dist/src/cli/commands/gateway/restart-health.js +45 -1
- package/dist/src/cli/commands/gateway/restart-health.js.map +1 -1
- package/dist/src/cli/commands/gateway/restart.js +3 -3
- package/dist/src/cli/commands/gateway/restart.js.map +1 -1
- package/dist/src/cli/commands/gateway/run-foreground.d.ts +0 -1
- package/dist/src/cli/commands/gateway/run-foreground.js +0 -35
- package/dist/src/cli/commands/gateway/run-foreground.js.map +1 -1
- package/dist/src/cli/commands/gateway/service.d.ts +4 -0
- package/dist/src/cli/commands/gateway/service.js +18 -3
- package/dist/src/cli/commands/gateway/service.js.map +1 -1
- package/dist/src/cli/commands/gateway/shared.d.ts +3 -0
- package/dist/src/cli/commands/gateway/shared.js +54 -0
- package/dist/src/cli/commands/gateway/shared.js.map +1 -0
- package/dist/src/cli/commands/gateway/status.js +1 -1
- package/dist/src/cli/commands/gateway/status.js.map +1 -1
- package/dist/src/cli/commands/gateway/stop.js +2 -2
- package/dist/src/cli/commands/gateway/stop.js.map +1 -1
- package/dist/src/cli/commands/gateway/subcommands.js +1 -4
- package/dist/src/cli/commands/gateway/subcommands.js.map +1 -1
- package/dist/src/cli/commands/gateway/token.js +1 -1
- package/dist/src/cli/commands/gateway/token.js.map +1 -1
- package/dist/src/cli/commands/gateway.js +5 -5
- package/dist/src/cli/commands/gateway.js.map +1 -1
- package/dist/src/cli/commands/image.js +2 -2
- package/dist/src/cli/commands/image.js.map +1 -1
- package/dist/src/cli/commands/init.js +31 -4
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/models.d.ts +4 -1
- package/dist/src/cli/commands/models.js +87 -75
- package/dist/src/cli/commands/models.js.map +1 -1
- package/dist/src/cli/commands/onboard/gateway.d.ts +0 -8
- package/dist/src/cli/commands/onboard/gateway.js +48 -49
- package/dist/src/cli/commands/onboard/gateway.js.map +1 -1
- package/dist/src/cli/commands/onboard.js +11 -64
- package/dist/src/cli/commands/onboard.js.map +1 -1
- package/dist/src/cli/commands/profile.d.ts +3 -5
- package/dist/src/cli/commands/profile.js +31 -31
- package/dist/src/cli/commands/profile.js.map +1 -1
- package/dist/src/cli/commands/session/utils.js +1 -1
- package/dist/src/cli/commands/session/utils.js.map +1 -1
- package/dist/src/cli/commands/setup.js +6 -1
- package/dist/src/cli/commands/setup.js.map +1 -1
- package/dist/src/cli/commands/skills.js +1 -1
- package/dist/src/cli/commands/tailscale.js +1 -1
- package/dist/src/cli/commands/tailscale.js.map +1 -1
- package/dist/src/cli/context.d.ts +20 -0
- package/dist/src/cli/context.js +23 -0
- package/dist/src/cli/context.js.map +1 -0
- package/dist/src/cli/extension-cli-register.js +3 -3
- package/dist/src/cli/gateway-run-argv.js +16 -9
- package/dist/src/cli/gateway-run-argv.js.map +1 -1
- package/dist/src/cli/gateway-run-fast-path.js +1 -1
- package/dist/src/cli/gateway-run-fast-path.js.map +1 -1
- package/dist/src/cli/index.d.ts +1 -7
- package/dist/src/cli/index.js +4 -6
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -2
- package/dist/src/config/commands.flags.d.ts +3 -0
- package/dist/src/config/commands.flags.js +11 -0
- package/dist/src/config/commands.flags.js.map +1 -0
- package/dist/src/config/index.d.ts +1 -0
- package/dist/src/config/index.js +6 -5
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/profile.js +2 -2
- package/dist/src/config/schema.d.ts +11 -4
- package/dist/src/config/schema.js +13 -12
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/workspace-path-helpers.d.ts +15 -0
- package/dist/src/config/workspace-path-helpers.js +14 -0
- package/dist/src/config/workspace-path-helpers.js.map +1 -0
- package/dist/src/cron/executor.js +4 -4
- 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/daemon/index.d.ts +0 -1
- package/dist/src/daemon/index.js +1 -2
- package/dist/src/daemon/install-plan.js +3 -2
- package/dist/src/daemon/install-plan.js.map +1 -1
- package/dist/src/daemon/launchd.js +2 -2
- package/dist/src/daemon/systemd.js +2 -2
- package/dist/src/daemon/types.d.ts +0 -6
- package/dist/src/extensions/api.d.ts +1 -1
- package/dist/src/extensions/api.js +2 -2
- package/dist/src/extensions/api.js.map +1 -1
- package/dist/src/extensions/bundle-mcp.js +1 -1
- package/dist/src/extensions/discover-extensions.js +1 -1
- package/dist/src/extensions/extension-registry-impl.d.ts +51 -0
- package/dist/src/extensions/extension-registry-impl.js +117 -0
- package/dist/src/extensions/extension-registry-impl.js.map +1 -0
- package/dist/src/extensions/health.js +1 -1
- package/dist/src/extensions/index.js +3 -2
- package/dist/src/extensions/loader.d.ts +3 -43
- package/dist/src/extensions/loader.js +3 -110
- package/dist/src/extensions/loader.js.map +1 -1
- package/dist/src/extensions/lockfile.js +2 -2
- package/dist/src/extensions/sdk/index.js +2 -1
- package/dist/src/extensions/sdk/index.js.map +1 -1
- package/dist/src/extensions/types/events.d.ts +7 -1
- package/dist/src/gateway/agents-admin.js +2 -2
- package/dist/src/gateway/file-path-classifier.js +2 -2
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/heartbeat/service.js.map +1 -1
- package/dist/src/gateway/hono/app.js +5 -53
- package/dist/src/gateway/hono/app.js.map +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +1 -1
- package/dist/src/gateway/hono/lib/static-ui.js +2 -2
- package/dist/src/gateway/hono/middleware/auth.d.ts +5 -14
- package/dist/src/gateway/hono/middleware/auth.js +89 -126
- package/dist/src/gateway/hono/middleware/auth.js.map +1 -1
- package/dist/src/gateway/hono/middleware/logger.js +1 -1
- package/dist/src/gateway/hono/middleware/logger.js.map +1 -1
- package/dist/src/gateway/hono/middleware/strict-rate-limit.d.ts +14 -0
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js +62 -0
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js.map +1 -0
- package/dist/src/gateway/hono/oauth.js +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +4 -4
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js.map +1 -1
- package/dist/src/gateway/hono/routes/browser.d.ts +20 -0
- package/dist/src/gateway/hono/routes/browser.js +626 -0
- package/dist/src/gateway/hono/routes/browser.js.map +1 -0
- package/dist/src/gateway/hono/routes/commands-skills.js +13 -13
- package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/agents.d.ts +18 -0
- package/dist/src/gateway/hono/routes/config-patch/agents.js +418 -0
- package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -0
- package/dist/src/gateway/hono/routes/config-patch/channels.d.ts +12 -0
- package/dist/src/gateway/hono/routes/config-patch/channels.js +186 -0
- package/dist/src/gateway/hono/routes/config-patch/channels.js.map +1 -0
- package/dist/src/gateway/hono/routes/config-patch/gateway.d.ts +18 -0
- package/dist/src/gateway/hono/routes/config-patch/gateway.js +264 -0
- package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -0
- package/dist/src/gateway/hono/routes/config-patch/index.d.ts +9 -0
- package/dist/src/gateway/hono/routes/config-patch/index.js +6 -0
- package/dist/src/gateway/hono/routes/config-patch/misc.d.ts +23 -0
- package/dist/src/gateway/hono/routes/config-patch/misc.js +139 -0
- package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -0
- package/dist/src/gateway/hono/routes/config-patch/result.d.ts +18 -0
- package/dist/src/gateway/hono/routes/config-patch/result.js +13 -0
- package/dist/src/gateway/hono/routes/config-patch/result.js.map +1 -0
- package/dist/src/gateway/hono/routes/config.js +20 -1764
- package/dist/src/gateway/hono/routes/config.js.map +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +2 -3
- package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
- package/dist/src/gateway/hono/routes/host-fs.js +1 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +10 -5
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/mcp.js +1 -2
- package/dist/src/gateway/hono/routes/mcp.js.map +1 -1
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +32 -32
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/hono/routes/shares.js +4 -4
- package/dist/src/gateway/hono/routes/shares.js.map +1 -1
- package/dist/src/gateway/hono/routes/tunnel.js +1 -1
- package/dist/src/gateway/hono/routes/tunnel.js.map +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +6 -7
- package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
- package/dist/src/gateway/hono/sse.js +2 -2
- package/dist/src/gateway/index.d.ts +1 -1
- package/dist/src/gateway/index.js +4 -2
- package/dist/src/gateway/lock.js +3 -3
- package/dist/src/gateway/rate-limit/auth-policy.d.ts +34 -0
- package/dist/src/gateway/rate-limit/auth-policy.js +49 -0
- package/dist/src/gateway/rate-limit/auth-policy.js.map +1 -0
- package/dist/src/gateway/rate-limit/buckets.d.ts +63 -0
- package/dist/src/gateway/rate-limit/buckets.js +143 -0
- package/dist/src/gateway/rate-limit/buckets.js.map +1 -0
- package/dist/src/gateway/rate-limit/env-flags.d.ts +13 -0
- package/dist/src/gateway/rate-limit/env-flags.js +16 -0
- package/dist/src/gateway/rate-limit/env-flags.js.map +1 -0
- package/dist/src/gateway/rate-limit/index.d.ts +3 -0
- package/dist/src/gateway/rate-limit/index.js +4 -0
- package/dist/src/gateway/run-loop.d.ts +1 -1
- package/dist/src/gateway/run-loop.js +24 -4
- package/dist/src/gateway/run-loop.js.map +1 -1
- package/dist/src/gateway/runtime-config.js +2 -1
- package/dist/src/gateway/runtime-config.js.map +1 -1
- package/dist/src/gateway/security/audit.js +2 -1
- package/dist/src/gateway/security/audit.js.map +1 -1
- package/dist/src/gateway/security/index.d.ts +0 -1
- package/dist/src/gateway/security/index.js +1 -2
- package/dist/src/gateway/security/loopback.d.ts +13 -0
- package/dist/src/gateway/security/loopback.js +45 -0
- package/dist/src/gateway/security/loopback.js.map +1 -0
- package/dist/src/gateway/service/agent-runner.d.ts +108 -0
- package/dist/src/gateway/service/agent-runner.js +184 -0
- package/dist/src/gateway/service/agent-runner.js.map +1 -0
- package/dist/src/gateway/service/config-coordinator.d.ts +119 -0
- package/dist/src/gateway/service/config-coordinator.js +351 -0
- package/dist/src/gateway/service/config-coordinator.js.map +1 -0
- package/dist/src/gateway/service/marketplace-service.d.ts +85 -0
- package/dist/src/gateway/service/marketplace-service.js +239 -0
- package/dist/src/gateway/service/marketplace-service.js.map +1 -0
- package/dist/src/gateway/service/run-gateway-agent.js +5 -5
- package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
- package/dist/src/gateway/service/sessions-api.d.ts +125 -0
- package/dist/src/gateway/service/sessions-api.js +135 -0
- package/dist/src/gateway/service/sessions-api.js.map +1 -0
- package/dist/src/gateway/service.d.ts +30 -360
- package/dist/src/gateway/service.js +122 -904
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/workspace-fs-file-list.js +1 -1
- package/dist/src/gateway/workspace-heartbeat-path.js +1 -2
- package/dist/src/gateway/workspace-heartbeat-path.js.map +1 -1
- package/dist/src/infra/gateway-process-argv.d.ts +4 -0
- package/dist/src/infra/gateway-process-argv.js +26 -0
- package/dist/src/infra/gateway-process-argv.js.map +1 -0
- package/dist/src/infra/gateway-processes.d.ts +5 -0
- package/dist/src/infra/gateway-processes.js +65 -0
- package/dist/src/infra/gateway-processes.js.map +1 -0
- package/dist/src/infra/rate-limit/failure-limiter.d.ts +50 -0
- package/dist/src/infra/rate-limit/failure-limiter.js +100 -0
- package/dist/src/infra/rate-limit/failure-limiter.js.map +1 -0
- package/dist/src/infra/rate-limit/index.d.ts +5 -0
- package/dist/src/infra/rate-limit/index.js +3 -0
- package/dist/src/infra/rate-limit/keyed-store.d.ts +34 -0
- package/dist/src/infra/rate-limit/keyed-store.js +44 -0
- package/dist/src/infra/rate-limit/keyed-store.js.map +1 -0
- package/dist/src/infra/rate-limit/rate-limiter.d.ts +39 -0
- package/dist/src/infra/rate-limit/rate-limiter.js +65 -0
- package/dist/src/infra/rate-limit/rate-limiter.js.map +1 -0
- package/dist/src/infra/restart.d.ts +21 -0
- package/dist/src/infra/restart.js +122 -0
- package/dist/src/infra/restart.js.map +1 -0
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/infra/update-lock.js +3 -3
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/infra/update-startup.js +2 -2
- package/dist/src/infra/write-file-atomic.js +2 -2
- package/dist/src/mcp/channel-bridge.d.ts +0 -6
- package/dist/src/mcp/channel-bridge.js +1 -5
- package/dist/src/mcp/channel-bridge.js.map +1 -1
- package/dist/src/media-shared/http/ssrf-guard.js +1 -1
- 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/session/config-store.js +2 -2
- package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
- package/dist/src/session/parity/sessions-json-file-read.d.ts +2 -1
- package/dist/src/session/parity/sessions-json-file-read.js.map +1 -1
- 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/search-index-cache.js +1 -1
- package/dist/src/session/search-index.js +1 -1
- package/dist/src/session/session-title.js +1 -1
- package/dist/src/session/store.js +5 -5
- package/dist/src/share/share-rate-limit.d.ts +10 -2
- package/dist/src/share/share-rate-limit.js +33 -42
- package/dist/src/share/share-rate-limit.js.map +1 -1
- package/dist/src/share/share-store.js +3 -3
- package/dist/src/tui/backends/embedded-backend.js +16 -12
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/clipboard-image.js +2 -2
- package/dist/src/tui/extension-host/load-extensions.js +1 -1
- package/dist/src/tui/format-tui-hotkeys.js +1 -1
- 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 +1 -1
- package/dist/src/tui/tui-settings.js +1 -1
- package/dist/src/tui/tui-skills-autocomplete.js +1 -1
- package/dist/src/tui/tui.js +1 -2
- package/dist/src/tui/tui.js.map +1 -1
- package/dist/src/tui/xopc-tui-keybindings.d.ts +0 -1
- package/dist/src/tui/xopc-tui-keybindings.js +1 -2
- package/dist/src/tui/xopc-tui-keybindings.js.map +1 -1
- package/dist/src/tunnel/frpc-binary.js +2 -2
- package/dist/src/tunnel/frpc-config.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/pairing-rate-limit.d.ts +10 -2
- package/dist/src/tunnel/pairing-rate-limit.js +19 -15
- package/dist/src/tunnel/pairing-rate-limit.js.map +1 -1
- package/dist/src/tunnel/tunnel-rate-limit.d.ts +6 -3
- package/dist/src/tunnel/tunnel-rate-limit.js +11 -22
- package/dist/src/tunnel/tunnel-rate-limit.js.map +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/factory.js +1 -1
- package/dist/src/voice/tts/index.js +2 -2
- package/dist/src/voice/tts/merge-config.js +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +1 -1
- package/dist/src/voice/tts/service.js +1 -1
- package/dist/src/voice/tts/service.js.map +1 -1
- package/dist/src/voice/tts/speak-core.js +1 -1
- package/package.json +10 -5
- package/dist/gateway/static/root/assets/agents-Cqh1ts38.js +0 -222
- package/dist/gateway/static/root/assets/channels-settings-wTiWStg9.js +0 -1
- package/dist/gateway/static/root/assets/fetch-BAAh_kXG.js +0 -3
- package/dist/gateway/static/root/assets/index-C8yHX-AA.css +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BeiFm0Ms.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-RPAz_Wg_.js +0 -3
- package/dist/gateway/static/root/assets/skills-page-Wu4aNWDx.js +0 -2
- package/dist/gateway/static/root/assets/voice-api-key-field-BxIGhhEL.js +0 -1
- package/dist/src/agent/embedded/session-raw-append-message.d.ts +0 -11
- package/dist/src/agent/embedded/session-raw-append-message.js +0 -15
- package/dist/src/agent/embedded/session-raw-append-message.js.map +0 -1
- package/dist/src/agent/embedded/session-tool-result-guard-wrapper.d.ts +0 -15
- package/dist/src/agent/embedded/session-tool-result-guard-wrapper.js +0 -24
- package/dist/src/agent/embedded/session-tool-result-guard-wrapper.js.map +0 -1
- package/dist/src/agent/embedded/session-tool-result-state.d.ts +0 -17
- package/dist/src/agent/embedded/session-tool-result-state.js +0 -26
- package/dist/src/agent/embedded/session-tool-result-state.js.map +0 -1
- package/dist/src/daemon/launchd-restart-handoff.d.ts +0 -25
- package/dist/src/daemon/launchd-restart-handoff.js +0 -132
- package/dist/src/daemon/launchd-restart-handoff.js.map +0 -1
- package/dist/src/gateway/auth-rate-limit.d.ts +0 -71
- package/dist/src/gateway/auth-rate-limit.js +0 -192
- package/dist/src/gateway/auth-rate-limit.js.map +0 -1
- package/dist/src/gateway/restart-handler.d.ts +0 -14
- package/dist/src/gateway/restart-handler.js +0 -64
- package/dist/src/gateway/restart-handler.js.map +0 -1
- package/dist/src/gateway/security/flood-guard.d.ts +0 -28
- package/dist/src/gateway/security/flood-guard.js +0 -42
- package/dist/src/gateway/security/flood-guard.js.map +0 -1
- package/dist/src/infra/rate-limit.d.ts +0 -38
- package/dist/src/infra/rate-limit.js +0 -60
- package/dist/src/infra/rate-limit.js.map +0 -1
- package/dist/src/infra/restart-intent.d.ts +0 -13
- package/dist/src/infra/restart-intent.js +0 -40
- package/dist/src/infra/restart-intent.js.map +0 -1
- package/dist/src/infra/restart-sentinel.d.ts +0 -23
- package/dist/src/infra/restart-sentinel.js +0 -75
- package/dist/src/infra/restart-sentinel.js.map +0 -1
- package/skills/creative/canvas-design/LICENSE.txt +0 -202
- package/skills/creative/canvas-design/SKILL-zh.md +0 -130
- package/skills/creative/canvas-design/SKILL.md +0 -130
- package/skills/creative/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BigShoulders-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Boldonse-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/DMMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/EricaOne-OFL.txt +0 -94
- package/skills/creative/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/GeistMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Gloock-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Italiana-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Jura-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/NationalPark-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Outfit-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/PixelifySans-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/PoiretOne-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/RedHatMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Silkscreen-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/SmoochSans-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Tektur-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/YoungSerif-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","names":[],"sources":["../../../../../src/gateway/hono/middleware/auth.ts"],"sourcesContent":["import { createMiddleware } from 'hono/factory';\nimport type { Context } from 'hono';\nimport { getConnInfo } from '@hono/node-server/conninfo';\nimport type { GatewayAuthConfig } from '../../../config/schema.js';\nimport {\n getClientIpFromHeaders,\n isAuthRateLimitGloballyDisabled,\n resolveAuthRateLimitConfig,\n resolveAuthRateLimitTracking,\n} from '../../auth-rate-limit.js';\nimport type { ResolvedGatewayAuth } from '../../auth.js';\nimport { resolveClientIpFromRequest } from '../../client-ip.js';\nimport { safeEqualSecret } from '../../security/secret-equal.js';\nimport { authorizeTrustedProxy } from '../../trusted-proxy.js';\nimport { createLogger } from '../../../utils/logger.js';\n\nconst log = createLogger('Hono:Auth');\n\nexport interface AuthConfig {\n token?: string;\n /** Current gateway auth from config (for rate-limit settings); optional. */\n getGatewayAuth?: () => GatewayAuthConfig | undefined;\n getResolvedAuth?: () => ResolvedGatewayAuth;\n getTrustedProxyContext?: () => {\n trustedProxies?: string[];\n allowRealIpFallback?: boolean;\n };\n}\n\n/**\n * Validate token using constant-time comparison to prevent timing attacks.\n */\nfunction validateToken(providedToken: string | undefined, expectedToken: string): boolean {\n if (!providedToken) return false;\n return safeEqualSecret(providedToken, expectedToken);\n}\n\n/**\n * Extract token from Authorization header\n * Supports: \"Bearer <token>\", \"<token>\"\n */\nfunction extractTokenFromHeader(authHeader: string | null): string | null {\n if (!authHeader) return null;\n\n const parts = authHeader.split(' ');\n if (parts.length === 2 && parts[0].toLowerCase() === 'bearer') {\n return parts[1];\n }\n return authHeader;\n}\n\n/**\n * Extract token from query parameter.\n *\n * SECURITY: query-string tokens leak into server logs, Referer headers, and\n * browser history. We accept them only for SSE/WebSocket connections where\n * the `Authorization` header cannot be set by `EventSource`. For normal REST\n * requests prefer the `Authorization: Bearer <token>` header.\n */\nfunction extractTokenFromQuery(url: string): string | null {\n const parsed = new URL(url);\n return parsed.searchParams.get('token');\n}\n\n/** Paths where query-string token auth is acceptable (SSE / WebSocket). */\nconst QUERY_TOKEN_ALLOWED_PATHS = new Set(['/api/events', '/api/ws']);\n\nfunction isQueryTokenAllowedPath(path: string): boolean {\n return QUERY_TOKEN_ALLOWED_PATHS.has(path) || path.startsWith('/api/events');\n}\n\nfunction resolveRemoteAddress(c: Context): string | undefined {\n try {\n return getConnInfo(c).remote.address;\n } catch {\n return undefined;\n }\n}\n\nfunction resolveMiddlewareClientIp(\n c: Context,\n trustedProxies?: string[],\n allowRealIpFallback?: boolean,\n): string {\n if (trustedProxies?.length) {\n return resolveClientIpFromRequest({\n remoteAddress: resolveRemoteAddress(c),\n getHeader: (name) => c.req.header(name),\n trustedProxies,\n allowRealIpFallback,\n });\n }\n return getClientIpFromHeaders({\n get: (name: string) => c.req.header(name) ?? undefined,\n });\n}\n\n/**\n * Create auth middleware for HTTP routes\n */\nexport function auth(config?: AuthConfig) {\n const { token, getGatewayAuth, getResolvedAuth, getTrustedProxyContext } = config || {};\n\n return createMiddleware(async (c, next) => {\n const resolvedAuth = getResolvedAuth?.();\n const authMode = resolvedAuth?.mode ?? (token ? 'token' : 'none');\n\n if (authMode === 'trusted-proxy') {\n const proxyContext = getTrustedProxyContext?.();\n const trustedProxies = proxyContext?.trustedProxies;\n const trustedProxyConfig = resolvedAuth?.trustedProxy;\n\n const rlInput = getGatewayAuth?.()?.rateLimit;\n const rlCfg = resolveAuthRateLimitConfig(rlInput);\n const rateLimitActive = rlCfg.enabled && !isAuthRateLimitGloballyDisabled();\n const clientIp = resolveMiddlewareClientIp(\n c,\n trustedProxies,\n proxyContext?.allowRealIpFallback,\n );\n const origin = c.req.header('origin');\n const tracking = resolveAuthRateLimitTracking({ clientIp, origin, cfg: rlCfg });\n const { limiter, key: rateLimitKey, cfg: activeRlCfg } = tracking;\n\n if (!trustedProxyConfig) {\n if (rateLimitActive) {\n limiter.recordFailure(rateLimitKey, activeRlCfg);\n }\n log.warn(\n { path: c.req.path, method: c.req.method, clientIp, reason: 'trusted_proxy_config_missing' },\n 'HTTP auth rejected: trusted-proxy config missing',\n );\n return c.json({ error: 'Unauthorized', message: 'Trusted-proxy auth is not configured' }, 401);\n }\n\n const result = authorizeTrustedProxy({\n remoteAddress: resolveRemoteAddress(c),\n getHeader: (name) => c.req.header(name),\n trustedProxies,\n trustedProxyConfig,\n });\n\n if (result.ok) {\n if (rateLimitActive) {\n limiter.recordSuccess(rateLimitKey);\n }\n await next();\n return;\n }\n\n if (result.ok === false) {\n if (rateLimitActive) {\n const blocked = limiter.checkBlocked(rateLimitKey, activeRlCfg);\n if (blocked.blocked) {\n log.warn(\n {\n clientIp,\n origin: origin ?? undefined,\n path: c.req.path,\n method: c.req.method,\n attemptCount: activeRlCfg.maxAttempts,\n windowSec: Math.round(activeRlCfg.windowMs / 1000),\n blockDurationSec: Math.round(activeRlCfg.blockDurationMs / 1000),\n retryAfterSec: blocked.retryAfterSec,\n reason: 'auth_failure_rate_limit',\n },\n `Auth rate limit blocked: ${activeRlCfg.maxAttempts} failures in ${activeRlCfg.windowMs / 1000}s, blocking for ${activeRlCfg.blockDurationMs / 1000}s`,\n );\n c.header('Retry-After', String(blocked.retryAfterSec));\n return c.json(\n {\n error: 'Too Many Requests',\n message: 'Too many authentication attempts',\n retryAfter: blocked.retryAfterSec,\n },\n 429,\n );\n }\n limiter.recordFailure(rateLimitKey, activeRlCfg);\n }\n\n log.warn(\n {\n path: c.req.path,\n method: c.req.method,\n clientIp,\n reason: result.reason,\n },\n `HTTP auth rejected: trusted-proxy validation failed (${result.reason})`,\n );\n return c.json({ error: 'Unauthorized', message: 'Trusted-proxy authentication failed' }, 401);\n }\n }\n\n if (authMode === 'none' || !token) {\n return next();\n }\n\n const rlInput = getGatewayAuth?.()?.rateLimit;\n const rlCfg = resolveAuthRateLimitConfig(rlInput);\n const rateLimitActive = rlCfg.enabled && !isAuthRateLimitGloballyDisabled();\n\n const proxyContext = getTrustedProxyContext?.();\n const clientIp = resolveMiddlewareClientIp(\n c,\n proxyContext?.trustedProxies,\n proxyContext?.allowRealIpFallback,\n );\n const origin = c.req.header('origin');\n const tracking = resolveAuthRateLimitTracking({ clientIp, origin, cfg: rlCfg });\n const { limiter, key: rateLimitKey, cfg: activeRlCfg } = tracking;\n\n const authHeader = extractTokenFromHeader(c.req.header('authorization'));\n const requestPath = new URL(c.req.url).pathname;\n const queryToken = isQueryTokenAllowedPath(requestPath)\n ? extractTokenFromQuery(c.req.url)\n : null;\n\n if (!authHeader && queryToken === null && new URL(c.req.url).searchParams.has('token')) {\n log.warn(\n { path: requestPath, method: c.req.method, clientIp },\n 'Token in query string rejected: use Authorization header for this endpoint',\n );\n }\n\n const providedToken = authHeader || queryToken;\n\n if (providedToken && validateToken(providedToken, token)) {\n if (rateLimitActive) {\n limiter.recordSuccess(rateLimitKey);\n }\n await next();\n return;\n }\n\n if (rateLimitActive) {\n const blocked = limiter.checkBlocked(rateLimitKey, activeRlCfg);\n if (blocked.blocked) {\n log.warn(\n {\n clientIp,\n origin: origin ?? undefined,\n path: requestPath,\n method: c.req.method,\n attemptCount: activeRlCfg.maxAttempts,\n windowSec: Math.round(activeRlCfg.windowMs / 1000),\n blockDurationSec: Math.round(activeRlCfg.blockDurationMs / 1000),\n retryAfterSec: blocked.retryAfterSec,\n reason: 'auth_failure_rate_limit',\n },\n `Auth rate limit blocked: ${activeRlCfg.maxAttempts} failures in ${activeRlCfg.windowMs / 1000}s, blocking for ${activeRlCfg.blockDurationMs / 1000}s`,\n );\n c.header('Retry-After', String(blocked.retryAfterSec));\n return c.json(\n {\n error: 'Too Many Requests',\n message: 'Too many authentication attempts',\n retryAfter: blocked.retryAfterSec,\n },\n 429,\n );\n }\n }\n\n if (!providedToken) {\n if (rateLimitActive) {\n limiter.recordFailure(rateLimitKey, activeRlCfg);\n }\n log.warn(\n { path: c.req.path, method: c.req.method, clientIp, reason: 'missing_token' },\n 'HTTP auth rejected: no Bearer or ?token=',\n );\n return c.json({ error: 'Unauthorized', message: 'Missing authentication token' }, 401);\n }\n\n if (!validateToken(providedToken, token)) {\n if (rateLimitActive) {\n limiter.recordFailure(rateLimitKey, activeRlCfg);\n }\n log.warn(\n { path: c.req.path, method: c.req.method, clientIp, reason: 'invalid_token' },\n 'HTTP auth rejected: token mismatch',\n );\n return c.json({ error: 'Unauthorized', message: 'Invalid authentication token' }, 401);\n }\n });\n}\n\nexport interface WebSocketAuthResult {\n valid: boolean;\n error?: string;\n}\n\n/**\n * Validate WebSocket connection token\n */\nexport function validateWebSocketAuth(\n url: URL,\n authHeader: string | null,\n expectedToken?: string\n): WebSocketAuthResult {\n if (!expectedToken) {\n return { valid: true };\n }\n\n const queryToken = url.searchParams.get('token');\n const headerToken = extractTokenFromHeader(authHeader);\n\n const providedToken = queryToken || headerToken;\n\n if (!providedToken) {\n log.warn(\n { path: url.pathname, reason: 'missing_token', hasHeaderToken: Boolean(headerToken) },\n 'WebSocket auth rejected: no token in query or Authorization',\n );\n return { valid: false, error: 'Missing authentication token' };\n }\n\n if (!safeEqualSecret(providedToken, expectedToken)) {\n log.warn({ path: url.pathname, reason: 'invalid_token' }, 'WebSocket auth rejected: token mismatch');\n return { valid: false, error: 'Invalid authentication token' };\n }\n\n return { valid: true };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"auth.js","names":[],"sources":["../../../../../src/gateway/hono/middleware/auth.ts"],"sourcesContent":["import { createMiddleware } from 'hono/factory';\nimport type { Context } from 'hono';\nimport { getConnInfo } from '@hono/node-server/conninfo';\n\nimport type { GatewayAuthConfig } from '../../../config/schema.js';\nimport type { ResolvedGatewayAuth } from '../../auth.js';\nimport { resolveClientIpFromRequest } from '../../client-ip.js';\nimport {\n authPolicyConfig,\n buckets,\n isAuthRateLimitGloballyDisabled,\n resolveAuthRateLimit,\n resolveAuthTracking,\n type ResolvedAuthRateLimitConfig,\n} from '../../rate-limit/index.js';\nimport { getClientIpFromHeaders } from '../../security/loopback.js';\nimport { safeEqualSecret } from '../../security/secret-equal.js';\nimport { authorizeTrustedProxy } from '../../trusted-proxy.js';\nimport { createLogger } from '../../../utils/logger.js';\n\nconst log = createLogger('Hono:Auth');\n\nexport interface AuthConfig {\n token?: string;\n /** Current gateway auth from config (for rate-limit settings); optional. */\n getGatewayAuth?: () => GatewayAuthConfig | undefined;\n getResolvedAuth?: () => ResolvedGatewayAuth;\n getTrustedProxyContext?: () => {\n trustedProxies?: string[];\n allowRealIpFallback?: boolean;\n };\n}\n\nfunction validateToken(providedToken: string | undefined, expectedToken: string): boolean {\n if (!providedToken) return false;\n return safeEqualSecret(providedToken, expectedToken);\n}\n\nfunction extractTokenFromHeader(authHeader: string | null): string | null {\n if (!authHeader) return null;\n const parts = authHeader.split(' ');\n if (parts.length === 2 && parts[0].toLowerCase() === 'bearer') return parts[1];\n return authHeader;\n}\n\n/**\n * SECURITY: query-string tokens leak into server logs, Referer headers, and\n * browser history. We accept them only for SSE/WebSocket connections where\n * the `Authorization` header cannot be set by `EventSource`. For normal REST\n * requests prefer the `Authorization: Bearer <token>` header.\n */\nfunction extractTokenFromQuery(url: string): string | null {\n return new URL(url).searchParams.get('token');\n}\n\nconst QUERY_TOKEN_ALLOWED_PATHS = new Set(['/api/events', '/api/ws']);\n\nfunction isQueryTokenAllowedPath(path: string): boolean {\n return QUERY_TOKEN_ALLOWED_PATHS.has(path) || path.startsWith('/api/events');\n}\n\nfunction resolveRemoteAddress(c: Context): string | undefined {\n try {\n return getConnInfo(c).remote.address;\n } catch {\n return undefined;\n }\n}\n\nfunction resolveMiddlewareClientIp(\n c: Context,\n trustedProxies?: string[],\n allowRealIpFallback?: boolean,\n): string {\n if (trustedProxies?.length) {\n return resolveClientIpFromRequest({\n remoteAddress: resolveRemoteAddress(c),\n getHeader: (name) => c.req.header(name),\n trustedProxies,\n allowRealIpFallback,\n });\n }\n return getClientIpFromHeaders({\n get: (name: string) => c.req.header(name) ?? undefined,\n });\n}\n\ntype RateLimitContext = {\n active: boolean;\n cfg: ResolvedAuthRateLimitConfig;\n /** `undefined` when the client is exempted (loopback, disabled, etc.). */\n trackingKey: string | undefined;\n};\n\nfunction buildRateLimitContext(\n getGatewayAuth: AuthConfig['getGatewayAuth'],\n clientIp: string,\n origin: string | undefined,\n): RateLimitContext {\n const cfg = resolveAuthRateLimit(getGatewayAuth?.()?.rateLimit);\n const active = cfg.enabled && !isAuthRateLimitGloballyDisabled();\n if (!active) return { active: false, cfg, trackingKey: undefined };\n const tracking = resolveAuthTracking({ clientIp, origin, cfg: authPolicyConfig(cfg) });\n return {\n active: true,\n cfg,\n trackingKey: tracking.exempt ? undefined : tracking.key,\n };\n}\n\nfunction checkBlocked(rl: RateLimitContext): { blocked: false } | { blocked: true; retryAfterSec: number } {\n if (!rl.active || rl.trackingKey === undefined) return { blocked: false };\n return buckets.authFailure(rl.cfg).check(rl.trackingKey);\n}\n\nfunction recordFailure(rl: RateLimitContext): void {\n if (!rl.active || rl.trackingKey === undefined) return;\n buckets.authFailure(rl.cfg).fail(rl.trackingKey);\n}\n\nfunction recordSuccess(rl: RateLimitContext): void {\n if (!rl.active || rl.trackingKey === undefined) return;\n buckets.authFailure(rl.cfg).succeed(rl.trackingKey);\n}\n\nfunction blockedResponse(c: Context, retryAfterSec: number) {\n c.header('Retry-After', String(retryAfterSec));\n return c.json(\n {\n error: 'Too Many Requests',\n code: 'auth_blocked',\n message: 'Too many authentication attempts',\n retryAfter: retryAfterSec,\n },\n 429,\n );\n}\n\nexport function auth(config?: AuthConfig) {\n const { token, getGatewayAuth, getResolvedAuth, getTrustedProxyContext } = config || {};\n\n return createMiddleware(async (c, next) => {\n const resolvedAuth = getResolvedAuth?.();\n const authMode = resolvedAuth?.mode ?? (token ? 'token' : 'none');\n\n if (authMode === 'trusted-proxy') {\n const proxyContext = getTrustedProxyContext?.();\n const trustedProxies = proxyContext?.trustedProxies;\n const trustedProxyConfig = resolvedAuth?.trustedProxy;\n\n const clientIp = resolveMiddlewareClientIp(c, trustedProxies, proxyContext?.allowRealIpFallback);\n const origin = c.req.header('origin');\n const rl = buildRateLimitContext(getGatewayAuth, clientIp, origin);\n\n // Server misconfiguration — not an attack signal. Don't count.\n if (!trustedProxyConfig) {\n log.warn(\n { path: c.req.path, method: c.req.method, clientIp, reason: 'trusted_proxy_config_missing' },\n 'HTTP auth rejected: trusted-proxy config missing',\n );\n return c.json(\n { error: 'Unauthorized', code: 'auth_unconfigured', message: 'Trusted-proxy auth is not configured' },\n 401,\n );\n }\n\n const blocked = checkBlocked(rl);\n if (blocked.blocked) {\n log.warn(\n { clientIp, origin: origin ?? undefined, path: c.req.path, method: c.req.method, retryAfterSec: blocked.retryAfterSec, reason: 'auth_blocked' },\n 'Auth rate limit blocked',\n );\n return blockedResponse(c, blocked.retryAfterSec);\n }\n\n const result = authorizeTrustedProxy({\n remoteAddress: resolveRemoteAddress(c),\n getHeader: (name) => c.req.header(name),\n trustedProxies,\n trustedProxyConfig,\n });\n\n if (result.ok === false) {\n recordFailure(rl);\n log.warn(\n { path: c.req.path, method: c.req.method, clientIp, reason: result.reason },\n `HTTP auth rejected: trusted-proxy validation failed (${result.reason})`,\n );\n return c.json(\n { error: 'Unauthorized', code: 'invalid_proxy_credentials', message: 'Trusted-proxy authentication failed' },\n 401,\n );\n }\n\n recordSuccess(rl);\n await next();\n return;\n }\n\n if (authMode === 'none' || !token) {\n return next();\n }\n\n const proxyContext = getTrustedProxyContext?.();\n const clientIp = resolveMiddlewareClientIp(c, proxyContext?.trustedProxies, proxyContext?.allowRealIpFallback);\n const origin = c.req.header('origin');\n const rl = buildRateLimitContext(getGatewayAuth, clientIp, origin);\n\n const authHeader = extractTokenFromHeader(c.req.header('authorization'));\n const requestPath = new URL(c.req.url).pathname;\n const queryToken = isQueryTokenAllowedPath(requestPath) ? extractTokenFromQuery(c.req.url) : null;\n\n if (!authHeader && queryToken === null && new URL(c.req.url).searchParams.has('token')) {\n log.warn(\n { path: requestPath, method: c.req.method, clientIp },\n 'Token in query string rejected: use Authorization header for this endpoint',\n );\n }\n\n const providedToken = authHeader || queryToken;\n\n if (providedToken && validateToken(providedToken, token)) {\n recordSuccess(rl);\n await next();\n return;\n }\n\n const blocked = checkBlocked(rl);\n if (blocked.blocked) {\n log.warn(\n { clientIp, origin: origin ?? undefined, path: requestPath, method: c.req.method, retryAfterSec: blocked.retryAfterSec, reason: 'auth_blocked' },\n 'Auth rate limit blocked',\n );\n return blockedResponse(c, blocked.retryAfterSec);\n }\n\n // Missing token is an unauthenticated request, not a brute-force signal —\n // page reloads / SDK cold starts often hit endpoints before the token is\n // attached. Counting this would lock users out of the token-entry path.\n if (!providedToken) {\n log.warn(\n { path: c.req.path, method: c.req.method, clientIp, reason: 'missing_token' },\n 'HTTP auth rejected: no Bearer or ?token=',\n );\n return c.json(\n { error: 'Unauthorized', code: 'missing_token', message: 'Missing authentication token' },\n 401,\n );\n }\n\n recordFailure(rl);\n log.warn(\n { path: c.req.path, method: c.req.method, clientIp, reason: 'invalid_token' },\n 'HTTP auth rejected: token mismatch',\n );\n return c.json(\n { error: 'Unauthorized', code: 'invalid_token', message: 'Invalid authentication token' },\n 401,\n );\n });\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 { getClientIpFromHeaders } from "../../auth-rate-limit.js";
|
|
4
3
|
import { resolveClientIpFromRequest } from "../../client-ip.js";
|
|
4
|
+
import { getClientIpFromHeaders } from "../../security/loopback.js";
|
|
5
5
|
import { createMiddleware } from "hono/factory";
|
|
6
6
|
import { getConnInfo } from "@hono/node-server/conninfo";
|
|
7
7
|
//#region src/gateway/hono/middleware/logger.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","names":[],"sources":["../../../../../src/gateway/hono/middleware/logger.ts"],"sourcesContent":["import { createMiddleware } from 'hono/factory';\nimport type { Context } from 'hono';\nimport { getConnInfo } from '@hono/node-server/conninfo';\n\nimport { getClientIpFromHeaders } from '../../
|
|
1
|
+
{"version":3,"file":"logger.js","names":[],"sources":["../../../../../src/gateway/hono/middleware/logger.ts"],"sourcesContent":["import { createMiddleware } from 'hono/factory';\nimport type { Context } from 'hono';\nimport { getConnInfo } from '@hono/node-server/conninfo';\n\nimport { getClientIpFromHeaders } from '../../security/loopback.js';\nimport { resolveClientIpFromRequest } from '../../client-ip.js';\nimport { createLogger } from '../../../utils/logger.js';\n\nconst log = createLogger('Hono:Request');\n\nexport interface LoggerMiddlewareConfig {\n trustedProxies?: string[];\n allowRealIpFallback?: boolean;\n}\n\nfunction resolveRemoteAddress(c: Context): string | undefined {\n try {\n return getConnInfo(c).remote.address;\n } catch {\n return undefined;\n }\n}\n\nfunction resolveRequestClientIp(c: Context, config?: LoggerMiddlewareConfig): string {\n const trustedProxies = config?.trustedProxies;\n if (trustedProxies?.length) {\n return resolveClientIpFromRequest({\n remoteAddress: resolveRemoteAddress(c),\n getHeader: (name) => c.req.header(name),\n trustedProxies,\n allowRealIpFallback: config?.allowRealIpFallback,\n });\n }\n return getClientIpFromHeaders({\n get: (name) => c.req.header(name) ?? undefined,\n });\n}\n\nexport function logger(config?: LoggerMiddlewareConfig) {\n return createMiddleware(async (c, next) => {\n const start = Date.now();\n\n const clientIp = resolveRequestClientIp(c, config);\n const userAgent = c.req.header('user-agent') ?? undefined;\n const contentLength = c.req.header('content-length');\n const referer = c.req.header('referer') ?? undefined;\n\n await next();\n\n const duration = Date.now() - start;\n const status = c.res.status;\n const isServerError = status >= 500;\n const isClientError = status >= 400 && status < 500;\n const isSlow = duration > 1000;\n\n const logData = {\n method: c.req.method,\n path: c.req.path,\n status,\n durationMs: duration,\n clientIp,\n ...(userAgent ? { userAgent } : {}),\n ...(contentLength ? { contentLength: Number(contentLength) } : {}),\n ...(referer ? { referer } : {}),\n };\n\n const msg = `HTTP ${c.req.method} ${c.req.path} → ${status} (${duration}ms)`;\n\n if (isServerError || isSlow) {\n log.warn(logData, msg);\n } else if (isClientError) {\n // 4xx: info avoids doubling warn noise from auth / rate-limit handlers\n log.info(logData, msg);\n } else {\n log.debug(logData, msg);\n }\n });\n}\n"],"mappings":";;;;;;;aAMwD;AAExD,MAAM,MAAM,aAAa,eAAe;AAOxC,SAAS,qBAAqB,GAAgC;AAC5D,KAAI;AACF,SAAO,YAAY,EAAE,CAAC,OAAO;SACvB;AACN;;;AAIJ,SAAS,uBAAuB,GAAY,QAAyC;CACnF,MAAM,iBAAiB,QAAQ;AAC/B,KAAI,gBAAgB,OAClB,QAAO,2BAA2B;EAChC,eAAe,qBAAqB,EAAE;EACtC,YAAY,SAAS,EAAE,IAAI,OAAO,KAAK;EACvC;EACA,qBAAqB,QAAQ;EAC9B,CAAC;AAEJ,QAAO,uBAAuB,EAC5B,MAAM,SAAS,EAAE,IAAI,OAAO,KAAK,IAAI,KAAA,GACtC,CAAC;;AAGJ,SAAgB,OAAO,QAAiC;AACtD,QAAO,iBAAiB,OAAO,GAAG,SAAS;EACzC,MAAM,QAAQ,KAAK,KAAK;EAExB,MAAM,WAAW,uBAAuB,GAAG,OAAO;EAClD,MAAM,YAAY,EAAE,IAAI,OAAO,aAAa,IAAI,KAAA;EAChD,MAAM,gBAAgB,EAAE,IAAI,OAAO,iBAAiB;EACpD,MAAM,UAAU,EAAE,IAAI,OAAO,UAAU,IAAI,KAAA;AAE3C,QAAM,MAAM;EAEZ,MAAM,WAAW,KAAK,KAAK,GAAG;EAC9B,MAAM,SAAS,EAAE,IAAI;EACrB,MAAM,gBAAgB,UAAU;EAChC,MAAM,gBAAgB,UAAU,OAAO,SAAS;EAChD,MAAM,SAAS,WAAW;EAE1B,MAAM,UAAU;GACd,QAAQ,EAAE,IAAI;GACd,MAAM,EAAE,IAAI;GACZ;GACA,YAAY;GACZ;GACA,GAAI,YAAY,EAAE,WAAW,GAAG,EAAE;GAClC,GAAI,gBAAgB,EAAE,eAAe,OAAO,cAAc,EAAE,GAAG,EAAE;GACjE,GAAI,UAAU,EAAE,SAAS,GAAG,EAAE;GAC/B;EAED,MAAM,MAAM,QAAQ,EAAE,IAAI,OAAO,GAAG,EAAE,IAAI,KAAK,KAAK,OAAO,IAAI,SAAS;AAExE,MAAI,iBAAiB,OACnB,KAAI,KAAK,SAAS,IAAI;WACb,cAET,KAAI,KAAK,SAAS,IAAI;MAEtB,KAAI,MAAM,SAAS,IAAI;GAEzB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-client request-rate gate for sensitive admin/mutation endpoints.
|
|
3
|
+
* Backed by `buckets.strictApi()` — see {@link ../../rate-limit/buckets.ts}.
|
|
4
|
+
*/
|
|
5
|
+
export type StrictRateLimitDeps = {
|
|
6
|
+
getTrustedProxyContext: () => {
|
|
7
|
+
trustedProxies?: string[];
|
|
8
|
+
allowRealIpFallback?: boolean;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
export declare function createStrictRateLimitMiddleware(deps: StrictRateLimitDeps): import("hono/dist/types/types.js").MiddlewareHandler<any, string, {}, Response & import("hono/dist/types/types.js").TypedResponse<{
|
|
12
|
+
error: string;
|
|
13
|
+
code: string;
|
|
14
|
+
}, 429, "json">>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { createLogger } from "../../../utils/logger/index.js";
|
|
2
|
+
import { init_logger } from "../../../utils/logger.js";
|
|
3
|
+
import { resolveClientIpFromRequest } from "../../client-ip.js";
|
|
4
|
+
import { buckets } from "../../rate-limit/buckets.js";
|
|
5
|
+
import { getClientIpFromHeaders } from "../../security/loopback.js";
|
|
6
|
+
import "../../rate-limit/index.js";
|
|
7
|
+
import { createMiddleware } from "hono/factory";
|
|
8
|
+
import { getConnInfo } from "@hono/node-server/conninfo";
|
|
9
|
+
//#region src/gateway/hono/middleware/strict-rate-limit.ts
|
|
10
|
+
/**
|
|
11
|
+
* Per-client request-rate gate for sensitive admin/mutation endpoints.
|
|
12
|
+
* Backed by `buckets.strictApi()` — see {@link ../../rate-limit/buckets.ts}.
|
|
13
|
+
*/
|
|
14
|
+
init_logger();
|
|
15
|
+
const log = createLogger("Hono:StrictRateLimit");
|
|
16
|
+
function resolveClientIp(c, deps) {
|
|
17
|
+
const { trustedProxies, allowRealIpFallback } = deps.getTrustedProxyContext();
|
|
18
|
+
if (trustedProxies?.length) {
|
|
19
|
+
let remoteAddress;
|
|
20
|
+
try {
|
|
21
|
+
remoteAddress = getConnInfo(c).remote.address;
|
|
22
|
+
} catch {
|
|
23
|
+
remoteAddress = void 0;
|
|
24
|
+
}
|
|
25
|
+
return resolveClientIpFromRequest({
|
|
26
|
+
remoteAddress,
|
|
27
|
+
getHeader: (name) => c.req.header(name),
|
|
28
|
+
trustedProxies,
|
|
29
|
+
allowRealIpFallback
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return getClientIpFromHeaders({ get: (name) => c.req.header(name) ?? void 0 });
|
|
33
|
+
}
|
|
34
|
+
function createStrictRateLimitMiddleware(deps) {
|
|
35
|
+
return createMiddleware(async (c, next) => {
|
|
36
|
+
const limiter = buckets.strictApi();
|
|
37
|
+
const clientIp = resolveClientIp(c, deps);
|
|
38
|
+
const result = limiter.consume(clientIp);
|
|
39
|
+
if (!result.allowed) {
|
|
40
|
+
const retryAfterSec = Math.ceil(result.retryAfterMs / 1e3);
|
|
41
|
+
log.warn({
|
|
42
|
+
clientIp,
|
|
43
|
+
path: c.req.path,
|
|
44
|
+
method: c.req.method,
|
|
45
|
+
retryAfterSec,
|
|
46
|
+
reason: "strict_rate_limit_exceeded"
|
|
47
|
+
}, "Strict API rate limit exceeded");
|
|
48
|
+
c.header("Retry-After", String(retryAfterSec));
|
|
49
|
+
c.header("X-RateLimit-Remaining", "0");
|
|
50
|
+
return c.json({
|
|
51
|
+
error: "Too many requests",
|
|
52
|
+
code: "rate_limited"
|
|
53
|
+
}, 429);
|
|
54
|
+
}
|
|
55
|
+
c.header("X-RateLimit-Remaining", String(result.remaining));
|
|
56
|
+
await next();
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
export { createStrictRateLimitMiddleware };
|
|
61
|
+
|
|
62
|
+
//# sourceMappingURL=strict-rate-limit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strict-rate-limit.js","names":[],"sources":["../../../../../src/gateway/hono/middleware/strict-rate-limit.ts"],"sourcesContent":["/**\n * Per-client request-rate gate for sensitive admin/mutation endpoints.\n * Backed by `buckets.strictApi()` — see {@link ../../rate-limit/buckets.ts}.\n */\n\nimport { createMiddleware } from 'hono/factory';\nimport type { Context } from 'hono';\nimport { getConnInfo } from '@hono/node-server/conninfo';\n\nimport { buckets } from '../../rate-limit/index.js';\nimport { getClientIpFromHeaders } from '../../security/loopback.js';\nimport { resolveClientIpFromRequest } from '../../client-ip.js';\nimport { createLogger } from '../../../utils/logger.js';\n\nconst log = createLogger('Hono:StrictRateLimit');\n\nexport type StrictRateLimitDeps = {\n getTrustedProxyContext: () => {\n trustedProxies?: string[];\n allowRealIpFallback?: boolean;\n };\n};\n\nfunction resolveClientIp(c: Context, deps: StrictRateLimitDeps): string {\n const { trustedProxies, allowRealIpFallback } = deps.getTrustedProxyContext();\n if (trustedProxies?.length) {\n let remoteAddress: string | undefined;\n try {\n remoteAddress = getConnInfo(c).remote.address;\n } catch {\n remoteAddress = undefined;\n }\n return resolveClientIpFromRequest({\n remoteAddress,\n getHeader: (name) => c.req.header(name),\n trustedProxies,\n allowRealIpFallback,\n });\n }\n return getClientIpFromHeaders({ get: (name) => c.req.header(name) ?? undefined });\n}\n\nexport function createStrictRateLimitMiddleware(deps: StrictRateLimitDeps) {\n return createMiddleware(async (c, next) => {\n const limiter = buckets.strictApi();\n const clientIp = resolveClientIp(c, deps);\n const result = limiter.consume(clientIp);\n\n if (!result.allowed) {\n const retryAfterSec = Math.ceil(result.retryAfterMs / 1000);\n log.warn(\n {\n clientIp,\n path: c.req.path,\n method: c.req.method,\n retryAfterSec,\n reason: 'strict_rate_limit_exceeded',\n },\n 'Strict API rate limit exceeded',\n );\n c.header('Retry-After', String(retryAfterSec));\n c.header('X-RateLimit-Remaining', '0');\n return c.json({ error: 'Too many requests', code: 'rate_limited' }, 429);\n }\n\n c.header('X-RateLimit-Remaining', String(result.remaining));\n await next();\n });\n}\n"],"mappings":";;;;;;;;;;;;;aAYwD;AAExD,MAAM,MAAM,aAAa,uBAAuB;AAShD,SAAS,gBAAgB,GAAY,MAAmC;CACtE,MAAM,EAAE,gBAAgB,wBAAwB,KAAK,wBAAwB;AAC7E,KAAI,gBAAgB,QAAQ;EAC1B,IAAI;AACJ,MAAI;AACF,mBAAgB,YAAY,EAAE,CAAC,OAAO;UAChC;AACN,mBAAgB,KAAA;;AAElB,SAAO,2BAA2B;GAChC;GACA,YAAY,SAAS,EAAE,IAAI,OAAO,KAAK;GACvC;GACA;GACD,CAAC;;AAEJ,QAAO,uBAAuB,EAAE,MAAM,SAAS,EAAE,IAAI,OAAO,KAAK,IAAI,KAAA,GAAW,CAAC;;AAGnF,SAAgB,gCAAgC,MAA2B;AACzE,QAAO,iBAAiB,OAAO,GAAG,SAAS;EACzC,MAAM,UAAU,QAAQ,WAAW;EACnC,MAAM,WAAW,gBAAgB,GAAG,KAAK;EACzC,MAAM,SAAS,QAAQ,QAAQ,SAAS;AAExC,MAAI,CAAC,OAAO,SAAS;GACnB,MAAM,gBAAgB,KAAK,KAAK,OAAO,eAAe,IAAK;AAC3D,OAAI,KACF;IACE;IACA,MAAM,EAAE,IAAI;IACZ,QAAQ,EAAE,IAAI;IACd;IACA,QAAQ;IACT,EACD,iCACD;AACD,KAAE,OAAO,eAAe,OAAO,cAAc,CAAC;AAC9C,KAAE,OAAO,yBAAyB,IAAI;AACtC,UAAO,EAAE,KAAK;IAAE,OAAO;IAAqB,MAAM;IAAgB,EAAE,IAAI;;AAG1E,IAAE,OAAO,yBAAyB,OAAO,OAAO,UAAU,CAAC;AAC3D,QAAM,MAAM;GACZ"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CredentialResolver, init_credentials } from "../../auth/credentials.js";
|
|
2
|
-
import { init_providers, isProviderConfigured } from "../../providers/index.js";
|
|
3
2
|
import { anthropicOAuthProvider } from "../../auth/oauth/anthropic.js";
|
|
3
|
+
import { init_providers, isProviderConfigured } from "../../providers/index.js";
|
|
4
4
|
import { minimaxOAuthProvider } from "../../auth/oauth/minimax.js";
|
|
5
5
|
import { minimaxCnOAuthProvider } from "../../auth/oauth/minimax-cn.js";
|
|
6
6
|
import { kimiCodingOAuthProvider } from "../../auth/oauth/kimi-coding.js";
|
|
@@ -7,8 +7,8 @@ import { createOAuthHandler } from "../oauth.js";
|
|
|
7
7
|
import { createOAuthAsyncHandler } from "../oauth-async.js";
|
|
8
8
|
import { extensionAssetMimeType } from "../lib/extension-assets.js";
|
|
9
9
|
import { loadExtensionStore, saveExtensionStore } from "../lib/extension-store.js";
|
|
10
|
-
import { relative, resolve } from "node:path";
|
|
11
10
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
11
|
+
import { relative, resolve } from "node:path";
|
|
12
12
|
//#region src/gateway/hono/routes/auth-registry-extensions.ts
|
|
13
13
|
init_providers();
|
|
14
14
|
const EXTENSION_ASSET_CSP = "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; connect-src 'none'; frame-ancestors 'self'; frame-src 'none'; base-uri 'none'; object-src 'none'; form-action 'none'";
|
|
@@ -312,7 +312,7 @@ function registerAuthRegistryExtensionsRoutes(authenticated, deps) {
|
|
|
312
312
|
}, 400);
|
|
313
313
|
}
|
|
314
314
|
try {
|
|
315
|
-
const payload = await service.
|
|
315
|
+
const payload = await service.marketplace.fetchExtensionPackageDetail(pkgName);
|
|
316
316
|
return c.json({
|
|
317
317
|
ok: true,
|
|
318
318
|
payload
|
|
@@ -342,7 +342,7 @@ function registerAuthRegistryExtensionsRoutes(authenticated, deps) {
|
|
|
342
342
|
error: "Expected { name: string, version?: string, overwrite?: boolean }"
|
|
343
343
|
}, 400);
|
|
344
344
|
try {
|
|
345
|
-
const payload = await service.
|
|
345
|
+
const payload = await service.marketplace.installExtension({
|
|
346
346
|
name,
|
|
347
347
|
version,
|
|
348
348
|
overwrite
|
|
@@ -374,7 +374,7 @@ function registerAuthRegistryExtensionsRoutes(authenticated, deps) {
|
|
|
374
374
|
error: "Expected { extensionId: string }"
|
|
375
375
|
}, 400);
|
|
376
376
|
try {
|
|
377
|
-
const payload = await service.
|
|
377
|
+
const payload = await service.marketplace.uninstallExtension(extensionId);
|
|
378
378
|
return c.json({
|
|
379
379
|
ok: true,
|
|
380
380
|
payload
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-registry-extensions.js","names":["extensionMarketplace.searchExtensions","extensionMarketplace.listExtensions","extensionMarketplace.fetchRegistry"],"sources":["../../../../../src/gateway/hono/routes/auth-registry-extensions.ts"],"sourcesContent":["import type { Hono } from 'hono';\nimport { existsSync, readFileSync, statSync } from 'node:fs';\nimport { relative, resolve } from 'node:path';\n\nimport type { Config as SurfaceConfig } from '../../../config/config-surface.js';\nimport type { GatewayService } from '../../service.js';\nimport { buildWhenContextSnapshot } from '../../../extensions/when-context.js';\nimport * as extensionMarketplace from '../../../extensions/marketplace.js';\nimport { mergeActivationContext } from '../../../extensions/activation-context.js';\nimport { ActivationPlanner } from '../../../extensions/activation-planner.js';\nimport { getAllModels, getAvailableModels, type Model, type Api } from '../../../providers/index.js';\nimport { createOAuthHandler, loadOAuthCredentialsToCache } from '../oauth.js';\nimport { createOAuthAsyncHandler } from '../oauth-async.js';\nimport { extensionAssetMimeType } from '../lib/extension-assets.js';\nimport { loadExtensionStore, saveExtensionStore } from '../lib/extension-store.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nconst EXTENSION_ASSET_CSP =\n \"default-src 'self'; \" +\n \"script-src 'self' 'unsafe-inline'; \" +\n \"style-src 'self' 'unsafe-inline'; \" +\n \"img-src 'self' data: blob:; \" +\n \"connect-src 'none'; \" +\n \"frame-ancestors 'self'; \" +\n \"frame-src 'none'; \" +\n \"base-uri 'none'; \" +\n \"object-src 'none'; \" +\n \"form-action 'none'\";\n\n/** Sandboxed extension iframes send `Origin: null`; echo it (and real origins) so every status includes ACAO. */\nfunction extensionUiAssetCorsAllowOrigin(c: { req: { header: (name: string) => string | undefined } }): string {\n const origin = c.req.header('origin');\n if (origin === 'null') return 'null';\n if (origin) return origin;\n return '*';\n}\n\nfunction rewriteExtensionAssetHtml(html: string, extensionId: string, assetPath: string): string {\n const assetDir = assetPath.includes('/') ? assetPath.slice(0, assetPath.lastIndexOf('/') + 1) : '';\n const assetBase = `/api/extensions/${extensionId}/assets/${assetDir}`;\n\n return html\n .replace(/(<script\\b[^>]*?\\ssrc=)([\"'])(\\.\\/)?([^\"']+)\\2/gi, (_match, tag, quote, _dot, file) => {\n const isAbsolute =\n file.startsWith('/') || file.startsWith('http://') || file.startsWith('https://');\n const resolvedSrc = isAbsolute ? file : `${assetBase}${file}`;\n return `${tag}${quote}${resolvedSrc}${quote} crossorigin=\"anonymous\"`;\n })\n .replace(/(<link\\b[^>]*?\\shref=)([\"'])(\\.\\/)?([^\"']+)\\2/gi, (_match, tag, quote, _dot, file) => {\n const isAbsolute =\n file.startsWith('/') || file.startsWith('http://') || file.startsWith('https://');\n const resolvedHref = isAbsolute ? file : `${assetBase}${file}`;\n return `${tag}${quote}${resolvedHref}${quote}`;\n });\n}\n\nfunction hasNonEmptyConfigSchema(schema: unknown): boolean {\n if (!schema || typeof schema !== 'object') return false;\n const properties = (schema as { properties?: unknown }).properties;\n return Boolean(properties && typeof properties === 'object' && Object.keys(properties).length > 0);\n}\n\n/**\n * Register extension UI asset routes on the public (unauthenticated) app.\n *\n * Sandboxed iframes (`sandbox=\"allow-scripts …\"` without `allow-same-origin`) have an\n * opaque origin of `null`, so sub-resource requests from inside the iframe cannot\n * carry the `?token=` query parameter that was on the parent HTML URL. Putting these\n * routes behind the auth middleware therefore causes every JS/CSS asset to return 401.\n *\n * Security is maintained by the strict Content-Security-Policy returned with every\n * asset (`frame-ancestors 'self'`), which prevents any page other than the gateway\n * console itself from embedding the extension iframes.\n */\nexport function registerPublicExtensionAssetRoutes(app: Hono, service: GatewayService): void {\n app.get('/api/extensions/:id/assets/*', async (c) => {\n const acao = extensionUiAssetCorsAllowOrigin(c);\n const corsHdr = { 'Access-Control-Allow-Origin': acao } as const;\n\n const extensionId = c.req.param('id');\n const loader = service.getExtensionLoader();\n if (!loader) {\n return c.json({ error: 'Extensions unavailable' }, 503, corsHdr);\n }\n\n const discovered = loader.discoverExtensions();\n const ext = discovered.find((e) => e.id === extensionId);\n if (!ext || !ext.manifest.ui) {\n return c.json({ error: 'Extension not found or has no UI' }, 404, corsHdr);\n }\n\n const prefix = `/api/extensions/${extensionId}/assets/`;\n const assetPathEncoded = c.req.path.startsWith(prefix) ? c.req.path.slice(prefix.length) : '';\n let assetPath = assetPathEncoded;\n try {\n assetPath = decodeURIComponent(assetPathEncoded);\n } catch {\n return c.json({ error: 'Invalid asset path' }, 400, corsHdr);\n }\n\n if (!assetPath || assetPath.includes('..')) {\n return c.json({ error: 'Invalid asset path' }, 400, corsHdr);\n }\n\n const root = resolve(ext.path);\n const fullPath = resolve(root, assetPath);\n const rel = relative(root, fullPath);\n if (rel.startsWith('..') || rel === '') {\n return c.json({ error: 'Path traversal denied' }, 403, corsHdr);\n }\n\n if (!existsSync(fullPath) || !statSync(fullPath).isFile()) {\n return c.json({ error: 'Not found' }, 404, corsHdr);\n }\n\n const rawContent = readFileSync(fullPath);\n const mimeType = extensionAssetMimeType(assetPath);\n\n const body: string | Uint8Array = mimeType.startsWith('text/html')\n ? rewriteExtensionAssetHtml(rawContent.toString('utf-8'), extensionId, assetPath)\n : new Uint8Array(rawContent);\n\n return new Response(body, {\n status: 200,\n headers: {\n 'Content-Type': mimeType,\n 'Content-Security-Policy': EXTENSION_ASSET_CSP,\n 'Cache-Control': 'no-store',\n 'X-Content-Type-Options': 'nosniff',\n 'Access-Control-Allow-Origin': acao,\n },\n });\n });\n}\n\nexport function registerAuthRegistryExtensionsRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service, strictRateLimitMiddleware } = deps;\n\n // ========== Auth API (/api/auth) ==========\n\n // GET /api/auth/token - Get current gateway token\n authenticated.get('/api/auth/token', (c) => {\n const authToken = service.getAuthToken();\n return c.json({ \n ok: true, \n payload: { \n token: authToken,\n mode: service.getAuthMode(),\n } \n });\n });\n\n // POST /api/auth/token/refresh - Generate new gateway token\n authenticated.post('/api/auth/token/refresh', async (c) => {\n try {\n const newToken = await service.refreshAuthToken();\n return c.json({ \n ok: true, \n payload: { \n token: newToken,\n message: 'Token refreshed successfully. Please update your client configuration.'\n } \n });\n } catch (err) {\n return c.json({ \n ok: false, \n error: err instanceof Error ? err.message : 'Failed to refresh token' \n }, 500);\n }\n });\n\n // ========== OAuth API (/api/auth/oauth) ==========\n authenticated.route('/api/auth/oauth', createOAuthHandler(service));\n\n // ========== Async OAuth API (/api/auth/oauth-async) ==========\n authenticated.route('/api/auth/oauth-async', createOAuthAsyncHandler(service));\n\n // Load OAuth credentials from config into cache on startup\n loadOAuthCredentialsToCache(service);\n\n // ========== Registry API ==========\n \n // GET /api/registry - Full registry for frontend\n authenticated.get('/api/registry', async (c) => {\n const allModels = getAllModels();\n const availableModels = await getAvailableModels();\n const configured = new Set(availableModels.map(m => `${m.provider}/${m.id}`));\n \n // Group models by provider\n const providerMap = new Map<string, Model<Api>[]>();\n for (const model of allModels) {\n const list = providerMap.get(model.provider) ?? [];\n list.push(model);\n providerMap.set(model.provider, list);\n }\n \n return c.json({\n ok: true,\n payload: {\n version: 'pi-ai',\n providers: Array.from(providerMap.entries()).map(([id, models]) => ({\n id,\n name: id.charAt(0).toUpperCase() + id.slice(1),\n configured: models.some(m => configured.has(`${m.provider}/${m.id}`)),\n models: models.map(m => ({\n ref: `${m.provider}/${m.id}`,\n id: m.id,\n name: m.name,\n provider: m.provider,\n reasoning: m.reasoning ?? false,\n input: m.input ?? ['text'],\n contextWindow: m.contextWindow ?? 128000,\n maxTokens: m.maxTokens ?? 4096,\n cost: {\n input: m.cost?.input ?? 0,\n output: m.cost?.output ?? 0,\n },\n available: configured.has(`${m.provider}/${m.id}`),\n })),\n })),\n },\n });\n });\n\n // ========== Extension UI (manifest discovery + static assets) ==========\n\n authenticated.get('/api/extensions', async (c) => {\n const loader = service.getExtensionLoader();\n if (!loader) {\n return c.json({ extensions: [] });\n }\n\n const registry = loader.getRegistry();\n const discovered = loader.discoverExtensions();\n const activeIds = new Set<string>();\n for (const [id] of registry.extensions) {\n activeIds.add(id);\n }\n\n loader.setConfig(service.currentConfig as unknown as SurfaceConfig);\n let activationEligibleIds: Set<string> = new Set();\n try {\n const planner = new ActivationPlanner(loader.buildManifestRegistry());\n activationEligibleIds = new Set(\n planner.getActivatedIds(mergeActivationContext(service.currentConfig as unknown as SurfaceConfig)),\n );\n } catch {\n activationEligibleIds = new Set();\n }\n\n const extensions = discovered.map((ext) => ({\n id: ext.manifest.id,\n name: ext.manifest.name,\n description: ext.manifest.description,\n version: ext.manifest.version,\n kind: ext.manifest.kind,\n source: ext.source,\n active: activeIds.has(ext.id),\n activationEligible: activationEligibleIds.has(ext.id),\n hasUi: Boolean(ext.manifest.ui),\n hasConfigSchema: hasNonEmptyConfigSchema(ext.manifest.configSchema),\n ui: ext.manifest.ui\n ? {\n icon: ext.manifest.ui.icon,\n permissions: ext.manifest.ui.permissions,\n contributions: ext.manifest.ui.contributions,\n }\n : undefined,\n }));\n return c.json({ extensions });\n });\n\n /**\n * Built-in (bundled) extension enable/disable — persists `extensions.enabled` / `extensions.disabled`.\n * Body: `{ extensionId: string, enabled: boolean }`\n */\n authenticated.post('/api/extensions/bundled/activation', strictRateLimitMiddleware, async (c) => {\n const body = (await c.req.json().catch(() => null)) as\n | { extensionId?: unknown; enabled?: unknown }\n | null;\n const extensionId =\n typeof body?.extensionId === 'string' ? body.extensionId.trim() : '';\n if (!extensionId) {\n return c.json({ ok: false, error: { message: 'extensionId is required' } }, 400);\n }\n if (typeof body?.enabled !== 'boolean') {\n return c.json({ ok: false, error: { message: 'enabled must be a boolean' } }, 400);\n }\n const result = await service.setBundledExtensionActivationTarget(extensionId, body.enabled);\n if (!result.ok) {\n return c.json({ ok: false, error: { message: result.error ?? 'Request failed' } }, 400);\n }\n return c.json({\n ok: true,\n payload: { requiresGatewayRestart: result.requiresGatewayRestart },\n });\n });\n\n authenticated.get('/api/extensions/:id', async (c) => {\n const extensionId = c.req.param('id');\n const loader = service.getExtensionLoader();\n if (!loader) {\n return c.json({ error: 'Extensions unavailable' }, 503);\n }\n const discovered = loader.discoverExtensions();\n const ext = discovered.find((e) => e.id === extensionId);\n if (!ext) {\n return c.json({ error: 'Extension not found' }, 404);\n }\n const registry = loader.getRegistry();\n return c.json({\n id: ext.manifest.id,\n name: ext.manifest.name,\n description: ext.manifest.description,\n version: ext.manifest.version,\n kind: ext.manifest.kind,\n source: ext.source,\n path: ext.path,\n active: registry.extensions.has(ext.id),\n manifest: ext.manifest,\n });\n });\n\n authenticated.get('/api/extensions/:id/storage', async (c) => {\n const extensionId = c.req.param('id');\n const store = await loadExtensionStore(extensionId);\n return c.json({ keys: Object.keys(store) });\n });\n\n authenticated.get('/api/extensions/:id/storage/:key', async (c) => {\n const extensionId = c.req.param('id');\n const key = decodeURIComponent(c.req.param('key'));\n const store = await loadExtensionStore(extensionId);\n if (!(key in store)) {\n return c.json({ error: 'Key not found' }, 404);\n }\n return c.json({ value: store[key] });\n });\n\n authenticated.put('/api/extensions/:id/storage/:key', async (c) => {\n const extensionId = c.req.param('id');\n const key = decodeURIComponent(c.req.param('key'));\n const body = (await c.req.json().catch(() => null)) as { value?: unknown } | null;\n if (body === null || !('value' in body)) {\n return c.json({ error: 'Request body must contain a \"value\" field' }, 400);\n }\n const store = await loadExtensionStore(extensionId);\n store[key] = body.value;\n await saveExtensionStore(extensionId, store);\n return c.json({ ok: true });\n });\n\n authenticated.delete('/api/extensions/:id/storage/:key', async (c) => {\n const extensionId = c.req.param('id');\n const key = decodeURIComponent(c.req.param('key'));\n const store = await loadExtensionStore(extensionId);\n delete store[key];\n await saveExtensionStore(extensionId, store);\n return c.json({ ok: true });\n });\n\n authenticated.get('/api/extensions/:id/config', async (c) => {\n const extensionId = c.req.param('id');\n return c.json(await loadExtensionStore(`__config__${extensionId}`));\n });\n\n authenticated.patch('/api/extensions/:id/config', async (c) => {\n const extensionId = c.req.param('id');\n const patch = (await c.req.json().catch(() => null)) as Record<string, unknown> | null;\n if (!patch || typeof patch !== 'object' || Array.isArray(patch)) {\n return c.json({ error: 'Request body must be a JSON object' }, 400);\n }\n const namespace = `__config__${extensionId}`;\n const config = await loadExtensionStore(namespace);\n Object.assign(config, patch);\n await saveExtensionStore(namespace, config);\n return c.json({ ok: true });\n });\n\n authenticated.get('/api/context', (c) => {\n const loader = service.getExtensionLoader();\n const snapshot = buildWhenContextSnapshot(\n service.currentConfig as unknown as SurfaceConfig,\n loader,\n );\n return c.json(snapshot);\n });\n\n authenticated.get('/api/marketplace', async (c) => {\n const q = c.req.query('q');\n const category = c.req.query('category');\n try {\n let extensions;\n if (typeof q === 'string' && q.trim()) {\n extensions = await extensionMarketplace.searchExtensions(q.trim());\n } else if (typeof category === 'string' && category.trim()) {\n extensions = await extensionMarketplace.listExtensions(category.trim());\n } else {\n const reg = await extensionMarketplace.fetchRegistry();\n extensions = reg.extensions;\n }\n return c.json({ ok: true, extensions });\n } catch (err) {\n return c.json(\n {\n ok: false,\n extensions: [],\n error: err instanceof Error ? err.message : 'marketplace fetch failed',\n },\n 500,\n );\n }\n });\n\n authenticated.get('/api/marketplace/packages/:pkgName', async (c) => {\n const raw = c.req.param('pkgName');\n if (!raw) {\n return c.json({ ok: false, error: 'Missing package name' }, 400);\n }\n let pkgName: string;\n try {\n pkgName = decodeURIComponent(raw);\n } catch {\n return c.json({ ok: false, error: 'Invalid package name' }, 400);\n }\n try {\n const payload = await service.fetchExtensionMarketplacePackageDetail(pkgName);\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Marketplace request failed' },\n 502,\n );\n }\n });\n\n authenticated.post('/api/marketplace/install', strictRateLimitMiddleware, async (c) => {\n let body: { name?: unknown; version?: unknown; overwrite?: unknown };\n try {\n body = (await c.req.json()) as typeof body;\n } catch {\n return c.json({ ok: false, error: 'Invalid JSON' }, 400);\n }\n const name = typeof body.name === 'string' ? body.name.trim() : '';\n const version = typeof body.version === 'string' ? body.version.trim() : undefined;\n const overwrite =\n body.overwrite === true || body.overwrite === 'true' || body.overwrite === '1';\n if (!name) {\n return c.json(\n { ok: false, error: 'Expected { name: string, version?: string, overwrite?: boolean }' },\n 400,\n );\n }\n try {\n const payload = await service.installExtensionFromMarketplace({ name, version, overwrite });\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Install failed' },\n 400,\n );\n }\n });\n\n authenticated.post('/api/marketplace/uninstall', strictRateLimitMiddleware, async (c) => {\n let body: { extensionId?: unknown };\n try {\n body = (await c.req.json()) as typeof body;\n } catch {\n return c.json({ ok: false, error: 'Invalid JSON' }, 400);\n }\n const extensionId = typeof body.extensionId === 'string' ? body.extensionId.trim() : '';\n if (!extensionId) {\n return c.json({ ok: false, error: 'Expected { extensionId: string }' }, 400);\n }\n try {\n const payload = await service.uninstallUserExtension(extensionId);\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Uninstall failed' },\n 400,\n );\n }\n });\n\n // POST /api/registry/reload — reload gateway config and refresh model list for clients\n authenticated.post('/api/registry/reload', async (c) => {\n try {\n // Reload config\n await service.reloadConfig();\n \n // Reload OAuth credentials from new config\n loadOAuthCredentialsToCache(service);\n \n const models = getAllModels();\n \n // Emit SSE event to all connected clients\n service.emit('registry.updated', { modelCount: models.length });\n \n return c.json({\n ok: true,\n payload: {\n message: 'Registry reloaded',\n modelCount: models.length,\n },\n });\n } catch (err) {\n return c.json({\n error: err instanceof Error ? err.message : 'Failed to reload registry',\n }, 500);\n }\n });\n\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"auth-registry-extensions.js","names":["extensionMarketplace.searchExtensions","extensionMarketplace.listExtensions","extensionMarketplace.fetchRegistry"],"sources":["../../../../../src/gateway/hono/routes/auth-registry-extensions.ts"],"sourcesContent":["import type { Hono } from 'hono';\nimport { existsSync, readFileSync, statSync } from 'node:fs';\nimport { relative, resolve } from 'node:path';\n\nimport type { Config as SurfaceConfig } from '../../../config/config-surface.js';\nimport type { GatewayService } from '../../service.js';\nimport { buildWhenContextSnapshot } from '../../../extensions/when-context.js';\nimport * as extensionMarketplace from '../../../extensions/marketplace.js';\nimport { mergeActivationContext } from '../../../extensions/activation-context.js';\nimport { ActivationPlanner } from '../../../extensions/activation-planner.js';\nimport { getAllModels, getAvailableModels, type Model, type Api } from '../../../providers/index.js';\nimport { createOAuthHandler, loadOAuthCredentialsToCache } from '../oauth.js';\nimport { createOAuthAsyncHandler } from '../oauth-async.js';\nimport { extensionAssetMimeType } from '../lib/extension-assets.js';\nimport { loadExtensionStore, saveExtensionStore } from '../lib/extension-store.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nconst EXTENSION_ASSET_CSP =\n \"default-src 'self'; \" +\n \"script-src 'self' 'unsafe-inline'; \" +\n \"style-src 'self' 'unsafe-inline'; \" +\n \"img-src 'self' data: blob:; \" +\n \"connect-src 'none'; \" +\n \"frame-ancestors 'self'; \" +\n \"frame-src 'none'; \" +\n \"base-uri 'none'; \" +\n \"object-src 'none'; \" +\n \"form-action 'none'\";\n\n/** Sandboxed extension iframes send `Origin: null`; echo it (and real origins) so every status includes ACAO. */\nfunction extensionUiAssetCorsAllowOrigin(c: { req: { header: (name: string) => string | undefined } }): string {\n const origin = c.req.header('origin');\n if (origin === 'null') return 'null';\n if (origin) return origin;\n return '*';\n}\n\nfunction rewriteExtensionAssetHtml(html: string, extensionId: string, assetPath: string): string {\n const assetDir = assetPath.includes('/') ? assetPath.slice(0, assetPath.lastIndexOf('/') + 1) : '';\n const assetBase = `/api/extensions/${extensionId}/assets/${assetDir}`;\n\n return html\n .replace(/(<script\\b[^>]*?\\ssrc=)([\"'])(\\.\\/)?([^\"']+)\\2/gi, (_match, tag, quote, _dot, file) => {\n const isAbsolute =\n file.startsWith('/') || file.startsWith('http://') || file.startsWith('https://');\n const resolvedSrc = isAbsolute ? file : `${assetBase}${file}`;\n return `${tag}${quote}${resolvedSrc}${quote} crossorigin=\"anonymous\"`;\n })\n .replace(/(<link\\b[^>]*?\\shref=)([\"'])(\\.\\/)?([^\"']+)\\2/gi, (_match, tag, quote, _dot, file) => {\n const isAbsolute =\n file.startsWith('/') || file.startsWith('http://') || file.startsWith('https://');\n const resolvedHref = isAbsolute ? file : `${assetBase}${file}`;\n return `${tag}${quote}${resolvedHref}${quote}`;\n });\n}\n\nfunction hasNonEmptyConfigSchema(schema: unknown): boolean {\n if (!schema || typeof schema !== 'object') return false;\n const properties = (schema as { properties?: unknown }).properties;\n return Boolean(properties && typeof properties === 'object' && Object.keys(properties).length > 0);\n}\n\n/**\n * Register extension UI asset routes on the public (unauthenticated) app.\n *\n * Sandboxed iframes (`sandbox=\"allow-scripts …\"` without `allow-same-origin`) have an\n * opaque origin of `null`, so sub-resource requests from inside the iframe cannot\n * carry the `?token=` query parameter that was on the parent HTML URL. Putting these\n * routes behind the auth middleware therefore causes every JS/CSS asset to return 401.\n *\n * Security is maintained by the strict Content-Security-Policy returned with every\n * asset (`frame-ancestors 'self'`), which prevents any page other than the gateway\n * console itself from embedding the extension iframes.\n */\nexport function registerPublicExtensionAssetRoutes(app: Hono, service: GatewayService): void {\n app.get('/api/extensions/:id/assets/*', async (c) => {\n const acao = extensionUiAssetCorsAllowOrigin(c);\n const corsHdr = { 'Access-Control-Allow-Origin': acao } as const;\n\n const extensionId = c.req.param('id');\n const loader = service.getExtensionLoader();\n if (!loader) {\n return c.json({ error: 'Extensions unavailable' }, 503, corsHdr);\n }\n\n const discovered = loader.discoverExtensions();\n const ext = discovered.find((e) => e.id === extensionId);\n if (!ext || !ext.manifest.ui) {\n return c.json({ error: 'Extension not found or has no UI' }, 404, corsHdr);\n }\n\n const prefix = `/api/extensions/${extensionId}/assets/`;\n const assetPathEncoded = c.req.path.startsWith(prefix) ? c.req.path.slice(prefix.length) : '';\n let assetPath = assetPathEncoded;\n try {\n assetPath = decodeURIComponent(assetPathEncoded);\n } catch {\n return c.json({ error: 'Invalid asset path' }, 400, corsHdr);\n }\n\n if (!assetPath || assetPath.includes('..')) {\n return c.json({ error: 'Invalid asset path' }, 400, corsHdr);\n }\n\n const root = resolve(ext.path);\n const fullPath = resolve(root, assetPath);\n const rel = relative(root, fullPath);\n if (rel.startsWith('..') || rel === '') {\n return c.json({ error: 'Path traversal denied' }, 403, corsHdr);\n }\n\n if (!existsSync(fullPath) || !statSync(fullPath).isFile()) {\n return c.json({ error: 'Not found' }, 404, corsHdr);\n }\n\n const rawContent = readFileSync(fullPath);\n const mimeType = extensionAssetMimeType(assetPath);\n\n const body: string | Uint8Array = mimeType.startsWith('text/html')\n ? rewriteExtensionAssetHtml(rawContent.toString('utf-8'), extensionId, assetPath)\n : new Uint8Array(rawContent);\n\n return new Response(body, {\n status: 200,\n headers: {\n 'Content-Type': mimeType,\n 'Content-Security-Policy': EXTENSION_ASSET_CSP,\n 'Cache-Control': 'no-store',\n 'X-Content-Type-Options': 'nosniff',\n 'Access-Control-Allow-Origin': acao,\n },\n });\n });\n}\n\nexport function registerAuthRegistryExtensionsRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service, strictRateLimitMiddleware } = deps;\n\n // ========== Auth API (/api/auth) ==========\n\n // GET /api/auth/token - Get current gateway token\n authenticated.get('/api/auth/token', (c) => {\n const authToken = service.getAuthToken();\n return c.json({ \n ok: true, \n payload: { \n token: authToken,\n mode: service.getAuthMode(),\n } \n });\n });\n\n // POST /api/auth/token/refresh - Generate new gateway token\n authenticated.post('/api/auth/token/refresh', async (c) => {\n try {\n const newToken = await service.refreshAuthToken();\n return c.json({ \n ok: true, \n payload: { \n token: newToken,\n message: 'Token refreshed successfully. Please update your client configuration.'\n } \n });\n } catch (err) {\n return c.json({ \n ok: false, \n error: err instanceof Error ? err.message : 'Failed to refresh token' \n }, 500);\n }\n });\n\n // ========== OAuth API (/api/auth/oauth) ==========\n authenticated.route('/api/auth/oauth', createOAuthHandler(service));\n\n // ========== Async OAuth API (/api/auth/oauth-async) ==========\n authenticated.route('/api/auth/oauth-async', createOAuthAsyncHandler(service));\n\n // Load OAuth credentials from config into cache on startup\n loadOAuthCredentialsToCache(service);\n\n // ========== Registry API ==========\n \n // GET /api/registry - Full registry for frontend\n authenticated.get('/api/registry', async (c) => {\n const allModels = getAllModels();\n const availableModels = await getAvailableModels();\n const configured = new Set(availableModels.map(m => `${m.provider}/${m.id}`));\n \n // Group models by provider\n const providerMap = new Map<string, Model<Api>[]>();\n for (const model of allModels) {\n const list = providerMap.get(model.provider) ?? [];\n list.push(model);\n providerMap.set(model.provider, list);\n }\n \n return c.json({\n ok: true,\n payload: {\n version: 'pi-ai',\n providers: Array.from(providerMap.entries()).map(([id, models]) => ({\n id,\n name: id.charAt(0).toUpperCase() + id.slice(1),\n configured: models.some(m => configured.has(`${m.provider}/${m.id}`)),\n models: models.map(m => ({\n ref: `${m.provider}/${m.id}`,\n id: m.id,\n name: m.name,\n provider: m.provider,\n reasoning: m.reasoning ?? false,\n input: m.input ?? ['text'],\n contextWindow: m.contextWindow ?? 128000,\n maxTokens: m.maxTokens ?? 4096,\n cost: {\n input: m.cost?.input ?? 0,\n output: m.cost?.output ?? 0,\n },\n available: configured.has(`${m.provider}/${m.id}`),\n })),\n })),\n },\n });\n });\n\n // ========== Extension UI (manifest discovery + static assets) ==========\n\n authenticated.get('/api/extensions', async (c) => {\n const loader = service.getExtensionLoader();\n if (!loader) {\n return c.json({ extensions: [] });\n }\n\n const registry = loader.getRegistry();\n const discovered = loader.discoverExtensions();\n const activeIds = new Set<string>();\n for (const [id] of registry.extensions) {\n activeIds.add(id);\n }\n\n loader.setConfig(service.currentConfig as unknown as SurfaceConfig);\n let activationEligibleIds: Set<string> = new Set();\n try {\n const planner = new ActivationPlanner(loader.buildManifestRegistry());\n activationEligibleIds = new Set(\n planner.getActivatedIds(mergeActivationContext(service.currentConfig as unknown as SurfaceConfig)),\n );\n } catch {\n activationEligibleIds = new Set();\n }\n\n const extensions = discovered.map((ext) => ({\n id: ext.manifest.id,\n name: ext.manifest.name,\n description: ext.manifest.description,\n version: ext.manifest.version,\n kind: ext.manifest.kind,\n source: ext.source,\n active: activeIds.has(ext.id),\n activationEligible: activationEligibleIds.has(ext.id),\n hasUi: Boolean(ext.manifest.ui),\n hasConfigSchema: hasNonEmptyConfigSchema(ext.manifest.configSchema),\n ui: ext.manifest.ui\n ? {\n icon: ext.manifest.ui.icon,\n permissions: ext.manifest.ui.permissions,\n contributions: ext.manifest.ui.contributions,\n }\n : undefined,\n }));\n return c.json({ extensions });\n });\n\n /**\n * Built-in (bundled) extension enable/disable — persists `extensions.enabled` / `extensions.disabled`.\n * Body: `{ extensionId: string, enabled: boolean }`\n */\n authenticated.post('/api/extensions/bundled/activation', strictRateLimitMiddleware, async (c) => {\n const body = (await c.req.json().catch(() => null)) as\n | { extensionId?: unknown; enabled?: unknown }\n | null;\n const extensionId =\n typeof body?.extensionId === 'string' ? body.extensionId.trim() : '';\n if (!extensionId) {\n return c.json({ ok: false, error: { message: 'extensionId is required' } }, 400);\n }\n if (typeof body?.enabled !== 'boolean') {\n return c.json({ ok: false, error: { message: 'enabled must be a boolean' } }, 400);\n }\n const result = await service.setBundledExtensionActivationTarget(extensionId, body.enabled);\n if (!result.ok) {\n return c.json({ ok: false, error: { message: result.error ?? 'Request failed' } }, 400);\n }\n return c.json({\n ok: true,\n payload: { requiresGatewayRestart: result.requiresGatewayRestart },\n });\n });\n\n authenticated.get('/api/extensions/:id', async (c) => {\n const extensionId = c.req.param('id');\n const loader = service.getExtensionLoader();\n if (!loader) {\n return c.json({ error: 'Extensions unavailable' }, 503);\n }\n const discovered = loader.discoverExtensions();\n const ext = discovered.find((e) => e.id === extensionId);\n if (!ext) {\n return c.json({ error: 'Extension not found' }, 404);\n }\n const registry = loader.getRegistry();\n return c.json({\n id: ext.manifest.id,\n name: ext.manifest.name,\n description: ext.manifest.description,\n version: ext.manifest.version,\n kind: ext.manifest.kind,\n source: ext.source,\n path: ext.path,\n active: registry.extensions.has(ext.id),\n manifest: ext.manifest,\n });\n });\n\n authenticated.get('/api/extensions/:id/storage', async (c) => {\n const extensionId = c.req.param('id');\n const store = await loadExtensionStore(extensionId);\n return c.json({ keys: Object.keys(store) });\n });\n\n authenticated.get('/api/extensions/:id/storage/:key', async (c) => {\n const extensionId = c.req.param('id');\n const key = decodeURIComponent(c.req.param('key'));\n const store = await loadExtensionStore(extensionId);\n if (!(key in store)) {\n return c.json({ error: 'Key not found' }, 404);\n }\n return c.json({ value: store[key] });\n });\n\n authenticated.put('/api/extensions/:id/storage/:key', async (c) => {\n const extensionId = c.req.param('id');\n const key = decodeURIComponent(c.req.param('key'));\n const body = (await c.req.json().catch(() => null)) as { value?: unknown } | null;\n if (body === null || !('value' in body)) {\n return c.json({ error: 'Request body must contain a \"value\" field' }, 400);\n }\n const store = await loadExtensionStore(extensionId);\n store[key] = body.value;\n await saveExtensionStore(extensionId, store);\n return c.json({ ok: true });\n });\n\n authenticated.delete('/api/extensions/:id/storage/:key', async (c) => {\n const extensionId = c.req.param('id');\n const key = decodeURIComponent(c.req.param('key'));\n const store = await loadExtensionStore(extensionId);\n delete store[key];\n await saveExtensionStore(extensionId, store);\n return c.json({ ok: true });\n });\n\n authenticated.get('/api/extensions/:id/config', async (c) => {\n const extensionId = c.req.param('id');\n return c.json(await loadExtensionStore(`__config__${extensionId}`));\n });\n\n authenticated.patch('/api/extensions/:id/config', async (c) => {\n const extensionId = c.req.param('id');\n const patch = (await c.req.json().catch(() => null)) as Record<string, unknown> | null;\n if (!patch || typeof patch !== 'object' || Array.isArray(patch)) {\n return c.json({ error: 'Request body must be a JSON object' }, 400);\n }\n const namespace = `__config__${extensionId}`;\n const config = await loadExtensionStore(namespace);\n Object.assign(config, patch);\n await saveExtensionStore(namespace, config);\n return c.json({ ok: true });\n });\n\n authenticated.get('/api/context', (c) => {\n const loader = service.getExtensionLoader();\n const snapshot = buildWhenContextSnapshot(\n service.currentConfig as unknown as SurfaceConfig,\n loader,\n );\n return c.json(snapshot);\n });\n\n authenticated.get('/api/marketplace', async (c) => {\n const q = c.req.query('q');\n const category = c.req.query('category');\n try {\n let extensions;\n if (typeof q === 'string' && q.trim()) {\n extensions = await extensionMarketplace.searchExtensions(q.trim());\n } else if (typeof category === 'string' && category.trim()) {\n extensions = await extensionMarketplace.listExtensions(category.trim());\n } else {\n const reg = await extensionMarketplace.fetchRegistry();\n extensions = reg.extensions;\n }\n return c.json({ ok: true, extensions });\n } catch (err) {\n return c.json(\n {\n ok: false,\n extensions: [],\n error: err instanceof Error ? err.message : 'marketplace fetch failed',\n },\n 500,\n );\n }\n });\n\n authenticated.get('/api/marketplace/packages/:pkgName', async (c) => {\n const raw = c.req.param('pkgName');\n if (!raw) {\n return c.json({ ok: false, error: 'Missing package name' }, 400);\n }\n let pkgName: string;\n try {\n pkgName = decodeURIComponent(raw);\n } catch {\n return c.json({ ok: false, error: 'Invalid package name' }, 400);\n }\n try {\n const payload = await service.marketplace.fetchExtensionPackageDetail(pkgName);\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Marketplace request failed' },\n 502,\n );\n }\n });\n\n authenticated.post('/api/marketplace/install', strictRateLimitMiddleware, async (c) => {\n let body: { name?: unknown; version?: unknown; overwrite?: unknown };\n try {\n body = (await c.req.json()) as typeof body;\n } catch {\n return c.json({ ok: false, error: 'Invalid JSON' }, 400);\n }\n const name = typeof body.name === 'string' ? body.name.trim() : '';\n const version = typeof body.version === 'string' ? body.version.trim() : undefined;\n const overwrite =\n body.overwrite === true || body.overwrite === 'true' || body.overwrite === '1';\n if (!name) {\n return c.json(\n { ok: false, error: 'Expected { name: string, version?: string, overwrite?: boolean }' },\n 400,\n );\n }\n try {\n const payload = await service.marketplace.installExtension({ name, version, overwrite });\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Install failed' },\n 400,\n );\n }\n });\n\n authenticated.post('/api/marketplace/uninstall', strictRateLimitMiddleware, async (c) => {\n let body: { extensionId?: unknown };\n try {\n body = (await c.req.json()) as typeof body;\n } catch {\n return c.json({ ok: false, error: 'Invalid JSON' }, 400);\n }\n const extensionId = typeof body.extensionId === 'string' ? body.extensionId.trim() : '';\n if (!extensionId) {\n return c.json({ ok: false, error: 'Expected { extensionId: string }' }, 400);\n }\n try {\n const payload = await service.marketplace.uninstallExtension(extensionId);\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Uninstall failed' },\n 400,\n );\n }\n });\n\n // POST /api/registry/reload — reload gateway config and refresh model list for clients\n authenticated.post('/api/registry/reload', async (c) => {\n try {\n // Reload config\n await service.reloadConfig();\n \n // Reload OAuth credentials from new config\n loadOAuthCredentialsToCache(service);\n \n const models = getAllModels();\n \n // Emit SSE event to all connected clients\n service.emit('registry.updated', { modelCount: models.length });\n \n return c.json({\n ok: true,\n payload: {\n message: 'Registry reloaded',\n modelCount: models.length,\n },\n });\n } catch (err) {\n return c.json({\n error: err instanceof Error ? err.message : 'Failed to reload registry',\n }, 500);\n }\n });\n\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser/extension settings routes: `/api/browser/*` except for the
|
|
3
|
+
* long-running install streams under `/api/browser/{playwright,cloakbrowser}/install/stream`
|
|
4
|
+
* (those live in `browser-install.ts` so the SSE pump doesn't have to load
|
|
5
|
+
* with the rest of settings).
|
|
6
|
+
*
|
|
7
|
+
* Four backend families:
|
|
8
|
+
* - **Extension WS bridge** — pair Chrome via the xopc browser extension.
|
|
9
|
+
* Owns a module-scoped manual handle so the bridge can outlive a config
|
|
10
|
+
* save (UI flow: Start → pair → Save).
|
|
11
|
+
* - **CloakBrowser** — install / launch / probe runtime status.
|
|
12
|
+
* - **Playwright Chromium** — doctor + on-demand install of bundled browser.
|
|
13
|
+
* - **Local CDP** — launch / list / stop user-driven debug Chrome instances.
|
|
14
|
+
* - **Cloud providers** (browserbase / browser-use) — connection test.
|
|
15
|
+
*
|
|
16
|
+
* Extracted from `config.ts` (which was 2237 lines and 80% browser routes).
|
|
17
|
+
*/
|
|
18
|
+
import type { Hono } from 'hono';
|
|
19
|
+
import type { AuthenticatedRouteDeps } from './deps.js';
|
|
20
|
+
export declare function registerBrowserRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void;
|