@xopcai/xopc 0.0.82 → 0.0.83
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 +1 -1
- package/README.zh-CN.md +1 -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-CrpYTHJS.js +222 -0
- package/dist/gateway/static/root/assets/{apps-page-pJ27dsqn.js → apps-page-1mcKh5Rh.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-zd6QNKPx.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-D1KYmOmi.js → channels-status-swr-uRAuhiUo.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-api-Y2wfSJVI.js → cron-api-O2Q_ruV6.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-page-B97KU_RG.js → cron-page-By09AQD-.js} +1 -1
- package/dist/gateway/static/root/assets/{dist-CboA_Css.js → dist-BpQxde0t.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DN_zNmpo.js → extension-debug-page-CY27wj_p.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BUXtOzv5.js → extension-page-C-Ed5ZmP.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-C2dX4KCW.js → extension-settings-page-raLux7E7.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-fa_hiQcX.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-DvfiRVrc.js → heartbeat-config-api-BVl5VHvL.js} +1 -1
- package/dist/gateway/static/root/assets/index-BuFldCsB.css +1 -0
- package/dist/gateway/static/root/assets/{index-DQuaMye9.js → index-Y-iqo-gL.js} +94 -85
- package/dist/gateway/static/root/assets/{logs-page-BQuBpHcc.js → logs-page-BdH2n7ZW.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-Vpchzdp-.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-2Yu-FASs.js → settings-form-section-Kk1yAGBl.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-KBm0u6Dz.js +3 -0
- package/dist/gateway/static/root/assets/skills-page-BjeXXaOn.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-DpTxN4AF.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-CwO8Cf01.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/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/doctor/checks/config-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
- package/dist/src/cli/commands/extension-dev.js +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/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.js +1 -1
- 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/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 +4 -4
- package/dist/src/cli/commands/models.js +1 -1
- 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 +9 -64
- package/dist/src/cli/commands/onboard.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/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 +1 -4
- 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 +2 -2
- 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 +121 -903
- 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/heartbeat/index.js +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,192 +0,0 @@
|
|
|
1
|
-
import { isLoopbackHost } from "./host.js";
|
|
2
|
-
//#region src/gateway/auth-rate-limit.ts
|
|
3
|
-
/**
|
|
4
|
-
* Rate limiting for failed gateway token authentication attempts (per client IP).
|
|
5
|
-
*/
|
|
6
|
-
const DEFAULT_CONFIG = {
|
|
7
|
-
enabled: true,
|
|
8
|
-
maxAttempts: 5,
|
|
9
|
-
windowMs: 900 * 1e3,
|
|
10
|
-
blockDurationMs: 300 * 1e3,
|
|
11
|
-
exemptLoopback: true
|
|
12
|
-
};
|
|
13
|
-
function resolveAuthRateLimitConfig(input) {
|
|
14
|
-
if (!input) return { ...DEFAULT_CONFIG };
|
|
15
|
-
const blockDurationMs = input.blockDurationMs ?? input.lockoutMs ?? DEFAULT_CONFIG.blockDurationMs;
|
|
16
|
-
return {
|
|
17
|
-
enabled: input.enabled ?? DEFAULT_CONFIG.enabled,
|
|
18
|
-
maxAttempts: Math.max(1, Math.floor(input.maxAttempts ?? DEFAULT_CONFIG.maxAttempts)),
|
|
19
|
-
windowMs: Math.max(1e3, Math.floor(input.windowMs ?? DEFAULT_CONFIG.windowMs)),
|
|
20
|
-
blockDurationMs: Math.max(1e3, Math.floor(blockDurationMs)),
|
|
21
|
-
exemptLoopback: input.exemptLoopback ?? DEFAULT_CONFIG.exemptLoopback
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
function isAuthRateLimitGloballyDisabled() {
|
|
25
|
-
return process.env.XOPC_AUTH_RATE_LIMIT === "false";
|
|
26
|
-
}
|
|
27
|
-
function isGatewayStrictSecurityEnabled(cfg) {
|
|
28
|
-
return cfg?.gateway?.security?.strict === true || process.env.XOPC_GATEWAY_STRICT_SECURITY === "1";
|
|
29
|
-
}
|
|
30
|
-
function isLoopbackClientIp(clientIp) {
|
|
31
|
-
if (!clientIp || clientIp === "unknown") return false;
|
|
32
|
-
const trimmed = clientIp.trim();
|
|
33
|
-
if (trimmed.includes(":") && !trimmed.includes(".")) return isLoopbackHost(trimmed.replace(/^\[/, "").replace(/\]$/, ""));
|
|
34
|
-
return isLoopbackHost(trimmed.split(":")[0]);
|
|
35
|
-
}
|
|
36
|
-
/** True when a browser Origin header targets the local gateway console (Electron / loopback SPA). */
|
|
37
|
-
function isLoopbackBrowserOrigin(origin) {
|
|
38
|
-
const trimmed = origin?.trim();
|
|
39
|
-
if (!trimmed || trimmed === "null") return false;
|
|
40
|
-
try {
|
|
41
|
-
return isLoopbackHost(new URL(trimmed).hostname);
|
|
42
|
-
} catch {
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
/** Loopback gateway console in a same-machine browser (Electron embedded UI, local dev). */
|
|
47
|
-
function isLoopbackEmbeddedBrowserClient(origin, clientIp) {
|
|
48
|
-
if (!isLoopbackBrowserOrigin(origin)) return false;
|
|
49
|
-
if (clientIp === "unknown") return true;
|
|
50
|
-
return isLoopbackClientIp(clientIp);
|
|
51
|
-
}
|
|
52
|
-
function parseBrowserOriginRateLimitKey(clientKey) {
|
|
53
|
-
if (!clientKey.startsWith("browser-origin:")) return null;
|
|
54
|
-
const pipeIdx = clientKey.indexOf("|");
|
|
55
|
-
if (pipeIdx === -1) return null;
|
|
56
|
-
return {
|
|
57
|
-
origin: clientKey.slice(15, pipeIdx),
|
|
58
|
-
clientIp: clientKey.slice(pipeIdx + 1)
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
function isLocalBrowserAuthClient(clientKey) {
|
|
62
|
-
const parsed = parseBrowserOriginRateLimitKey(clientKey);
|
|
63
|
-
if (!parsed) return false;
|
|
64
|
-
return isLoopbackEmbeddedBrowserClient(parsed.origin, parsed.clientIp);
|
|
65
|
-
}
|
|
66
|
-
/** Browser-origin auth failures are tracked independently from CLI/server clients. */
|
|
67
|
-
function buildBrowserOriginRateLimitKey(origin, clientIp) {
|
|
68
|
-
return `browser-origin:${origin.trim().toLowerCase()}|${clientIp.trim()}`;
|
|
69
|
-
}
|
|
70
|
-
function shouldSkipRateLimit(clientKey, cfg) {
|
|
71
|
-
if (!cfg.exemptLoopback) return false;
|
|
72
|
-
if (clientKey.startsWith("browser-origin:")) return isLocalBrowserAuthClient(clientKey);
|
|
73
|
-
return isLoopbackClientIp(clientKey);
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Tracks failed auth attempts per IP; blocks further attempts after the threshold.
|
|
77
|
-
*/
|
|
78
|
-
var AuthFailureRateLimiter = class {
|
|
79
|
-
store = /* @__PURE__ */ new Map();
|
|
80
|
-
cleanupTimer;
|
|
81
|
-
constructor() {
|
|
82
|
-
const interval = 600 * 1e3;
|
|
83
|
-
this.cleanupTimer = setInterval(() => this.cleanupStale(), interval);
|
|
84
|
-
this.cleanupTimer.unref?.();
|
|
85
|
-
}
|
|
86
|
-
destroy() {
|
|
87
|
-
if (this.cleanupTimer) {
|
|
88
|
-
clearInterval(this.cleanupTimer);
|
|
89
|
-
this.cleanupTimer = void 0;
|
|
90
|
-
}
|
|
91
|
-
this.store.clear();
|
|
92
|
-
}
|
|
93
|
-
cleanupStale() {
|
|
94
|
-
const now = Date.now();
|
|
95
|
-
const maxAge = 1440 * 60 * 1e3;
|
|
96
|
-
for (const [ip, state] of this.store.entries()) if (now - (state.blockedUntil ?? state.windowStart) > maxAge) this.store.delete(ip);
|
|
97
|
-
}
|
|
98
|
-
checkBlocked(clientKey, cfg, nowMs = Date.now()) {
|
|
99
|
-
if (shouldSkipRateLimit(clientKey, cfg)) return { blocked: false };
|
|
100
|
-
const state = this.store.get(clientKey);
|
|
101
|
-
if (!state?.blockedUntil) return { blocked: false };
|
|
102
|
-
if (nowMs >= state.blockedUntil) {
|
|
103
|
-
state.blockedUntil = void 0;
|
|
104
|
-
state.count = 0;
|
|
105
|
-
state.windowStart = nowMs;
|
|
106
|
-
return { blocked: false };
|
|
107
|
-
}
|
|
108
|
-
return {
|
|
109
|
-
blocked: true,
|
|
110
|
-
retryAfterSec: Math.max(1, Math.ceil((state.blockedUntil - nowMs) / 1e3))
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
recordFailure(clientKey, cfg, nowMs = Date.now()) {
|
|
114
|
-
if (shouldSkipRateLimit(clientKey, cfg)) return;
|
|
115
|
-
let state = this.store.get(clientKey);
|
|
116
|
-
if (!state) {
|
|
117
|
-
state = {
|
|
118
|
-
windowStart: nowMs,
|
|
119
|
-
count: 0
|
|
120
|
-
};
|
|
121
|
-
this.store.set(clientKey, state);
|
|
122
|
-
}
|
|
123
|
-
if (state.blockedUntil && nowMs < state.blockedUntil) return;
|
|
124
|
-
if (state.blockedUntil && nowMs >= state.blockedUntil) {
|
|
125
|
-
state.blockedUntil = void 0;
|
|
126
|
-
state.count = 0;
|
|
127
|
-
state.windowStart = nowMs;
|
|
128
|
-
}
|
|
129
|
-
if (nowMs - state.windowStart > cfg.windowMs) {
|
|
130
|
-
state.count = 0;
|
|
131
|
-
state.windowStart = nowMs;
|
|
132
|
-
}
|
|
133
|
-
state.count += 1;
|
|
134
|
-
if (state.count >= cfg.maxAttempts) state.blockedUntil = nowMs + cfg.blockDurationMs;
|
|
135
|
-
}
|
|
136
|
-
recordSuccess(clientKey) {
|
|
137
|
-
this.store.delete(clientKey);
|
|
138
|
-
}
|
|
139
|
-
resetForTests() {
|
|
140
|
-
this.store.clear();
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
let singleton = null;
|
|
144
|
-
let browserOriginSingleton = null;
|
|
145
|
-
function getAuthFailureRateLimiter() {
|
|
146
|
-
if (!singleton) singleton = new AuthFailureRateLimiter();
|
|
147
|
-
return singleton;
|
|
148
|
-
}
|
|
149
|
-
/** Browser-origin limiter: never exempts loopback (defense-in-depth). */
|
|
150
|
-
function getBrowserOriginAuthFailureRateLimiter() {
|
|
151
|
-
if (!browserOriginSingleton) browserOriginSingleton = new AuthFailureRateLimiter();
|
|
152
|
-
return browserOriginSingleton;
|
|
153
|
-
}
|
|
154
|
-
function resetAuthRateLimitersForTests() {
|
|
155
|
-
getAuthFailureRateLimiter().resetForTests();
|
|
156
|
-
getBrowserOriginAuthFailureRateLimiter().resetForTests();
|
|
157
|
-
}
|
|
158
|
-
function getClientIpFromHeaders(headers) {
|
|
159
|
-
const xff = headers.get("x-forwarded-for");
|
|
160
|
-
if (xff) {
|
|
161
|
-
const first = xff.split(",")[0]?.trim();
|
|
162
|
-
if (first) return first;
|
|
163
|
-
}
|
|
164
|
-
const real = headers.get("x-real-ip")?.trim();
|
|
165
|
-
if (real) return real;
|
|
166
|
-
const cf = headers.get("cf-connecting-ip")?.trim();
|
|
167
|
-
if (cf) return cf;
|
|
168
|
-
return "unknown";
|
|
169
|
-
}
|
|
170
|
-
function resolveAuthRateLimitTracking(params) {
|
|
171
|
-
const origin = params.origin?.trim();
|
|
172
|
-
if (origin) {
|
|
173
|
-
const localBrowserClient = isLoopbackEmbeddedBrowserClient(origin, params.clientIp);
|
|
174
|
-
return {
|
|
175
|
-
limiter: getBrowserOriginAuthFailureRateLimiter(),
|
|
176
|
-
key: buildBrowserOriginRateLimitKey(origin, params.clientIp),
|
|
177
|
-
cfg: {
|
|
178
|
-
...params.cfg,
|
|
179
|
-
exemptLoopback: localBrowserClient ? params.cfg.exemptLoopback : false
|
|
180
|
-
}
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
return {
|
|
184
|
-
limiter: getAuthFailureRateLimiter(),
|
|
185
|
-
key: params.clientIp,
|
|
186
|
-
cfg: params.cfg
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
//#endregion
|
|
190
|
-
export { AuthFailureRateLimiter, buildBrowserOriginRateLimitKey, getAuthFailureRateLimiter, getBrowserOriginAuthFailureRateLimiter, getClientIpFromHeaders, isAuthRateLimitGloballyDisabled, isGatewayStrictSecurityEnabled, isLoopbackBrowserOrigin, isLoopbackClientIp, isLoopbackEmbeddedBrowserClient, resetAuthRateLimitersForTests, resolveAuthRateLimitConfig, resolveAuthRateLimitTracking };
|
|
191
|
-
|
|
192
|
-
//# sourceMappingURL=auth-rate-limit.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth-rate-limit.js","names":[],"sources":["../../../src/gateway/auth-rate-limit.ts"],"sourcesContent":["/**\n * Rate limiting for failed gateway token authentication attempts (per client IP).\n */\n\nimport { isLoopbackHost } from './host.js';\n\nexport type AuthRateLimitConfig = {\n enabled: boolean;\n maxAttempts: number;\n windowMs: number;\n blockDurationMs: number;\n /** When true, loopback client IPs skip rate limiting (default). */\n exemptLoopback: boolean;\n};\n\nconst DEFAULT_CONFIG: AuthRateLimitConfig = {\n enabled: true,\n maxAttempts: 5,\n windowMs: 15 * 60 * 1000,\n blockDurationMs: 5 * 60 * 1000,\n exemptLoopback: true,\n};\n\nexport type GatewayAuthRateLimitInput = {\n enabled?: boolean;\n maxAttempts?: number;\n windowMs?: number;\n blockDurationMs?: number;\n /** OpenClaw alias for blockDurationMs. */\n lockoutMs?: number;\n exemptLoopback?: boolean;\n} | undefined;\n\nexport function resolveAuthRateLimitConfig(\n input: GatewayAuthRateLimitInput,\n): AuthRateLimitConfig {\n if (!input) {\n return { ...DEFAULT_CONFIG };\n }\n const blockDurationMs = input.blockDurationMs ?? input.lockoutMs ?? DEFAULT_CONFIG.blockDurationMs;\n return {\n enabled: input.enabled ?? DEFAULT_CONFIG.enabled,\n maxAttempts: Math.max(1, Math.floor(input.maxAttempts ?? DEFAULT_CONFIG.maxAttempts)),\n windowMs: Math.max(1000, Math.floor(input.windowMs ?? DEFAULT_CONFIG.windowMs)),\n blockDurationMs: Math.max(1000, Math.floor(blockDurationMs)),\n exemptLoopback: input.exemptLoopback ?? DEFAULT_CONFIG.exemptLoopback,\n };\n}\n\nexport function isAuthRateLimitGloballyDisabled(): boolean {\n return process.env.XOPC_AUTH_RATE_LIMIT === 'false';\n}\n\nexport function isGatewayStrictSecurityEnabled(cfg?: {\n gateway?: { security?: { strict?: boolean } };\n}): boolean {\n return (\n cfg?.gateway?.security?.strict === true ||\n process.env.XOPC_GATEWAY_STRICT_SECURITY === '1'\n );\n}\n\nexport function isLoopbackClientIp(clientIp: string | undefined): boolean {\n if (!clientIp || clientIp === 'unknown') {\n return false;\n }\n const trimmed = clientIp.trim();\n if (trimmed.includes(':') && !trimmed.includes('.')) {\n return isLoopbackHost(trimmed.replace(/^\\[/, '').replace(/\\]$/, ''));\n }\n return isLoopbackHost(trimmed.split(':')[0]);\n}\n\n/** True when a browser Origin header targets the local gateway console (Electron / loopback SPA). */\nexport function isLoopbackBrowserOrigin(origin: string | undefined): boolean {\n const trimmed = origin?.trim();\n if (!trimmed || trimmed === 'null') {\n return false;\n }\n try {\n return isLoopbackHost(new URL(trimmed).hostname);\n } catch {\n return false;\n }\n}\n\n/** Loopback gateway console in a same-machine browser (Electron embedded UI, local dev). */\nexport function isLoopbackEmbeddedBrowserClient(\n origin: string | undefined,\n clientIp: string,\n): boolean {\n if (!isLoopbackBrowserOrigin(origin)) {\n return false;\n }\n if (clientIp === 'unknown') {\n return true;\n }\n return isLoopbackClientIp(clientIp);\n}\n\nfunction parseBrowserOriginRateLimitKey(clientKey: string): { origin: string; clientIp: string } | null {\n if (!clientKey.startsWith('browser-origin:')) {\n return null;\n }\n const pipeIdx = clientKey.indexOf('|');\n if (pipeIdx === -1) {\n return null;\n }\n return {\n origin: clientKey.slice('browser-origin:'.length, pipeIdx),\n clientIp: clientKey.slice(pipeIdx + 1),\n };\n}\n\nfunction isLocalBrowserAuthClient(clientKey: string): boolean {\n const parsed = parseBrowserOriginRateLimitKey(clientKey);\n if (!parsed) {\n return false;\n }\n return isLoopbackEmbeddedBrowserClient(parsed.origin, parsed.clientIp);\n}\n\n/** Browser-origin auth failures are tracked independently from CLI/server clients. */\nexport function buildBrowserOriginRateLimitKey(origin: string, clientIp: string): string {\n const normalizedOrigin = origin.trim().toLowerCase();\n return `browser-origin:${normalizedOrigin}|${clientIp.trim()}`;\n}\n\nfunction shouldSkipRateLimit(clientKey: string, cfg: AuthRateLimitConfig): boolean {\n if (!cfg.exemptLoopback) {\n return false;\n }\n if (clientKey.startsWith('browser-origin:')) {\n return isLocalBrowserAuthClient(clientKey);\n }\n return isLoopbackClientIp(clientKey);\n}\n\ntype IpState = {\n windowStart: number;\n count: number;\n blockedUntil?: number;\n};\n\n/**\n * Tracks failed auth attempts per IP; blocks further attempts after the threshold.\n */\nexport class AuthFailureRateLimiter {\n private readonly store = new Map<string, IpState>();\n private cleanupTimer?: NodeJS.Timeout;\n\n constructor() {\n const interval = 10 * 60 * 1000;\n this.cleanupTimer = setInterval(() => this.cleanupStale(), interval);\n this.cleanupTimer.unref?.();\n }\n\n destroy(): void {\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n this.cleanupTimer = undefined;\n }\n this.store.clear();\n }\n\n private cleanupStale(): void {\n const now = Date.now();\n const maxAge = 24 * 60 * 60 * 1000;\n for (const [ip, state] of this.store.entries()) {\n const last = state.blockedUntil ?? state.windowStart;\n if (now - last > maxAge) {\n this.store.delete(ip);\n }\n }\n }\n\n checkBlocked(\n clientKey: string,\n cfg: AuthRateLimitConfig,\n nowMs: number = Date.now(),\n ): { blocked: false } | { blocked: true; retryAfterSec: number } {\n if (shouldSkipRateLimit(clientKey, cfg)) {\n return { blocked: false };\n }\n\n const state = this.store.get(clientKey);\n if (!state?.blockedUntil) {\n return { blocked: false };\n }\n if (nowMs >= state.blockedUntil) {\n state.blockedUntil = undefined;\n state.count = 0;\n state.windowStart = nowMs;\n return { blocked: false };\n }\n return {\n blocked: true,\n retryAfterSec: Math.max(1, Math.ceil((state.blockedUntil - nowMs) / 1000)),\n };\n }\n\n recordFailure(clientKey: string, cfg: AuthRateLimitConfig, nowMs: number = Date.now()): void {\n if (shouldSkipRateLimit(clientKey, cfg)) {\n return;\n }\n\n let state = this.store.get(clientKey);\n if (!state) {\n state = { windowStart: nowMs, count: 0 };\n this.store.set(clientKey, state);\n }\n\n if (state.blockedUntil && nowMs < state.blockedUntil) {\n return;\n }\n if (state.blockedUntil && nowMs >= state.blockedUntil) {\n state.blockedUntil = undefined;\n state.count = 0;\n state.windowStart = nowMs;\n }\n\n if (nowMs - state.windowStart > cfg.windowMs) {\n state.count = 0;\n state.windowStart = nowMs;\n }\n\n state.count += 1;\n if (state.count >= cfg.maxAttempts) {\n state.blockedUntil = nowMs + cfg.blockDurationMs;\n }\n }\n\n recordSuccess(clientKey: string): void {\n this.store.delete(clientKey);\n }\n\n resetForTests(): void {\n this.store.clear();\n }\n}\n\nlet singleton: AuthFailureRateLimiter | null = null;\nlet browserOriginSingleton: AuthFailureRateLimiter | null = null;\n\nexport function getAuthFailureRateLimiter(): AuthFailureRateLimiter {\n if (!singleton) {\n singleton = new AuthFailureRateLimiter();\n }\n return singleton;\n}\n\n/** Browser-origin limiter: never exempts loopback (defense-in-depth). */\nexport function getBrowserOriginAuthFailureRateLimiter(): AuthFailureRateLimiter {\n if (!browserOriginSingleton) {\n browserOriginSingleton = new AuthFailureRateLimiter();\n }\n return browserOriginSingleton;\n}\n\nexport function resetAuthRateLimitersForTests(): void {\n getAuthFailureRateLimiter().resetForTests();\n getBrowserOriginAuthFailureRateLimiter().resetForTests();\n}\n\nexport function getClientIpFromHeaders(headers: {\n get(name: string): string | undefined;\n}): string {\n const xff = headers.get('x-forwarded-for');\n if (xff) {\n const first = xff.split(',')[0]?.trim();\n if (first) return first;\n }\n const real = headers.get('x-real-ip')?.trim();\n if (real) return real;\n const cf = headers.get('cf-connecting-ip')?.trim();\n if (cf) return cf;\n return 'unknown';\n}\n\nexport function resolveAuthRateLimitTracking(params: {\n clientIp: string;\n origin?: string | null;\n cfg: AuthRateLimitConfig;\n}): { limiter: AuthFailureRateLimiter; key: string; cfg: AuthRateLimitConfig } {\n const origin = params.origin?.trim();\n if (origin) {\n const localBrowserClient = isLoopbackEmbeddedBrowserClient(origin, params.clientIp);\n return {\n limiter: getBrowserOriginAuthFailureRateLimiter(),\n key: buildBrowserOriginRateLimitKey(origin, params.clientIp),\n cfg: {\n ...params.cfg,\n exemptLoopback: localBrowserClient ? params.cfg.exemptLoopback : false,\n },\n };\n }\n return {\n limiter: getAuthFailureRateLimiter(),\n key: params.clientIp,\n cfg: params.cfg,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Gateway Restart Handler - SIGUSR1 signal handler for graceful restart
|
|
3
|
-
*
|
|
4
|
-
* Reads restart intent from disk to determine restart behavior:
|
|
5
|
-
* - force=true: exit immediately (KeepAlive will restart)
|
|
6
|
-
* - force=false/unset: wait for active agent turns to complete, then exit
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* Register the SIGUSR1 handler for gateway restart.
|
|
10
|
-
* Call once during gateway startup.
|
|
11
|
-
*/
|
|
12
|
-
export declare function registerGatewayRestartHandler(params?: {
|
|
13
|
-
getActiveAgentTurnCount?: () => number;
|
|
14
|
-
}): void;
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { createLogger } from "../utils/logger/index.js";
|
|
2
|
-
import { init_logger } from "../utils/logger.js";
|
|
3
|
-
import { clearGatewayRestartIntentSync, readGatewayRestartIntentSync } from "../infra/restart-intent.js";
|
|
4
|
-
//#region src/gateway/restart-handler.ts
|
|
5
|
-
init_logger();
|
|
6
|
-
const log = createLogger("RestartHandler");
|
|
7
|
-
const DEFAULT_GRACEFUL_WAIT_MS = 3e4;
|
|
8
|
-
let restartHandlerRegistered = false;
|
|
9
|
-
let activeAgentTurnCounter = null;
|
|
10
|
-
/**
|
|
11
|
-
* Register the SIGUSR1 handler for gateway restart.
|
|
12
|
-
* Call once during gateway startup.
|
|
13
|
-
*/
|
|
14
|
-
function registerGatewayRestartHandler(params) {
|
|
15
|
-
if (restartHandlerRegistered) return;
|
|
16
|
-
restartHandlerRegistered = true;
|
|
17
|
-
if (params?.getActiveAgentTurnCount) activeAgentTurnCounter = params.getActiveAgentTurnCount;
|
|
18
|
-
process.on("SIGUSR1", handleSigusr1);
|
|
19
|
-
log.info("SIGUSR1 restart handler registered");
|
|
20
|
-
}
|
|
21
|
-
async function handleSigusr1() {
|
|
22
|
-
log.info("Received SIGUSR1 restart signal");
|
|
23
|
-
const intent = readGatewayRestartIntentSync();
|
|
24
|
-
clearGatewayRestartIntentSync();
|
|
25
|
-
if (intent?.force) {
|
|
26
|
-
log.info("Force restart requested, exiting immediately");
|
|
27
|
-
process.exit(0);
|
|
28
|
-
}
|
|
29
|
-
const waitMs = intent?.waitMs ?? DEFAULT_GRACEFUL_WAIT_MS;
|
|
30
|
-
if (!activeAgentTurnCounter) {
|
|
31
|
-
log.info("No active turn counter registered, exiting");
|
|
32
|
-
process.exit(0);
|
|
33
|
-
}
|
|
34
|
-
const activeTurns = activeAgentTurnCounter();
|
|
35
|
-
if (activeTurns <= 0) {
|
|
36
|
-
log.info("No active agent turns, exiting immediately");
|
|
37
|
-
process.exit(0);
|
|
38
|
-
}
|
|
39
|
-
log.info({
|
|
40
|
-
activeTurns,
|
|
41
|
-
waitMs
|
|
42
|
-
}, "Waiting for active agent turns to complete");
|
|
43
|
-
await waitForActiveAgentTurnsToComplete(waitMs);
|
|
44
|
-
log.info("Active turns completed, exiting for restart");
|
|
45
|
-
process.exit(0);
|
|
46
|
-
}
|
|
47
|
-
async function waitForActiveAgentTurnsToComplete(maxWaitMs) {
|
|
48
|
-
const startedAt = Date.now();
|
|
49
|
-
const pollIntervalMs = 500;
|
|
50
|
-
while (Date.now() - startedAt < maxWaitMs) {
|
|
51
|
-
if (!activeAgentTurnCounter) break;
|
|
52
|
-
if (activeAgentTurnCounter() <= 0) return;
|
|
53
|
-
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
54
|
-
}
|
|
55
|
-
const remaining = activeAgentTurnCounter?.() ?? 0;
|
|
56
|
-
if (remaining > 0) log.warn({
|
|
57
|
-
remaining,
|
|
58
|
-
maxWaitMs
|
|
59
|
-
}, "Graceful wait timed out, forcing exit");
|
|
60
|
-
}
|
|
61
|
-
//#endregion
|
|
62
|
-
export { registerGatewayRestartHandler };
|
|
63
|
-
|
|
64
|
-
//# sourceMappingURL=restart-handler.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"restart-handler.js","names":[],"sources":["../../../src/gateway/restart-handler.ts"],"sourcesContent":["/**\n * Gateway Restart Handler - SIGUSR1 signal handler for graceful restart\n *\n * Reads restart intent from disk to determine restart behavior:\n * - force=true: exit immediately (KeepAlive will restart)\n * - force=false/unset: wait for active agent turns to complete, then exit\n */\n\nimport { createLogger } from '../utils/logger.js';\nimport {\n readGatewayRestartIntentSync,\n clearGatewayRestartIntentSync,\n} from '../infra/restart-intent.js';\n\nconst log = createLogger('RestartHandler');\n\nconst DEFAULT_GRACEFUL_WAIT_MS = 30_000;\n\nlet restartHandlerRegistered = false;\nlet activeAgentTurnCounter: (() => number) | null = null;\n\n/**\n * Register the SIGUSR1 handler for gateway restart.\n * Call once during gateway startup.\n */\nexport function registerGatewayRestartHandler(params?: {\n getActiveAgentTurnCount?: () => number;\n}): void {\n if (restartHandlerRegistered) return;\n restartHandlerRegistered = true;\n\n if (params?.getActiveAgentTurnCount) {\n activeAgentTurnCounter = params.getActiveAgentTurnCount;\n }\n\n process.on('SIGUSR1', handleSigusr1);\n log.info('SIGUSR1 restart handler registered');\n}\n\nasync function handleSigusr1(): Promise<void> {\n log.info('Received SIGUSR1 restart signal');\n\n const intent = readGatewayRestartIntentSync();\n clearGatewayRestartIntentSync();\n\n if (intent?.force) {\n log.info('Force restart requested, exiting immediately');\n process.exit(0);\n }\n\n // Graceful restart: wait for active agent turns to complete\n const waitMs = intent?.waitMs ?? DEFAULT_GRACEFUL_WAIT_MS;\n\n if (!activeAgentTurnCounter) {\n log.info('No active turn counter registered, exiting');\n process.exit(0);\n }\n\n const activeTurns = activeAgentTurnCounter();\n if (activeTurns <= 0) {\n log.info('No active agent turns, exiting immediately');\n process.exit(0);\n }\n\n log.info({ activeTurns, waitMs }, 'Waiting for active agent turns to complete');\n\n await waitForActiveAgentTurnsToComplete(waitMs);\n log.info('Active turns completed, exiting for restart');\n process.exit(0);\n}\n\nasync function waitForActiveAgentTurnsToComplete(maxWaitMs: number): Promise<void> {\n const startedAt = Date.now();\n const pollIntervalMs = 500;\n\n while (Date.now() - startedAt < maxWaitMs) {\n if (!activeAgentTurnCounter) break;\n\n const activeTurns = activeAgentTurnCounter();\n if (activeTurns <= 0) {\n return;\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));\n }\n\n // Timeout reached, exit anyway\n const remaining = activeAgentTurnCounter?.() ?? 0;\n if (remaining > 0) {\n log.warn({ remaining, maxWaitMs }, 'Graceful wait timed out, forcing exit');\n }\n}\n"],"mappings":";;;;aAQkD;AAMlD,MAAM,MAAM,aAAa,iBAAiB;AAE1C,MAAM,2BAA2B;AAEjC,IAAI,2BAA2B;AAC/B,IAAI,yBAAgD;;;;;AAMpD,SAAgB,8BAA8B,QAErC;AACP,KAAI,yBAA0B;AAC9B,4BAA2B;AAE3B,KAAI,QAAQ,wBACV,0BAAyB,OAAO;AAGlC,SAAQ,GAAG,WAAW,cAAc;AACpC,KAAI,KAAK,qCAAqC;;AAGhD,eAAe,gBAA+B;AAC5C,KAAI,KAAK,kCAAkC;CAE3C,MAAM,SAAS,8BAA8B;AAC7C,gCAA+B;AAE/B,KAAI,QAAQ,OAAO;AACjB,MAAI,KAAK,+CAA+C;AACxD,UAAQ,KAAK,EAAE;;CAIjB,MAAM,SAAS,QAAQ,UAAU;AAEjC,KAAI,CAAC,wBAAwB;AAC3B,MAAI,KAAK,6CAA6C;AACtD,UAAQ,KAAK,EAAE;;CAGjB,MAAM,cAAc,wBAAwB;AAC5C,KAAI,eAAe,GAAG;AACpB,MAAI,KAAK,6CAA6C;AACtD,UAAQ,KAAK,EAAE;;AAGjB,KAAI,KAAK;EAAE;EAAa;EAAQ,EAAE,6CAA6C;AAE/E,OAAM,kCAAkC,OAAO;AAC/C,KAAI,KAAK,8CAA8C;AACvD,SAAQ,KAAK,EAAE;;AAGjB,eAAe,kCAAkC,WAAkC;CACjF,MAAM,YAAY,KAAK,KAAK;CAC5B,MAAM,iBAAiB;AAEvB,QAAO,KAAK,KAAK,GAAG,YAAY,WAAW;AACzC,MAAI,CAAC,uBAAwB;AAG7B,MADoB,wBACL,IAAI,EACjB;AAGF,QAAM,IAAI,SAAS,YAAY,WAAW,SAAS,eAAe,CAAC;;CAIrE,MAAM,YAAY,0BAA0B,IAAI;AAChD,KAAI,YAAY,EACd,KAAI,KAAK;EAAE;EAAW;EAAW,EAAE,wCAAwC"}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unauthorized flood guard for WebSocket connections.
|
|
3
|
-
*
|
|
4
|
-
* Tracks repeated unauthorized message attempts on a single WS connection
|
|
5
|
-
* and decides when to forcibly close it. Prevents a rogue client from
|
|
6
|
-
* holding a socket open and spamming unauthorized requests.
|
|
7
|
-
*/
|
|
8
|
-
export type FloodGuardOptions = {
|
|
9
|
-
/** Close the connection after this many unauthorized messages. @default 10 */
|
|
10
|
-
closeAfter?: number;
|
|
11
|
-
/** Log every N unauthorized messages to prevent log spam. @default 100 */
|
|
12
|
-
logEvery?: number;
|
|
13
|
-
};
|
|
14
|
-
export type FloodGuardDecision = {
|
|
15
|
-
shouldClose: boolean;
|
|
16
|
-
shouldLog: boolean;
|
|
17
|
-
count: number;
|
|
18
|
-
suppressedSinceLastLog: number;
|
|
19
|
-
};
|
|
20
|
-
export declare class UnauthorizedFloodGuard {
|
|
21
|
-
private readonly closeAfter;
|
|
22
|
-
private readonly logEvery;
|
|
23
|
-
private count;
|
|
24
|
-
private suppressedSinceLastLog;
|
|
25
|
-
constructor(options?: FloodGuardOptions);
|
|
26
|
-
registerUnauthorized(): FloodGuardDecision;
|
|
27
|
-
reset(): void;
|
|
28
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
//#region src/gateway/security/flood-guard.ts
|
|
2
|
-
const DEFAULT_CLOSE_AFTER = 10;
|
|
3
|
-
const DEFAULT_LOG_EVERY = 100;
|
|
4
|
-
var UnauthorizedFloodGuard = class {
|
|
5
|
-
closeAfter;
|
|
6
|
-
logEvery;
|
|
7
|
-
count = 0;
|
|
8
|
-
suppressedSinceLastLog = 0;
|
|
9
|
-
constructor(options) {
|
|
10
|
-
this.closeAfter = Math.max(1, Math.floor(options?.closeAfter ?? DEFAULT_CLOSE_AFTER));
|
|
11
|
-
this.logEvery = Math.max(1, Math.floor(options?.logEvery ?? DEFAULT_LOG_EVERY));
|
|
12
|
-
}
|
|
13
|
-
registerUnauthorized() {
|
|
14
|
-
this.count += 1;
|
|
15
|
-
const shouldClose = this.count > this.closeAfter;
|
|
16
|
-
if (!(this.count === 1 || this.count % this.logEvery === 0 || shouldClose)) {
|
|
17
|
-
this.suppressedSinceLastLog += 1;
|
|
18
|
-
return {
|
|
19
|
-
shouldClose,
|
|
20
|
-
shouldLog: false,
|
|
21
|
-
count: this.count,
|
|
22
|
-
suppressedSinceLastLog: 0
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
const suppressedSinceLastLog = this.suppressedSinceLastLog;
|
|
26
|
-
this.suppressedSinceLastLog = 0;
|
|
27
|
-
return {
|
|
28
|
-
shouldClose,
|
|
29
|
-
shouldLog: true,
|
|
30
|
-
count: this.count,
|
|
31
|
-
suppressedSinceLastLog
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
reset() {
|
|
35
|
-
this.count = 0;
|
|
36
|
-
this.suppressedSinceLastLog = 0;
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
//#endregion
|
|
40
|
-
export { UnauthorizedFloodGuard };
|
|
41
|
-
|
|
42
|
-
//# sourceMappingURL=flood-guard.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"flood-guard.js","names":[],"sources":["../../../../src/gateway/security/flood-guard.ts"],"sourcesContent":["/**\n * Unauthorized flood guard for WebSocket connections.\n *\n * Tracks repeated unauthorized message attempts on a single WS connection\n * and decides when to forcibly close it. Prevents a rogue client from\n * holding a socket open and spamming unauthorized requests.\n */\n\nexport type FloodGuardOptions = {\n /** Close the connection after this many unauthorized messages. @default 10 */\n closeAfter?: number;\n /** Log every N unauthorized messages to prevent log spam. @default 100 */\n logEvery?: number;\n};\n\nexport type FloodGuardDecision = {\n shouldClose: boolean;\n shouldLog: boolean;\n count: number;\n suppressedSinceLastLog: number;\n};\n\nconst DEFAULT_CLOSE_AFTER = 10;\nconst DEFAULT_LOG_EVERY = 100;\n\nexport class UnauthorizedFloodGuard {\n private readonly closeAfter: number;\n private readonly logEvery: number;\n private count = 0;\n private suppressedSinceLastLog = 0;\n\n constructor(options?: FloodGuardOptions) {\n this.closeAfter = Math.max(1, Math.floor(options?.closeAfter ?? DEFAULT_CLOSE_AFTER));\n this.logEvery = Math.max(1, Math.floor(options?.logEvery ?? DEFAULT_LOG_EVERY));\n }\n\n registerUnauthorized(): FloodGuardDecision {\n this.count += 1;\n const shouldClose = this.count > this.closeAfter;\n const shouldLog = this.count === 1 || this.count % this.logEvery === 0 || shouldClose;\n\n if (!shouldLog) {\n this.suppressedSinceLastLog += 1;\n return {\n shouldClose,\n shouldLog: false,\n count: this.count,\n suppressedSinceLastLog: 0,\n };\n }\n\n const suppressedSinceLastLog = this.suppressedSinceLastLog;\n this.suppressedSinceLastLog = 0;\n return {\n shouldClose,\n shouldLog: true,\n count: this.count,\n suppressedSinceLastLog,\n };\n }\n\n reset(): void {\n this.count = 0;\n this.suppressedSinceLastLog = 0;\n }\n}\n"],"mappings":";AAsBA,MAAM,sBAAsB;AAC5B,MAAM,oBAAoB;AAE1B,IAAa,yBAAb,MAAoC;CAClC;CACA;CACA,QAAgB;CAChB,yBAAiC;CAEjC,YAAY,SAA6B;AACvC,OAAK,aAAa,KAAK,IAAI,GAAG,KAAK,MAAM,SAAS,cAAc,oBAAoB,CAAC;AACrF,OAAK,WAAW,KAAK,IAAI,GAAG,KAAK,MAAM,SAAS,YAAY,kBAAkB,CAAC;;CAGjF,uBAA2C;AACzC,OAAK,SAAS;EACd,MAAM,cAAc,KAAK,QAAQ,KAAK;AAGtC,MAAI,EAFc,KAAK,UAAU,KAAK,KAAK,QAAQ,KAAK,aAAa,KAAK,cAE1D;AACd,QAAK,0BAA0B;AAC/B,UAAO;IACL;IACA,WAAW;IACX,OAAO,KAAK;IACZ,wBAAwB;IACzB;;EAGH,MAAM,yBAAyB,KAAK;AACpC,OAAK,yBAAyB;AAC9B,SAAO;GACL;GACA,WAAW;GACX,OAAO,KAAK;GACZ;GACD;;CAGH,QAAc;AACZ,OAAK,QAAQ;AACb,OAAK,yBAAyB"}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fixed Window Rate Limiter
|
|
3
|
-
*
|
|
4
|
-
* Simple rate limiting using fixed window algorithm.
|
|
5
|
-
* Prevents abuse by limiting requests within a time window.
|
|
6
|
-
*/
|
|
7
|
-
export type RateLimitResult = {
|
|
8
|
-
/** Whether the request is allowed */
|
|
9
|
-
allowed: boolean;
|
|
10
|
-
/** Time to wait before retry (ms) */
|
|
11
|
-
retryAfterMs: number;
|
|
12
|
-
/** Remaining requests in current window */
|
|
13
|
-
remaining: number;
|
|
14
|
-
};
|
|
15
|
-
export type FixedWindowRateLimiter = {
|
|
16
|
-
consume: () => RateLimitResult;
|
|
17
|
-
reset: () => void;
|
|
18
|
-
};
|
|
19
|
-
export declare function createFixedWindowRateLimiter(params: {
|
|
20
|
-
maxRequests: number;
|
|
21
|
-
windowMs: number;
|
|
22
|
-
now?: () => number;
|
|
23
|
-
}): FixedWindowRateLimiter;
|
|
24
|
-
/** Per-session rate limiter cache */
|
|
25
|
-
export declare class SessionRateLimiter {
|
|
26
|
-
private readonly config;
|
|
27
|
-
private readonly limiters;
|
|
28
|
-
constructor(config: {
|
|
29
|
-
maxRequests: number;
|
|
30
|
-
windowMs: number;
|
|
31
|
-
});
|
|
32
|
-
/** Consume a request for the given session */
|
|
33
|
-
consume(sessionKey: string): RateLimitResult;
|
|
34
|
-
/** Reset rate limiter for a session */
|
|
35
|
-
reset(sessionKey: string): void;
|
|
36
|
-
/** Clear all limiters */
|
|
37
|
-
clear(): void;
|
|
38
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
//#region src/infra/rate-limit.ts
|
|
2
|
-
function createFixedWindowRateLimiter(params) {
|
|
3
|
-
const maxRequests = Math.max(1, Math.floor(params.maxRequests));
|
|
4
|
-
const windowMs = Math.max(1, Math.floor(params.windowMs));
|
|
5
|
-
const now = params.now ?? Date.now;
|
|
6
|
-
let count = 0;
|
|
7
|
-
let windowStartMs = 0;
|
|
8
|
-
return {
|
|
9
|
-
consume() {
|
|
10
|
-
const nowMs = now();
|
|
11
|
-
if (nowMs - windowStartMs >= windowMs) {
|
|
12
|
-
windowStartMs = nowMs;
|
|
13
|
-
count = 0;
|
|
14
|
-
}
|
|
15
|
-
if (count >= maxRequests) return {
|
|
16
|
-
allowed: false,
|
|
17
|
-
retryAfterMs: Math.max(0, windowStartMs + windowMs - nowMs),
|
|
18
|
-
remaining: 0
|
|
19
|
-
};
|
|
20
|
-
count += 1;
|
|
21
|
-
return {
|
|
22
|
-
allowed: true,
|
|
23
|
-
retryAfterMs: 0,
|
|
24
|
-
remaining: Math.max(0, maxRequests - count)
|
|
25
|
-
};
|
|
26
|
-
},
|
|
27
|
-
reset() {
|
|
28
|
-
count = 0;
|
|
29
|
-
windowStartMs = 0;
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
/** Per-session rate limiter cache */
|
|
34
|
-
var SessionRateLimiter = class {
|
|
35
|
-
limiters = /* @__PURE__ */ new Map();
|
|
36
|
-
constructor(config) {
|
|
37
|
-
this.config = config;
|
|
38
|
-
}
|
|
39
|
-
/** Consume a request for the given session */
|
|
40
|
-
consume(sessionKey) {
|
|
41
|
-
let limiter = this.limiters.get(sessionKey);
|
|
42
|
-
if (!limiter) {
|
|
43
|
-
limiter = createFixedWindowRateLimiter(this.config);
|
|
44
|
-
this.limiters.set(sessionKey, limiter);
|
|
45
|
-
}
|
|
46
|
-
return limiter.consume();
|
|
47
|
-
}
|
|
48
|
-
/** Reset rate limiter for a session */
|
|
49
|
-
reset(sessionKey) {
|
|
50
|
-
this.limiters.delete(sessionKey);
|
|
51
|
-
}
|
|
52
|
-
/** Clear all limiters */
|
|
53
|
-
clear() {
|
|
54
|
-
this.limiters.clear();
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
//#endregion
|
|
58
|
-
export { SessionRateLimiter, createFixedWindowRateLimiter };
|
|
59
|
-
|
|
60
|
-
//# sourceMappingURL=rate-limit.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit.js","names":[],"sources":["../../../src/infra/rate-limit.ts"],"sourcesContent":["/**\n * Fixed Window Rate Limiter\n *\n * Simple rate limiting using fixed window algorithm.\n * Prevents abuse by limiting requests within a time window.\n */\n\nexport type RateLimitResult = {\n /** Whether the request is allowed */\n allowed: boolean;\n /** Time to wait before retry (ms) */\n retryAfterMs: number;\n /** Remaining requests in current window */\n remaining: number;\n};\n\nexport type FixedWindowRateLimiter = {\n consume: () => RateLimitResult;\n reset: () => void;\n};\n\nexport function createFixedWindowRateLimiter(params: {\n maxRequests: number;\n windowMs: number;\n now?: () => number;\n}): FixedWindowRateLimiter {\n const maxRequests = Math.max(1, Math.floor(params.maxRequests));\n const windowMs = Math.max(1, Math.floor(params.windowMs));\n const now = params.now ?? Date.now;\n\n let count = 0;\n let windowStartMs = 0;\n\n return {\n consume(): RateLimitResult {\n const nowMs = now();\n \n // Reset window if expired\n if (nowMs - windowStartMs >= windowMs) {\n windowStartMs = nowMs;\n count = 0;\n }\n\n // Check limit\n if (count >= maxRequests) {\n return {\n allowed: false,\n retryAfterMs: Math.max(0, windowStartMs + windowMs - nowMs),\n remaining: 0,\n };\n }\n\n count += 1;\n return {\n allowed: true,\n retryAfterMs: 0,\n remaining: Math.max(0, maxRequests - count),\n };\n },\n\n reset(): void {\n count = 0;\n windowStartMs = 0;\n },\n };\n}\n\n/** Per-session rate limiter cache */\nexport class SessionRateLimiter {\n private readonly limiters = new Map<string, FixedWindowRateLimiter>();\n\n constructor(\n private readonly config: {\n maxRequests: number;\n windowMs: number;\n }\n ) {}\n\n /** Consume a request for the given session */\n consume(sessionKey: string): RateLimitResult {\n let limiter = this.limiters.get(sessionKey);\n if (!limiter) {\n limiter = createFixedWindowRateLimiter(this.config);\n this.limiters.set(sessionKey, limiter);\n }\n return limiter.consume();\n }\n\n /** Reset rate limiter for a session */\n reset(sessionKey: string): void {\n this.limiters.delete(sessionKey);\n }\n\n /** Clear all limiters */\n clear(): void {\n this.limiters.clear();\n }\n}\n"],"mappings":";AAqBA,SAAgB,6BAA6B,QAIlB;CACzB,MAAM,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,YAAY,CAAC;CAC/D,MAAM,WAAW,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,SAAS,CAAC;CACzD,MAAM,MAAM,OAAO,OAAO,KAAK;CAE/B,IAAI,QAAQ;CACZ,IAAI,gBAAgB;AAEpB,QAAO;EACL,UAA2B;GACzB,MAAM,QAAQ,KAAK;AAGnB,OAAI,QAAQ,iBAAiB,UAAU;AACrC,oBAAgB;AAChB,YAAQ;;AAIV,OAAI,SAAS,YACX,QAAO;IACL,SAAS;IACT,cAAc,KAAK,IAAI,GAAG,gBAAgB,WAAW,MAAM;IAC3D,WAAW;IACZ;AAGH,YAAS;AACT,UAAO;IACL,SAAS;IACT,cAAc;IACd,WAAW,KAAK,IAAI,GAAG,cAAc,MAAM;IAC5C;;EAGH,QAAc;AACZ,WAAQ;AACR,mBAAgB;;EAEnB;;;AAIH,IAAa,qBAAb,MAAgC;CAC9B,2BAA4B,IAAI,KAAqC;CAErE,YACE,QAIA;AAJiB,OAAA,SAAA;;;CAOnB,QAAQ,YAAqC;EAC3C,IAAI,UAAU,KAAK,SAAS,IAAI,WAAW;AAC3C,MAAI,CAAC,SAAS;AACZ,aAAU,6BAA6B,KAAK,OAAO;AACnD,QAAK,SAAS,IAAI,YAAY,QAAQ;;AAExC,SAAO,QAAQ,SAAS;;;CAI1B,MAAM,YAA0B;AAC9B,OAAK,SAAS,OAAO,WAAW;;;CAIlC,QAAc;AACZ,OAAK,SAAS,OAAO"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Restart Intent - File-based coordination between CLI and gateway
|
|
3
|
-
*
|
|
4
|
-
* CLI writes an intent file before sending restart signal.
|
|
5
|
-
* Gateway reads it in SIGUSR1 handler to determine restart behavior.
|
|
6
|
-
*/
|
|
7
|
-
import type { GatewayRestartIntent } from '../daemon/types.js';
|
|
8
|
-
/** Write restart intent (CLI side, before sending restart signal) */
|
|
9
|
-
export declare function writeGatewayRestartIntentSync(intent: GatewayRestartIntent): void;
|
|
10
|
-
/** Read restart intent (gateway side, in SIGUSR1 handler) */
|
|
11
|
-
export declare function readGatewayRestartIntentSync(): GatewayRestartIntent | null;
|
|
12
|
-
/** Clear restart intent (after consumption) */
|
|
13
|
-
export declare function clearGatewayRestartIntentSync(): void;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { init_paths_state, resolveStateDir } from "../config/paths-state.js";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
4
|
-
//#region src/infra/restart-intent.ts
|
|
5
|
-
/**
|
|
6
|
-
* Restart Intent - File-based coordination between CLI and gateway
|
|
7
|
-
*
|
|
8
|
-
* CLI writes an intent file before sending restart signal.
|
|
9
|
-
* Gateway reads it in SIGUSR1 handler to determine restart behavior.
|
|
10
|
-
*/
|
|
11
|
-
init_paths_state();
|
|
12
|
-
const INTENT_FILENAME = "restart-intent.json";
|
|
13
|
-
function resolveIntentPath() {
|
|
14
|
-
return path.join(resolveStateDir(), INTENT_FILENAME);
|
|
15
|
-
}
|
|
16
|
-
/** Write restart intent (CLI side, before sending restart signal) */
|
|
17
|
-
function writeGatewayRestartIntentSync(intent) {
|
|
18
|
-
const intentPath = resolveIntentPath();
|
|
19
|
-
mkdirSync(path.dirname(intentPath), { recursive: true });
|
|
20
|
-
writeFileSync(intentPath, JSON.stringify(intent, null, 2), "utf8");
|
|
21
|
-
}
|
|
22
|
-
/** Read restart intent (gateway side, in SIGUSR1 handler) */
|
|
23
|
-
function readGatewayRestartIntentSync() {
|
|
24
|
-
try {
|
|
25
|
-
const raw = readFileSync(resolveIntentPath(), "utf8");
|
|
26
|
-
return JSON.parse(raw);
|
|
27
|
-
} catch {
|
|
28
|
-
return null;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
/** Clear restart intent (after consumption) */
|
|
32
|
-
function clearGatewayRestartIntentSync() {
|
|
33
|
-
try {
|
|
34
|
-
rmSync(resolveIntentPath());
|
|
35
|
-
} catch {}
|
|
36
|
-
}
|
|
37
|
-
//#endregion
|
|
38
|
-
export { clearGatewayRestartIntentSync, readGatewayRestartIntentSync, writeGatewayRestartIntentSync };
|
|
39
|
-
|
|
40
|
-
//# sourceMappingURL=restart-intent.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"restart-intent.js","names":[],"sources":["../../../src/infra/restart-intent.ts"],"sourcesContent":["/**\n * Restart Intent - File-based coordination between CLI and gateway\n *\n * CLI writes an intent file before sending restart signal.\n * Gateway reads it in SIGUSR1 handler to determine restart behavior.\n */\n\nimport { mkdirSync, readFileSync, writeFileSync, rmSync } from 'node:fs';\nimport path from 'node:path';\nimport { resolveStateDir } from '../config/paths-state.js';\nimport type { GatewayRestartIntent } from '../daemon/types.js';\n\nconst INTENT_FILENAME = 'restart-intent.json';\n\nfunction resolveIntentPath(): string {\n return path.join(resolveStateDir(), INTENT_FILENAME);\n}\n\n/** Write restart intent (CLI side, before sending restart signal) */\nexport function writeGatewayRestartIntentSync(intent: GatewayRestartIntent): void {\n const intentPath = resolveIntentPath();\n mkdirSync(path.dirname(intentPath), { recursive: true });\n writeFileSync(intentPath, JSON.stringify(intent, null, 2), 'utf8');\n}\n\n/** Read restart intent (gateway side, in SIGUSR1 handler) */\nexport function readGatewayRestartIntentSync(): GatewayRestartIntent | null {\n try {\n const raw = readFileSync(resolveIntentPath(), 'utf8');\n return JSON.parse(raw) as GatewayRestartIntent;\n } catch {\n return null;\n }\n}\n\n/** Clear restart intent (after consumption) */\nexport function clearGatewayRestartIntentSync(): void {\n try {\n rmSync(resolveIntentPath());\n } catch {\n // File may not exist\n }\n}\n"],"mappings":";;;;;;;;;;kBAS2D;AAG3D,MAAM,kBAAkB;AAExB,SAAS,oBAA4B;AACnC,QAAO,KAAK,KAAK,iBAAiB,EAAE,gBAAgB;;;AAItD,SAAgB,8BAA8B,QAAoC;CAChF,MAAM,aAAa,mBAAmB;AACtC,WAAU,KAAK,QAAQ,WAAW,EAAE,EAAE,WAAW,MAAM,CAAC;AACxD,eAAc,YAAY,KAAK,UAAU,QAAQ,MAAM,EAAE,EAAE,OAAO;;;AAIpE,SAAgB,+BAA4D;AAC1E,KAAI;EACF,MAAM,MAAM,aAAa,mBAAmB,EAAE,OAAO;AACrD,SAAO,KAAK,MAAM,IAAI;SAChB;AACN,SAAO;;;;AAKX,SAAgB,gCAAsC;AACpD,KAAI;AACF,SAAO,mBAAmB,CAAC;SACrB"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Restart Sentinel - Upgrade recovery coordination
|
|
3
|
-
*
|
|
4
|
-
* After an auto-update completes, the update runner writes a sentinel file.
|
|
5
|
-
* On next gateway startup, the sentinel is consumed to:
|
|
6
|
-
* 1. Log the version transition
|
|
7
|
-
* 2. Restore active session context
|
|
8
|
-
* 3. Broadcast update-complete via SSE
|
|
9
|
-
*/
|
|
10
|
-
export interface RestartSentinel {
|
|
11
|
-
previousVersion: string;
|
|
12
|
-
newVersion: string;
|
|
13
|
-
restartedAt: string;
|
|
14
|
-
sessionKeys?: string[];
|
|
15
|
-
reason?: string;
|
|
16
|
-
}
|
|
17
|
-
export declare function writeRestartSentinel(sentinel: RestartSentinel): void;
|
|
18
|
-
/** Read and delete the sentinel file atomically. Returns null if not present. */
|
|
19
|
-
export declare function consumeRestartSentinel(): RestartSentinel | null;
|
|
20
|
-
/** Read without consuming (for inspection) */
|
|
21
|
-
export declare function readRestartSentinel(): RestartSentinel | null;
|
|
22
|
-
/** Check if a sentinel file exists */
|
|
23
|
-
export declare function hasRestartSentinel(): boolean;
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { init_paths_state, resolveStateDir } from "../config/paths-state.js";
|
|
2
|
-
import { createLogger } from "../utils/logger/index.js";
|
|
3
|
-
import { init_logger } from "../utils/logger.js";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
6
|
-
//#region src/infra/restart-sentinel.ts
|
|
7
|
-
/**
|
|
8
|
-
* Restart Sentinel - Upgrade recovery coordination
|
|
9
|
-
*
|
|
10
|
-
* After an auto-update completes, the update runner writes a sentinel file.
|
|
11
|
-
* On next gateway startup, the sentinel is consumed to:
|
|
12
|
-
* 1. Log the version transition
|
|
13
|
-
* 2. Restore active session context
|
|
14
|
-
* 3. Broadcast update-complete via SSE
|
|
15
|
-
*/
|
|
16
|
-
init_paths_state();
|
|
17
|
-
init_logger();
|
|
18
|
-
const log = createLogger("RestartSentinel");
|
|
19
|
-
const SENTINEL_FILENAME = "restart-sentinel.json";
|
|
20
|
-
function resolveSentinelPath() {
|
|
21
|
-
return path.join(resolveStateDir(), SENTINEL_FILENAME);
|
|
22
|
-
}
|
|
23
|
-
function writeRestartSentinel(sentinel) {
|
|
24
|
-
const sentinelPath = resolveSentinelPath();
|
|
25
|
-
mkdirSync(path.dirname(sentinelPath), { recursive: true });
|
|
26
|
-
writeFileSync(sentinelPath, JSON.stringify(sentinel, null, 2), "utf8");
|
|
27
|
-
log.info({
|
|
28
|
-
previousVersion: sentinel.previousVersion,
|
|
29
|
-
newVersion: sentinel.newVersion
|
|
30
|
-
}, "Restart sentinel written");
|
|
31
|
-
}
|
|
32
|
-
/** Read and delete the sentinel file atomically. Returns null if not present. */
|
|
33
|
-
function consumeRestartSentinel() {
|
|
34
|
-
const sentinelPath = resolveSentinelPath();
|
|
35
|
-
try {
|
|
36
|
-
const raw = readFileSync(sentinelPath, "utf8");
|
|
37
|
-
const parsed = JSON.parse(raw);
|
|
38
|
-
if (!parsed.previousVersion || !parsed.newVersion || !parsed.restartedAt) {
|
|
39
|
-
rmSync(sentinelPath, { force: true });
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
rmSync(sentinelPath, { force: true });
|
|
43
|
-
log.info({
|
|
44
|
-
previousVersion: parsed.previousVersion,
|
|
45
|
-
newVersion: parsed.newVersion
|
|
46
|
-
}, "Restart sentinel consumed");
|
|
47
|
-
return parsed;
|
|
48
|
-
} catch {
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
/** Read without consuming (for inspection) */
|
|
53
|
-
function readRestartSentinel() {
|
|
54
|
-
try {
|
|
55
|
-
const raw = readFileSync(resolveSentinelPath(), "utf8");
|
|
56
|
-
const parsed = JSON.parse(raw);
|
|
57
|
-
if (!parsed.previousVersion || !parsed.newVersion) return null;
|
|
58
|
-
return parsed;
|
|
59
|
-
} catch {
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
/** Check if a sentinel file exists */
|
|
64
|
-
function hasRestartSentinel() {
|
|
65
|
-
try {
|
|
66
|
-
readFileSync(resolveSentinelPath());
|
|
67
|
-
return true;
|
|
68
|
-
} catch {
|
|
69
|
-
return false;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
//#endregion
|
|
73
|
-
export { consumeRestartSentinel, hasRestartSentinel, readRestartSentinel, writeRestartSentinel };
|
|
74
|
-
|
|
75
|
-
//# sourceMappingURL=restart-sentinel.js.map
|