@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,10 +1,12 @@
|
|
|
1
1
|
import { createLogger } from "../../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../../utils/logger.js";
|
|
3
|
+
import { formatPortDiagnostics, inspectPortUsage } from "../../../infra/ports.js";
|
|
3
4
|
//#region src/cli/commands/gateway/restart-health.ts
|
|
4
5
|
init_logger();
|
|
5
6
|
const log = createLogger("RestartHealth");
|
|
6
7
|
const DEFAULT_RESTART_HEALTH_TIMEOUT_MS = 6e4;
|
|
7
8
|
const DEFAULT_RESTART_HEALTH_DELAY_MS = 500;
|
|
9
|
+
const DEFAULT_RESTART_HEALTH_ATTEMPTS = Math.ceil(DEFAULT_RESTART_HEALTH_TIMEOUT_MS / 500);
|
|
8
10
|
/**
|
|
9
11
|
* Wait for gateway restart to complete and verify health.
|
|
10
12
|
*
|
|
@@ -148,7 +150,49 @@ async function probeHealth(port, token) {
|
|
|
148
150
|
function sleep(ms) {
|
|
149
151
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
150
152
|
}
|
|
153
|
+
async function inspectGatewayPortHealth(port, token) {
|
|
154
|
+
let portUsage;
|
|
155
|
+
try {
|
|
156
|
+
portUsage = await inspectPortUsage(port);
|
|
157
|
+
} catch (err) {
|
|
158
|
+
portUsage = {
|
|
159
|
+
port,
|
|
160
|
+
status: "unknown",
|
|
161
|
+
listeners: [],
|
|
162
|
+
hints: [],
|
|
163
|
+
errors: [String(err)]
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
let healthy = false;
|
|
167
|
+
if (portUsage.status === "busy") healthy = (await probeHealth(port, token)).ok;
|
|
168
|
+
return {
|
|
169
|
+
portUsage,
|
|
170
|
+
healthy
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
async function waitForGatewayHealthyListener(params) {
|
|
174
|
+
const attempts = params.attempts ?? DEFAULT_RESTART_HEALTH_ATTEMPTS;
|
|
175
|
+
const delayMs = params.delayMs ?? 500;
|
|
176
|
+
let snapshot = await inspectGatewayPortHealth(params.port, params.token);
|
|
177
|
+
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
178
|
+
if (snapshot.healthy) return snapshot;
|
|
179
|
+
await sleep(delayMs);
|
|
180
|
+
snapshot = await inspectGatewayPortHealth(params.port, params.token);
|
|
181
|
+
}
|
|
182
|
+
return snapshot;
|
|
183
|
+
}
|
|
184
|
+
function renderGatewayPortHealthDiagnostics(snapshot) {
|
|
185
|
+
const lines = [];
|
|
186
|
+
if (!snapshot.portUsage) {
|
|
187
|
+
lines.push("Gateway port health unavailable.");
|
|
188
|
+
return lines;
|
|
189
|
+
}
|
|
190
|
+
if (snapshot.portUsage.status === "busy") lines.push(...formatPortDiagnostics(snapshot.portUsage));
|
|
191
|
+
else lines.push(`Gateway port ${snapshot.portUsage.port} status: ${snapshot.portUsage.status}.`);
|
|
192
|
+
if (snapshot.portUsage.errors?.length) lines.push(`Port diagnostics errors: ${snapshot.portUsage.errors.join("; ")}`);
|
|
193
|
+
return lines;
|
|
194
|
+
}
|
|
151
195
|
//#endregion
|
|
152
|
-
export { DEFAULT_RESTART_HEALTH_DELAY_MS, DEFAULT_RESTART_HEALTH_TIMEOUT_MS, waitForRestartHealth };
|
|
196
|
+
export { DEFAULT_RESTART_HEALTH_ATTEMPTS, DEFAULT_RESTART_HEALTH_DELAY_MS, DEFAULT_RESTART_HEALTH_TIMEOUT_MS, renderGatewayPortHealthDiagnostics, waitForGatewayHealthyListener, waitForRestartHealth };
|
|
153
197
|
|
|
154
198
|
//# sourceMappingURL=restart-health.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"restart-health.js","names":[],"sources":["../../../../../src/cli/commands/gateway/restart-health.ts"],"sourcesContent":["/**\n * Restart Health - Wait loop after restart to verify gateway is healthy\n *\n * Polls service runtime + port usage + HTTP health probe to confirm:\n * 1. Service is running with a new PID\n * 2. Port is being listened on by the new process\n * 3. HTTP /api/health responds successfully\n * 4. Version matches expected (optional)\n */\n\nimport { createLogger } from '../../../utils/logger.js';\nimport type { GatewayServiceRuntime } from '../../../daemon/types.js';\nimport type { PortUsage } from '../../../infra/ports.js';\n\nconst log = createLogger('RestartHealth');\n\nexport const DEFAULT_RESTART_HEALTH_TIMEOUT_MS = 60_000;\nexport const DEFAULT_RESTART_HEALTH_DELAY_MS = 500;\n\nexport type GatewayRestartWaitOutcome =\n | 'healthy'\n | 'version-mismatch'\n | 'stale-pids'\n | 'stopped-free'\n | 'timeout';\n\nexport interface GatewayRestartSnapshot {\n runtime?: GatewayServiceRuntime;\n portUsage?: PortUsage;\n healthy: boolean;\n staleGatewayPids: number[];\n gatewayVersion?: string | null;\n expectedVersion?: string;\n versionMismatch?: { expected: string; actual: string | null };\n waitOutcome?: GatewayRestartWaitOutcome;\n elapsedMs?: number;\n}\n\ninterface RestartHealthService {\n readRuntime: (env?: Record<string, string | undefined>) => Promise<GatewayServiceRuntime>;\n}\n\n/**\n * Wait for gateway restart to complete and verify health.\n *\n * Loop:\n * 1. Check service runtime → get PID\n * 2. inspectPortUsage → confirm port is busy with new process\n * 3. HTTP probe /api/health → confirm reachable\n * 4. Version match (if expectedVersion provided)\n */\nexport async function waitForRestartHealth(params: {\n service: RestartHealthService;\n port: number;\n expectedVersion?: string;\n timeoutMs?: number;\n delayMs?: number;\n token?: string;\n onProgress?: (snapshot: GatewayRestartSnapshot) => void;\n}): Promise<GatewayRestartSnapshot> {\n const {\n service,\n port,\n expectedVersion,\n timeoutMs = DEFAULT_RESTART_HEALTH_TIMEOUT_MS,\n delayMs = DEFAULT_RESTART_HEALTH_DELAY_MS,\n token,\n onProgress,\n } = params;\n\n const { inspectPortUsage, classifyPortListener } = await import('../../../infra/ports.js');\n\n const startedAt = Date.now();\n\n while (Date.now() - startedAt < timeoutMs) {\n const elapsed = Date.now() - startedAt;\n\n // 1. Check service runtime\n const runtime = await service.readRuntime();\n\n if (runtime.status !== 'running' || !runtime.pid) {\n const snapshot: GatewayRestartSnapshot = {\n runtime,\n healthy: false,\n staleGatewayPids: [],\n elapsedMs: elapsed,\n };\n onProgress?.(snapshot);\n await sleep(delayMs);\n continue;\n }\n\n // 2. Check port usage\n const portUsage = await inspectPortUsage(port);\n\n if (portUsage.status !== 'busy') {\n const snapshot: GatewayRestartSnapshot = {\n runtime,\n portUsage,\n healthy: false,\n staleGatewayPids: [],\n elapsedMs: elapsed,\n };\n onProgress?.(snapshot);\n await sleep(delayMs);\n continue;\n }\n\n // 3. Verify port listener matches runtime PID\n const gatewayListeners = portUsage.listeners.filter(\n (l) => classifyPortListener(l, runtime.pid) === 'gateway',\n );\n const staleListeners = portUsage.listeners.filter(\n (l) => l.pid && l.pid !== runtime.pid && classifyPortListener(l) === 'gateway',\n );\n const staleGatewayPids = staleListeners.map((l) => l.pid!).filter(Boolean);\n\n if (gatewayListeners.length === 0) {\n const snapshot: GatewayRestartSnapshot = {\n runtime,\n portUsage,\n healthy: false,\n staleGatewayPids,\n elapsedMs: elapsed,\n };\n onProgress?.(snapshot);\n await sleep(delayMs);\n continue;\n }\n\n // 4. HTTP health probe\n const healthResult = await probeHealth(port, token);\n\n if (!healthResult.ok) {\n const snapshot: GatewayRestartSnapshot = {\n runtime,\n portUsage,\n healthy: false,\n staleGatewayPids,\n elapsedMs: elapsed,\n };\n onProgress?.(snapshot);\n await sleep(delayMs);\n continue;\n }\n\n // 5. Version check (optional)\n const gatewayVersion = healthResult.version ?? null;\n\n if (expectedVersion && gatewayVersion && gatewayVersion !== expectedVersion) {\n const snapshot: GatewayRestartSnapshot = {\n runtime,\n portUsage,\n healthy: false,\n staleGatewayPids,\n gatewayVersion,\n expectedVersion,\n versionMismatch: { expected: expectedVersion, actual: gatewayVersion },\n waitOutcome: 'version-mismatch',\n elapsedMs: elapsed,\n };\n onProgress?.(snapshot);\n return snapshot;\n }\n\n // Success!\n const snapshot: GatewayRestartSnapshot = {\n runtime,\n portUsage,\n healthy: true,\n staleGatewayPids,\n gatewayVersion,\n expectedVersion,\n waitOutcome: 'healthy',\n elapsedMs: elapsed,\n };\n onProgress?.(snapshot);\n\n log.info({ pid: runtime.pid, elapsedMs: elapsed, port }, 'Restart health confirmed');\n return snapshot;\n }\n\n // Timeout\n const finalRuntime = await service.readRuntime();\n const finalSnapshot: GatewayRestartSnapshot = {\n runtime: finalRuntime,\n healthy: false,\n staleGatewayPids: [],\n waitOutcome: 'timeout',\n elapsedMs: Date.now() - startedAt,\n };\n\n log.warn({ timeoutMs, port }, 'Restart health check timed out');\n return finalSnapshot;\n}\n\n// ─── HTTP Health Probe ───\n\ninterface HealthProbeResult {\n ok: boolean;\n version?: string;\n error?: string;\n}\n\nasync function probeHealth(port: number, token?: string): Promise<HealthProbeResult> {\n try {\n const headers: Record<string, string> = {};\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 3000);\n\n const response = await fetch(`http://127.0.0.1:${port}/api/health`, {\n method: 'GET',\n headers,\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (!response.ok) {\n return { ok: false, error: `HTTP ${response.status}` };\n }\n\n const body = await response.json() as { version?: string };\n return { ok: true, version: body.version };\n } catch (err) {\n return { ok: false, error: err instanceof Error ? err.message : String(err) };\n }\n}\n\n// ─── Utility ───\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"restart-health.js","names":[],"sources":["../../../../../src/cli/commands/gateway/restart-health.ts"],"sourcesContent":["/**\n * Restart Health - Wait loop after restart to verify gateway is healthy\n *\n * Polls service runtime + port usage + HTTP health probe to confirm:\n * 1. Service is running with a new PID\n * 2. Port is being listened on by the new process\n * 3. HTTP /api/health responds successfully\n * 4. Version matches expected (optional)\n */\n\nimport { createLogger } from '../../../utils/logger.js';\nimport type { GatewayServiceRuntime } from '../../../daemon/types.js';\nimport type { PortUsage } from '../../../infra/ports.js';\nimport { formatPortDiagnostics, inspectPortUsage } from '../../../infra/ports.js';\n\nconst log = createLogger('RestartHealth');\n\nexport const DEFAULT_RESTART_HEALTH_TIMEOUT_MS = 60_000;\nexport const DEFAULT_RESTART_HEALTH_DELAY_MS = 500;\nexport const DEFAULT_RESTART_HEALTH_ATTEMPTS = Math.ceil(\n DEFAULT_RESTART_HEALTH_TIMEOUT_MS / DEFAULT_RESTART_HEALTH_DELAY_MS,\n);\n\nexport type GatewayRestartWaitOutcome =\n | 'healthy'\n | 'version-mismatch'\n | 'stale-pids'\n | 'stopped-free'\n | 'timeout';\n\nexport interface GatewayRestartSnapshot {\n runtime?: GatewayServiceRuntime;\n portUsage?: PortUsage;\n healthy: boolean;\n staleGatewayPids: number[];\n gatewayVersion?: string | null;\n expectedVersion?: string;\n versionMismatch?: { expected: string; actual: string | null };\n waitOutcome?: GatewayRestartWaitOutcome;\n elapsedMs?: number;\n}\n\ninterface RestartHealthService {\n readRuntime: (env?: Record<string, string | undefined>) => Promise<GatewayServiceRuntime>;\n}\n\n/**\n * Wait for gateway restart to complete and verify health.\n *\n * Loop:\n * 1. Check service runtime → get PID\n * 2. inspectPortUsage → confirm port is busy with new process\n * 3. HTTP probe /api/health → confirm reachable\n * 4. Version match (if expectedVersion provided)\n */\nexport async function waitForRestartHealth(params: {\n service: RestartHealthService;\n port: number;\n expectedVersion?: string;\n timeoutMs?: number;\n delayMs?: number;\n token?: string;\n onProgress?: (snapshot: GatewayRestartSnapshot) => void;\n}): Promise<GatewayRestartSnapshot> {\n const {\n service,\n port,\n expectedVersion,\n timeoutMs = DEFAULT_RESTART_HEALTH_TIMEOUT_MS,\n delayMs = DEFAULT_RESTART_HEALTH_DELAY_MS,\n token,\n onProgress,\n } = params;\n\n const { inspectPortUsage, classifyPortListener } = await import('../../../infra/ports.js');\n\n const startedAt = Date.now();\n\n while (Date.now() - startedAt < timeoutMs) {\n const elapsed = Date.now() - startedAt;\n\n // 1. Check service runtime\n const runtime = await service.readRuntime();\n\n if (runtime.status !== 'running' || !runtime.pid) {\n const snapshot: GatewayRestartSnapshot = {\n runtime,\n healthy: false,\n staleGatewayPids: [],\n elapsedMs: elapsed,\n };\n onProgress?.(snapshot);\n await sleep(delayMs);\n continue;\n }\n\n // 2. Check port usage\n const portUsage = await inspectPortUsage(port);\n\n if (portUsage.status !== 'busy') {\n const snapshot: GatewayRestartSnapshot = {\n runtime,\n portUsage,\n healthy: false,\n staleGatewayPids: [],\n elapsedMs: elapsed,\n };\n onProgress?.(snapshot);\n await sleep(delayMs);\n continue;\n }\n\n // 3. Verify port listener matches runtime PID\n const gatewayListeners = portUsage.listeners.filter(\n (l) => classifyPortListener(l, runtime.pid) === 'gateway',\n );\n const staleListeners = portUsage.listeners.filter(\n (l) => l.pid && l.pid !== runtime.pid && classifyPortListener(l) === 'gateway',\n );\n const staleGatewayPids = staleListeners.map((l) => l.pid!).filter(Boolean);\n\n if (gatewayListeners.length === 0) {\n const snapshot: GatewayRestartSnapshot = {\n runtime,\n portUsage,\n healthy: false,\n staleGatewayPids,\n elapsedMs: elapsed,\n };\n onProgress?.(snapshot);\n await sleep(delayMs);\n continue;\n }\n\n // 4. HTTP health probe\n const healthResult = await probeHealth(port, token);\n\n if (!healthResult.ok) {\n const snapshot: GatewayRestartSnapshot = {\n runtime,\n portUsage,\n healthy: false,\n staleGatewayPids,\n elapsedMs: elapsed,\n };\n onProgress?.(snapshot);\n await sleep(delayMs);\n continue;\n }\n\n // 5. Version check (optional)\n const gatewayVersion = healthResult.version ?? null;\n\n if (expectedVersion && gatewayVersion && gatewayVersion !== expectedVersion) {\n const snapshot: GatewayRestartSnapshot = {\n runtime,\n portUsage,\n healthy: false,\n staleGatewayPids,\n gatewayVersion,\n expectedVersion,\n versionMismatch: { expected: expectedVersion, actual: gatewayVersion },\n waitOutcome: 'version-mismatch',\n elapsedMs: elapsed,\n };\n onProgress?.(snapshot);\n return snapshot;\n }\n\n // Success!\n const snapshot: GatewayRestartSnapshot = {\n runtime,\n portUsage,\n healthy: true,\n staleGatewayPids,\n gatewayVersion,\n expectedVersion,\n waitOutcome: 'healthy',\n elapsedMs: elapsed,\n };\n onProgress?.(snapshot);\n\n log.info({ pid: runtime.pid, elapsedMs: elapsed, port }, 'Restart health confirmed');\n return snapshot;\n }\n\n // Timeout\n const finalRuntime = await service.readRuntime();\n const finalSnapshot: GatewayRestartSnapshot = {\n runtime: finalRuntime,\n healthy: false,\n staleGatewayPids: [],\n waitOutcome: 'timeout',\n elapsedMs: Date.now() - startedAt,\n };\n\n log.warn({ timeoutMs, port }, 'Restart health check timed out');\n return finalSnapshot;\n}\n\n// ─── HTTP Health Probe ───\n\ninterface HealthProbeResult {\n ok: boolean;\n version?: string;\n error?: string;\n}\n\nasync function probeHealth(port: number, token?: string): Promise<HealthProbeResult> {\n try {\n const headers: Record<string, string> = {};\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 3000);\n\n const response = await fetch(`http://127.0.0.1:${port}/api/health`, {\n method: 'GET',\n headers,\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (!response.ok) {\n return { ok: false, error: `HTTP ${response.status}` };\n }\n\n const body = await response.json() as { version?: string };\n return { ok: true, version: body.version };\n } catch (err) {\n return { ok: false, error: err instanceof Error ? err.message : String(err) };\n }\n}\n\n// ─── Utility ───\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport type GatewayPortHealthSnapshot = {\n portUsage?: PortUsage;\n healthy: boolean;\n};\n\nasync function inspectGatewayPortHealth(port: number, token?: string): Promise<GatewayPortHealthSnapshot> {\n let portUsage: PortUsage;\n try {\n portUsage = await inspectPortUsage(port);\n } catch (err) {\n portUsage = {\n port,\n status: 'unknown',\n listeners: [],\n hints: [],\n errors: [String(err)],\n };\n }\n\n let healthy = false;\n if (portUsage.status === 'busy') {\n const healthResult = await probeHealth(port, token);\n healthy = healthResult.ok;\n }\n\n return { portUsage, healthy };\n}\n\nexport async function waitForGatewayHealthyListener(params: {\n port: number;\n attempts?: number;\n delayMs?: number;\n token?: string;\n}): Promise<GatewayPortHealthSnapshot> {\n const attempts = params.attempts ?? DEFAULT_RESTART_HEALTH_ATTEMPTS;\n const delayMs = params.delayMs ?? DEFAULT_RESTART_HEALTH_DELAY_MS;\n\n let snapshot = await inspectGatewayPortHealth(params.port, params.token);\n for (let attempt = 0; attempt < attempts; attempt += 1) {\n if (snapshot.healthy) {\n return snapshot;\n }\n await sleep(delayMs);\n snapshot = await inspectGatewayPortHealth(params.port, params.token);\n }\n return snapshot;\n}\n\nexport function renderGatewayPortHealthDiagnostics(snapshot: GatewayPortHealthSnapshot): string[] {\n const lines: string[] = [];\n if (!snapshot.portUsage) {\n lines.push('Gateway port health unavailable.');\n return lines;\n }\n if (snapshot.portUsage.status === 'busy') {\n lines.push(...formatPortDiagnostics(snapshot.portUsage));\n } else {\n lines.push(`Gateway port ${snapshot.portUsage.port} status: ${snapshot.portUsage.status}.`);\n }\n if (snapshot.portUsage.errors?.length) {\n lines.push(`Port diagnostics errors: ${snapshot.portUsage.errors.join('; ')}`);\n }\n return lines;\n}\n"],"mappings":"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"}
|
|
@@ -4,9 +4,9 @@ import { Command } from "commander";
|
|
|
4
4
|
* Create restart subcommand - delegates to daemon lifecycle core
|
|
5
5
|
*/
|
|
6
6
|
function createRestartCommand() {
|
|
7
|
-
return new Command("restart").description("Restart the gateway service").option("--
|
|
8
|
-
const {
|
|
9
|
-
await
|
|
7
|
+
return new Command("restart").description("Restart the gateway service").option("--wait <timeout>", "Wait for health after restart (e.g. \"30s\", \"1m\")").option("--json", "Output JSON").action(async (options) => {
|
|
8
|
+
const { runDaemonRestart } = await import("./lifecycle.js");
|
|
9
|
+
await runDaemonRestart(options);
|
|
10
10
|
});
|
|
11
11
|
}
|
|
12
12
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"restart.js","names":[],"sources":["../../../../../src/cli/commands/gateway/restart.ts"],"sourcesContent":["import { Command } from 'commander';\n\n/**\n * Create restart subcommand - delegates to daemon lifecycle core\n */\nexport function createRestartCommand(): Command {\n return new Command('restart')\n .description('Restart the gateway service')\n .option('--
|
|
1
|
+
{"version":3,"file":"restart.js","names":[],"sources":["../../../../../src/cli/commands/gateway/restart.ts"],"sourcesContent":["import { Command } from 'commander';\n\n/**\n * Create restart subcommand - delegates to daemon lifecycle core\n */\nexport function createRestartCommand(): Command {\n return new Command('restart')\n .description('Restart the gateway service')\n .option('--wait <timeout>', 'Wait for health after restart (e.g. \"30s\", \"1m\")')\n .option('--json', 'Output JSON')\n .action(async (options) => {\n const { runDaemonRestart } = await import('./lifecycle.js');\n await runDaemonRestart(options);\n });\n}\n"],"mappings":";;;;;AAKA,SAAgB,uBAAgC;AAC9C,QAAO,IAAI,QAAQ,UAAU,CAC1B,YAAY,8BAA8B,CAC1C,OAAO,oBAAoB,uDAAmD,CAC9E,OAAO,UAAU,cAAc,CAC/B,OAAO,OAAO,YAAY;EACzB,MAAM,EAAE,qBAAqB,MAAM,OAAO;AAC1C,QAAM,iBAAiB,QAAQ;GAC/B"}
|
|
@@ -7,7 +7,6 @@ export type GatewayRunCliOptions = {
|
|
|
7
7
|
tailscaleResetOnExit?: boolean;
|
|
8
8
|
force?: boolean;
|
|
9
9
|
hotReload?: boolean;
|
|
10
|
-
background?: boolean;
|
|
11
10
|
foreground?: boolean;
|
|
12
11
|
};
|
|
13
12
|
export declare function runGatewayFromCliOptions(options: GatewayRunCliOptions, ctx: CLIContext): Promise<void>;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
1
|
//#region src/cli/commands/gateway/run-foreground.ts
|
|
3
2
|
async function ensureGatewayReady(configPath, workspacePath, port) {
|
|
4
3
|
const [{ initWorkspace }, { seedMainAgentProfileMarkdown }] = await Promise.all([import("../../utils/init-workspace.js"), import("../../../agent/context/workspace-seed.js")]);
|
|
@@ -103,40 +102,6 @@ async function runGatewayFromCliOptions(options, ctx) {
|
|
|
103
102
|
console.error(`Port ${port} is already in use. Use --force to kill existing process.`);
|
|
104
103
|
process.exit(1);
|
|
105
104
|
}
|
|
106
|
-
if (options.background === true) {
|
|
107
|
-
console.log("🚀 Starting xopc gateway in background...");
|
|
108
|
-
console.log(` Bind: ${listenPlan.bindMode} (${bindHost})`);
|
|
109
|
-
console.log(` Port: ${port}`);
|
|
110
|
-
console.log("");
|
|
111
|
-
const args = [
|
|
112
|
-
...process.execArgv,
|
|
113
|
-
...process.argv.slice(1).filter((arg) => arg !== "--background"),
|
|
114
|
-
"--foreground"
|
|
115
|
-
];
|
|
116
|
-
const child = spawn(process.execPath, args, {
|
|
117
|
-
detached: true,
|
|
118
|
-
stdio: "ignore",
|
|
119
|
-
env: process.env
|
|
120
|
-
});
|
|
121
|
-
child.unref();
|
|
122
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
123
|
-
if (child.pid && !child.killed) {
|
|
124
|
-
const displayHost = bindHost === "0.0.0.0" ? "localhost" : bindHost;
|
|
125
|
-
console.log("✅ Gateway started in background");
|
|
126
|
-
console.log(` PID: ${child.pid}`);
|
|
127
|
-
console.log(` URL: http://${displayHost}:${port}`);
|
|
128
|
-
const token = options.token || config?.gateway?.auth?.token;
|
|
129
|
-
if (token) console.log(` Token: ${token.slice(0, 8)}...${token.slice(-8)}`);
|
|
130
|
-
console.log("");
|
|
131
|
-
console.log("📝 Management commands:");
|
|
132
|
-
console.log(` xopc gateway status # Check status`);
|
|
133
|
-
console.log(` xopc gateway stop # Stop gateway`);
|
|
134
|
-
console.log(` xopc gateway restart # Restart gateway`);
|
|
135
|
-
process.exit(0);
|
|
136
|
-
}
|
|
137
|
-
console.error("❌ Failed to start gateway in background");
|
|
138
|
-
process.exit(1);
|
|
139
|
-
}
|
|
140
105
|
console.log("🚀 Starting xopc gateway...");
|
|
141
106
|
console.log(` Bind: ${listenPlan.bindMode} (${bindHost})`);
|
|
142
107
|
console.log(` Port: ${port}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-foreground.js","names":[],"sources":["../../../../../src/cli/commands/gateway/run-foreground.ts"],"sourcesContent":["import { spawn } from 'node:child_process';\n\nimport type { CLIContext } from '../../registry.js';\n\nexport type GatewayRunCliOptions = {\n bind?: string;\n port?: string | number;\n token?: string;\n tailscale?: string;\n tailscaleResetOnExit?: boolean;\n force?: boolean;\n hotReload?: boolean;\n background?: boolean;\n foreground?: boolean;\n};\n\nasync function ensureGatewayReady(\n configPath: string,\n workspacePath: string,\n port: number,\n): Promise<void> {\n const [{ initWorkspace }, { seedMainAgentProfileMarkdown }] = await Promise.all([\n import('../../utils/init-workspace.js'),\n import('../../../agent/context/workspace-seed.js'),\n ]);\n const result = await initWorkspace({\n configPath,\n workspacePath,\n gatewayPort: port,\n });\n\n if (result.configCreated || result.workspaceCreated) {\n console.log('');\n console.log('👋 Welcome to xopc! Running first-time setup before starting the gateway...');\n console.log('');\n console.log('✅ First-time setup complete!');\n console.log(` Config: ${configPath}`);\n console.log(` Workspace: ${workspacePath}`);\n console.log(` Token: ${result.token.slice(0, 8)}...${result.token.slice(-8)}`);\n console.log('');\n console.log('💡 Tip: run `xopc onboard` anytime to configure models, channels, and more.');\n console.log('');\n seedMainAgentProfileMarkdown(result.config);\n }\n}\n\nexport async function runGatewayFromCliOptions(\n options: GatewayRunCliOptions,\n ctx: CLIContext,\n): Promise<void> {\n const tailscaleModes = new Set(['off', 'serve', 'funnel']);\n const tailscaleRaw =\n typeof options.tailscale === 'string' ? options.tailscale.trim().toLowerCase() : undefined;\n const tailscaleOverride =\n tailscaleRaw && tailscaleModes.has(tailscaleRaw)\n ? (tailscaleRaw as 'off' | 'serve' | 'funnel')\n : undefined;\n if (tailscaleRaw && !tailscaleOverride) {\n console.error(`Invalid --tailscale mode \"${tailscaleRaw}\". Use: off, serve, funnel.`);\n process.exit(1);\n }\n\n if (tailscaleOverride && tailscaleOverride !== 'off') {\n process.env.XOPC_GATEWAY_TAILSCALE_MODE = tailscaleOverride;\n }\n if (options.tailscaleResetOnExit === true) {\n process.env.XOPC_GATEWAY_TAILSCALE_RESET_ON_EXIT = '1';\n }\n\n const [{ loadConfig }, { resolveConfigPath }, { runGatewayLoop }, gatewayPorts] = await Promise.all([\n import('../../../config/index.js'),\n import('../../../config/paths.js'),\n import('../../../gateway/run-loop.js'),\n import('../../../gateway/ports.js'),\n ]);\n const { checkPortAvailable, forceFreePortAndWait } = gatewayPorts;\n const config = loadConfig(ctx.configPath);\n\n const bindFromFlagRaw =\n typeof options.bind === 'string' && options.bind.trim().length > 0\n ? options.bind.trim().toLowerCase()\n : undefined;\n const bindModes = new Set(['auto', 'loopback', 'lan', 'tailnet', 'custom']);\n const bindFromFlag = bindFromFlagRaw && bindModes.has(bindFromFlagRaw)\n ? (bindFromFlagRaw as import('../../../config/schema.js').GatewayBindMode)\n : undefined;\n if (bindFromFlagRaw && !bindFromFlag) {\n console.error(`Invalid --bind mode \"${bindFromFlagRaw}\". Use: loopback, lan, auto, custom, tailnet.`);\n process.exit(1);\n }\n\n const portRaw = options.port;\n const portFromFlag =\n portRaw !== undefined && portRaw !== null && String(portRaw).trim().length > 0\n ? parseInt(String(portRaw), 10)\n : undefined;\n\n const { resolveGatewayListenPlan } = await import('../../../gateway/listen.js');\n const listenPlan = resolveGatewayListenPlan({\n cfg: config,\n bindOverride: bindFromFlag,\n });\n const bindHost = listenPlan.bindHost;\n const port =\n portFromFlag !== undefined && Number.isFinite(portFromFlag)\n ? portFromFlag\n : (typeof config.gateway.port === 'number' ? config.gateway.port : 18790);\n\n await ensureGatewayReady(ctx.configPath, ctx.workspacePath, port);\n\n const effectiveConfig = loadConfig(ctx.configPath);\n const { resolveGatewayAuth, assertGatewayAuthConfigured } = await import('../../../gateway/auth.js');\n const { assertGatewayRuntimeConfig } = await import('../../../gateway/runtime-config.js');\n\n let auth = resolveGatewayAuth({ authConfig: effectiveConfig.gateway?.auth });\n if (typeof options.token === 'string' && options.token.trim().length > 0) {\n auth = { mode: 'token', token: options.token.trim() };\n }\n try {\n assertGatewayAuthConfigured(auth);\n assertGatewayRuntimeConfig({\n cfg: effectiveConfig,\n auth,\n bindOverride: bindFromFlag,\n port,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(`Gateway refused to start: ${message}`);\n process.exit(1);\n }\n\n if (options.force) {\n try {\n const result = await forceFreePortAndWait(port, {\n timeoutMs: 2000,\n sigtermTimeoutMs: 700,\n });\n if (result.killed.length > 0) {\n console.log(`Force killed ${result.killed.length} process(es) on port ${port}`);\n if (result.escalatedToSigkill) {\n console.log('Escalated to SIGKILL');\n }\n }\n } catch (err) {\n console.error(`Failed to free port ${port}: ${String(err)}`);\n process.exit(1);\n }\n }\n\n const portAvailable = await checkPortAvailable(port, bindHost);\n if (!portAvailable) {\n console.error(`Port ${port} is already in use. Use --force to kill existing process.`);\n process.exit(1);\n }\n\n if (options.background === true) {\n console.log('🚀 Starting xopc gateway in background...');\n console.log(` Bind: ${listenPlan.bindMode} (${bindHost})`);\n console.log(` Port: ${port}`);\n console.log('');\n\n const args = [\n ...process.execArgv,\n ...process.argv.slice(1).filter((arg) => arg !== '--background'),\n '--foreground',\n ];\n\n const child = spawn(process.execPath, args, {\n detached: true,\n stdio: 'ignore',\n env: process.env,\n });\n\n child.unref();\n\n await new Promise((resolve) => setTimeout(resolve, 500));\n\n if (child.pid && !child.killed) {\n const displayHost = bindHost === '0.0.0.0' ? 'localhost' : bindHost;\n console.log('✅ Gateway started in background');\n console.log(` PID: ${child.pid}`);\n console.log(` URL: http://${displayHost}:${port}`);\n const token = options.token || config?.gateway?.auth?.token;\n if (token) {\n console.log(` Token: ${token.slice(0, 8)}...${token.slice(-8)}`);\n }\n console.log('');\n console.log('📝 Management commands:');\n console.log(` xopc gateway status # Check status`);\n console.log(` xopc gateway stop # Stop gateway`);\n console.log(` xopc gateway restart # Restart gateway`);\n process.exit(0);\n }\n\n console.error('❌ Failed to start gateway in background');\n process.exit(1);\n }\n\n console.log('🚀 Starting xopc gateway...');\n console.log(` Bind: ${listenPlan.bindMode} (${bindHost})`);\n console.log(` Port: ${port}`);\n console.log('');\n console.log('Press Ctrl+C to stop');\n console.log('');\n\n await runGatewayLoop({\n configPath: ctx.configPath || resolveConfigPath(),\n port,\n start: async () => {\n const { GatewayServer } = await import('../../../gateway/index.js');\n const server = new GatewayServer({\n bindHost: listenPlan.bindHost,\n bind: listenPlan.bindMode,\n customBindHost: listenPlan.customBindHost,\n port,\n token: options.token || config?.gateway?.auth?.token,\n verbose: ctx.isVerbose,\n configPath: ctx.configPath,\n enableHotReload: options.hotReload,\n });\n await server.start();\n\n const displayHost = bindHost === '0.0.0.0' ? 'localhost' : bindHost;\n const token = options.token || config?.gateway?.auth?.token;\n console.log('✅ Gateway started');\n console.log(` URL: http://${displayHost}:${port}`);\n if (token) {\n console.log(` Token: ${token.slice(0, 8)}...${token.slice(-8)}`);\n }\n console.log('');\n\n return server;\n },\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"run-foreground.js","names":[],"sources":["../../../../../src/cli/commands/gateway/run-foreground.ts"],"sourcesContent":["import type { CLIContext } from '../../registry.js';\n\nexport type GatewayRunCliOptions = {\n bind?: string;\n port?: string | number;\n token?: string;\n tailscale?: string;\n tailscaleResetOnExit?: boolean;\n force?: boolean;\n hotReload?: boolean;\n foreground?: boolean;\n};\n\nasync function ensureGatewayReady(\n configPath: string,\n workspacePath: string,\n port: number,\n): Promise<void> {\n const [{ initWorkspace }, { seedMainAgentProfileMarkdown }] = await Promise.all([\n import('../../utils/init-workspace.js'),\n import('../../../agent/context/workspace-seed.js'),\n ]);\n const result = await initWorkspace({\n configPath,\n workspacePath,\n gatewayPort: port,\n });\n\n if (result.configCreated || result.workspaceCreated) {\n console.log('');\n console.log('👋 Welcome to xopc! Running first-time setup before starting the gateway...');\n console.log('');\n console.log('✅ First-time setup complete!');\n console.log(` Config: ${configPath}`);\n console.log(` Workspace: ${workspacePath}`);\n console.log(` Token: ${result.token.slice(0, 8)}...${result.token.slice(-8)}`);\n console.log('');\n console.log('💡 Tip: run `xopc onboard` anytime to configure models, channels, and more.');\n console.log('');\n seedMainAgentProfileMarkdown(result.config);\n }\n}\n\nexport async function runGatewayFromCliOptions(\n options: GatewayRunCliOptions,\n ctx: CLIContext,\n): Promise<void> {\n const tailscaleModes = new Set(['off', 'serve', 'funnel']);\n const tailscaleRaw =\n typeof options.tailscale === 'string' ? options.tailscale.trim().toLowerCase() : undefined;\n const tailscaleOverride =\n tailscaleRaw && tailscaleModes.has(tailscaleRaw)\n ? (tailscaleRaw as 'off' | 'serve' | 'funnel')\n : undefined;\n if (tailscaleRaw && !tailscaleOverride) {\n console.error(`Invalid --tailscale mode \"${tailscaleRaw}\". Use: off, serve, funnel.`);\n process.exit(1);\n }\n\n if (tailscaleOverride && tailscaleOverride !== 'off') {\n process.env.XOPC_GATEWAY_TAILSCALE_MODE = tailscaleOverride;\n }\n if (options.tailscaleResetOnExit === true) {\n process.env.XOPC_GATEWAY_TAILSCALE_RESET_ON_EXIT = '1';\n }\n\n const [{ loadConfig }, { resolveConfigPath }, { runGatewayLoop }, gatewayPorts] = await Promise.all([\n import('../../../config/index.js'),\n import('../../../config/paths.js'),\n import('../../../gateway/run-loop.js'),\n import('../../../gateway/ports.js'),\n ]);\n const { checkPortAvailable, forceFreePortAndWait } = gatewayPorts;\n const config = loadConfig(ctx.configPath);\n\n const bindFromFlagRaw =\n typeof options.bind === 'string' && options.bind.trim().length > 0\n ? options.bind.trim().toLowerCase()\n : undefined;\n const bindModes = new Set(['auto', 'loopback', 'lan', 'tailnet', 'custom']);\n const bindFromFlag = bindFromFlagRaw && bindModes.has(bindFromFlagRaw)\n ? (bindFromFlagRaw as import('../../../config/schema.js').GatewayBindMode)\n : undefined;\n if (bindFromFlagRaw && !bindFromFlag) {\n console.error(`Invalid --bind mode \"${bindFromFlagRaw}\". Use: loopback, lan, auto, custom, tailnet.`);\n process.exit(1);\n }\n\n const portRaw = options.port;\n const portFromFlag =\n portRaw !== undefined && portRaw !== null && String(portRaw).trim().length > 0\n ? parseInt(String(portRaw), 10)\n : undefined;\n\n const { resolveGatewayListenPlan } = await import('../../../gateway/listen.js');\n const listenPlan = resolveGatewayListenPlan({\n cfg: config,\n bindOverride: bindFromFlag,\n });\n const bindHost = listenPlan.bindHost;\n const port =\n portFromFlag !== undefined && Number.isFinite(portFromFlag)\n ? portFromFlag\n : (typeof config.gateway.port === 'number' ? config.gateway.port : 18790);\n\n await ensureGatewayReady(ctx.configPath, ctx.workspacePath, port);\n\n const effectiveConfig = loadConfig(ctx.configPath);\n const { resolveGatewayAuth, assertGatewayAuthConfigured } = await import('../../../gateway/auth.js');\n const { assertGatewayRuntimeConfig } = await import('../../../gateway/runtime-config.js');\n\n let auth = resolveGatewayAuth({ authConfig: effectiveConfig.gateway?.auth });\n if (typeof options.token === 'string' && options.token.trim().length > 0) {\n auth = { mode: 'token', token: options.token.trim() };\n }\n try {\n assertGatewayAuthConfigured(auth);\n assertGatewayRuntimeConfig({\n cfg: effectiveConfig,\n auth,\n bindOverride: bindFromFlag,\n port,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(`Gateway refused to start: ${message}`);\n process.exit(1);\n }\n\n if (options.force) {\n try {\n const result = await forceFreePortAndWait(port, {\n timeoutMs: 2000,\n sigtermTimeoutMs: 700,\n });\n if (result.killed.length > 0) {\n console.log(`Force killed ${result.killed.length} process(es) on port ${port}`);\n if (result.escalatedToSigkill) {\n console.log('Escalated to SIGKILL');\n }\n }\n } catch (err) {\n console.error(`Failed to free port ${port}: ${String(err)}`);\n process.exit(1);\n }\n }\n\n const portAvailable = await checkPortAvailable(port, bindHost);\n if (!portAvailable) {\n console.error(`Port ${port} is already in use. Use --force to kill existing process.`);\n process.exit(1);\n }\n\n console.log('🚀 Starting xopc gateway...');\n console.log(` Bind: ${listenPlan.bindMode} (${bindHost})`);\n console.log(` Port: ${port}`);\n console.log('');\n console.log('Press Ctrl+C to stop');\n console.log('');\n\n await runGatewayLoop({\n configPath: ctx.configPath || resolveConfigPath(),\n port,\n start: async () => {\n const { GatewayServer } = await import('../../../gateway/index.js');\n const server = new GatewayServer({\n bindHost: listenPlan.bindHost,\n bind: listenPlan.bindMode,\n customBindHost: listenPlan.customBindHost,\n port,\n token: options.token || config?.gateway?.auth?.token,\n verbose: ctx.isVerbose,\n configPath: ctx.configPath,\n enableHotReload: options.hotReload,\n });\n await server.start();\n\n const displayHost = bindHost === '0.0.0.0' ? 'localhost' : bindHost;\n const token = options.token || config?.gateway?.auth?.token;\n console.log('✅ Gateway started');\n console.log(` URL: http://${displayHost}:${port}`);\n if (token) {\n console.log(` Token: ${token.slice(0, 8)}...${token.slice(-8)}`);\n }\n console.log('');\n\n return server;\n },\n });\n}\n"],"mappings":"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"}
|
|
@@ -15,3 +15,7 @@ export declare function createServiceStartCommand(): Command;
|
|
|
15
15
|
* Create service status subcommand
|
|
16
16
|
*/
|
|
17
17
|
export declare function createServiceStatusCommand(): Command;
|
|
18
|
+
/**
|
|
19
|
+
* Gateway OS service command group (`xopc gateway service …`).
|
|
20
|
+
*/
|
|
21
|
+
export declare function createServiceCommand(): Command;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { init_paths, resolveConfigPath } from "../../../config/paths.js";
|
|
2
|
-
import { getContextWithOpts } from "../../
|
|
2
|
+
import { getContextWithOpts } from "../../context.js";
|
|
3
|
+
import { createStopCommand } from "./stop.js";
|
|
4
|
+
import { createRestartCommand } from "./restart.js";
|
|
3
5
|
import { Command } from "commander";
|
|
4
6
|
//#region src/cli/commands/gateway/service.ts
|
|
5
7
|
init_paths();
|
|
@@ -122,7 +124,7 @@ function createServiceStartCommand() {
|
|
|
122
124
|
* Create service status subcommand
|
|
123
125
|
*/
|
|
124
126
|
function createServiceStatusCommand() {
|
|
125
|
-
return new Command("
|
|
127
|
+
return new Command("status").description("Show OS service status").option("--json", "Output JSON").action(async (options) => {
|
|
126
128
|
const [{ resolveGatewayService, isDaemonAvailableAsync, getPlatformName }] = await Promise.all([import("../../../daemon/service.js")]);
|
|
127
129
|
if (!await isDaemonAvailableAsync()) {
|
|
128
130
|
if (options.json) console.log(JSON.stringify({
|
|
@@ -165,7 +167,20 @@ function createServiceStatusCommand() {
|
|
|
165
167
|
}
|
|
166
168
|
});
|
|
167
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* Gateway OS service command group (`xopc gateway service …`).
|
|
172
|
+
*/
|
|
173
|
+
function createServiceCommand() {
|
|
174
|
+
const cmd = new Command("service").description("Manage gateway OS service (LaunchAgent / systemd / Task)");
|
|
175
|
+
cmd.addCommand(createInstallCommand());
|
|
176
|
+
cmd.addCommand(createUninstallCommand());
|
|
177
|
+
cmd.addCommand(createServiceStartCommand());
|
|
178
|
+
cmd.addCommand(createServiceStatusCommand());
|
|
179
|
+
cmd.addCommand(createStopCommand());
|
|
180
|
+
cmd.addCommand(createRestartCommand());
|
|
181
|
+
return cmd;
|
|
182
|
+
}
|
|
168
183
|
//#endregion
|
|
169
|
-
export { createInstallCommand, createServiceStartCommand, createServiceStatusCommand, createUninstallCommand };
|
|
184
|
+
export { createInstallCommand, createServiceCommand, createServiceStartCommand, createServiceStatusCommand, createUninstallCommand };
|
|
170
185
|
|
|
171
186
|
//# sourceMappingURL=service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","names":[],"sources":["../../../../../src/cli/commands/gateway/service.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { resolveConfigPath } from '../../../config/paths.js';\nimport { getContextWithOpts } from '../../index.js';\n\n/**\n * Create service install subcommand - actually installs the OS service\n */\nexport function createInstallCommand(): Command {\n return new Command('install')\n .description('Install gateway as OS service (LaunchAgent / systemd / Task)')\n .option('--port <port>', 'Gateway port')\n .option('--token <token>', 'Gateway auth token')\n .option('--force', 'Force reinstall if already installed')\n .option('--json', 'Output JSON')\n .action(async (options) => {\n const ctx = getContextWithOpts();\n const configPath = ctx.configPath || resolveConfigPath();\n\n const [{ loadConfig }, { resolveGatewayService, isDaemonAvailableAsync, getPlatformName }, { buildGatewayInstallArgs }] =\n await Promise.all([\n import('../../../config/index.js'),\n import('../../../daemon/service.js'),\n import('../../../daemon/install-plan.js'),\n ]);\n\n const config = loadConfig(configPath);\n const port = options.port ? parseInt(options.port, 10) : (config?.gateway?.port || 18790);\n const bind = config?.gateway?.bind ?? 'loopback';\n const token = options.token || config?.gateway?.auth?.token;\n\n const available = await isDaemonAvailableAsync();\n if (!available) {\n if (options.json) {\n console.log(JSON.stringify({ ok: false, error: 'Daemon not available' }));\n } else {\n console.error(`❌ OS service not available on ${getPlatformName()}`);\n }\n process.exit(1);\n }\n\n const service = await resolveGatewayService();\n\n // Check if already installed\n const loaded = await service.isLoaded({ env: process.env });\n if (loaded && !options.force) {\n if (options.json) {\n console.log(JSON.stringify({ ok: true, result: 'already-installed' }));\n } else {\n console.log('ℹ️ Service already installed. Use --force to reinstall.');\n }\n return;\n }\n\n // Uninstall first if force\n if (loaded && options.force) {\n try {\n await service.uninstall({ env: process.env });\n } catch {\n // Best-effort\n }\n }\n\n // Build install args and install\n const installArgs = buildGatewayInstallArgs({ port, bind, token });\n installArgs.stdout = process.stdout;\n\n try {\n await service.install(installArgs);\n\n if (options.json) {\n console.log(JSON.stringify({ ok: true, result: 'installed', label: service.label, port }));\n } else {\n console.log('');\n console.log(`✅ Gateway service installed`);\n console.log(` Service: ${service.label}`);\n console.log(` Port: ${port}`);\n console.log('');\n console.log('💡 The service will start automatically on login.');\n console.log(' Use `xopc gateway status` to verify.');\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (options.json) {\n console.log(JSON.stringify({ ok: false, error: message }));\n } else {\n console.error(`❌ Failed to install service: ${message}`);\n }\n process.exit(1);\n }\n });\n}\n\n/**\n * Create service uninstall subcommand\n */\nexport function createUninstallCommand(): Command {\n return new Command('uninstall')\n .description('Uninstall gateway OS service')\n .option('--json', 'Output JSON')\n .action(async (options) => {\n const { executeDaemonUninstall } = await import('./lifecycle-core.js');\n await executeDaemonUninstall(options);\n });\n}\n\n/**\n * Create service start subcommand - starts via daemon service manager\n */\nexport function createServiceStartCommand(): Command {\n return new Command('start')\n .description('Start gateway via OS service manager')\n .option('--json', 'Output JSON')\n .action(async (options) => {\n const [{ resolveGatewayService, startGatewayService, isDaemonAvailableAsync }] =\n await Promise.all([import('../../../daemon/service.js')]);\n\n const available = await isDaemonAvailableAsync();\n if (!available) {\n console.error('❌ Daemon not available on this platform');\n process.exit(1);\n }\n\n const service = await resolveGatewayService();\n const result = await startGatewayService({ service });\n\n if (options.json) {\n console.log(JSON.stringify({ ok: result.outcome === 'started', outcome: result.outcome }));\n return;\n }\n\n switch (result.outcome) {\n case 'started':\n console.log('✅ Gateway service started');\n break;\n case 'missing-install':\n console.error('❌ Service not installed. Run: xopc gateway service install');\n process.exit(1);\n break;\n case 'repair-required':\n console.error('⚠️ Service needs repair:');\n for (const issue of result.issues || []) {\n console.error(` - ${issue.message}`);\n }\n console.log('💡 Run: xopc gateway service install --force');\n process.exit(1);\n break;\n default:\n console.log(`ℹ️ Service start outcome: ${result.outcome}`);\n }\n });\n}\n\n/**\n * Create service status subcommand\n */\nexport function createServiceStatusCommand(): Command {\n return new Command('service-status')\n .description('Show OS service status')\n .option('--json', 'Output JSON')\n .action(async (options) => {\n const [{ resolveGatewayService, isDaemonAvailableAsync, getPlatformName }] =\n await Promise.all([import('../../../daemon/service.js')]);\n\n const available = await isDaemonAvailableAsync();\n if (!available) {\n if (options.json) {\n console.log(JSON.stringify({ available: false, platform: process.platform }));\n } else {\n console.log(`ℹ️ Daemon not available on ${getPlatformName()}`);\n }\n return;\n }\n\n const service = await resolveGatewayService();\n const [loaded, runtime, command] = await Promise.all([\n service.isLoaded({ env: process.env }),\n service.readRuntime(),\n service.readCommand(),\n ]);\n\n if (options.json) {\n console.log(JSON.stringify({ available: true, loaded, runtime, command, label: service.label }, null, 2));\n return;\n }\n\n console.log('📊 Gateway Service Status');\n console.log('');\n console.log(` Platform: ${getPlatformName()}`);\n console.log(` Service: ${loaded ? service.loadedText : service.notLoadedText}`);\n console.log(` Runtime: ${runtime.status}${runtime.pid ? ` (pid ${runtime.pid})` : ''}`);\n\n if (command) {\n const portMatch = command.programArguments.join(' ').match(/--port\\s+(\\d+)/);\n if (portMatch) {\n console.log(` Port: ${portMatch[1]}`);\n }\n const version = command.environment?.XOPC_SERVICE_VERSION;\n if (version) {\n console.log(` Version: ${version}`);\n }\n }\n\n if (!loaded) {\n console.log('');\n console.log('💡 Install with: xopc gateway service install');\n }\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service.js","names":[],"sources":["../../../../../src/cli/commands/gateway/service.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { resolveConfigPath } from '../../../config/paths.js';\nimport { getContextWithOpts } from '../../context.js';\nimport { createRestartCommand } from './restart.js';\nimport { createStopCommand } from './stop.js';\n\n/**\n * Create service install subcommand - actually installs the OS service\n */\nexport function createInstallCommand(): Command {\n return new Command('install')\n .description('Install gateway as OS service (LaunchAgent / systemd / Task)')\n .option('--port <port>', 'Gateway port')\n .option('--token <token>', 'Gateway auth token')\n .option('--force', 'Force reinstall if already installed')\n .option('--json', 'Output JSON')\n .action(async (options) => {\n const ctx = getContextWithOpts();\n const configPath = ctx.configPath || resolveConfigPath();\n\n const [{ loadConfig }, { resolveGatewayService, isDaemonAvailableAsync, getPlatformName }, { buildGatewayInstallArgs }] =\n await Promise.all([\n import('../../../config/index.js'),\n import('../../../daemon/service.js'),\n import('../../../daemon/install-plan.js'),\n ]);\n\n const config = loadConfig(configPath);\n const port = options.port ? parseInt(options.port, 10) : (config?.gateway?.port || 18790);\n const bind = config?.gateway?.bind ?? 'loopback';\n const token = options.token || config?.gateway?.auth?.token;\n\n const available = await isDaemonAvailableAsync();\n if (!available) {\n if (options.json) {\n console.log(JSON.stringify({ ok: false, error: 'Daemon not available' }));\n } else {\n console.error(`❌ OS service not available on ${getPlatformName()}`);\n }\n process.exit(1);\n }\n\n const service = await resolveGatewayService();\n\n // Check if already installed\n const loaded = await service.isLoaded({ env: process.env });\n if (loaded && !options.force) {\n if (options.json) {\n console.log(JSON.stringify({ ok: true, result: 'already-installed' }));\n } else {\n console.log('ℹ️ Service already installed. Use --force to reinstall.');\n }\n return;\n }\n\n // Uninstall first if force\n if (loaded && options.force) {\n try {\n await service.uninstall({ env: process.env });\n } catch {\n // Best-effort\n }\n }\n\n // Build install args and install\n const installArgs = buildGatewayInstallArgs({ port, bind, token });\n installArgs.stdout = process.stdout;\n\n try {\n await service.install(installArgs);\n\n if (options.json) {\n console.log(JSON.stringify({ ok: true, result: 'installed', label: service.label, port }));\n } else {\n console.log('');\n console.log(`✅ Gateway service installed`);\n console.log(` Service: ${service.label}`);\n console.log(` Port: ${port}`);\n console.log('');\n console.log('💡 The service will start automatically on login.');\n console.log(' Use `xopc gateway status` to verify.');\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (options.json) {\n console.log(JSON.stringify({ ok: false, error: message }));\n } else {\n console.error(`❌ Failed to install service: ${message}`);\n }\n process.exit(1);\n }\n });\n}\n\n/**\n * Create service uninstall subcommand\n */\nexport function createUninstallCommand(): Command {\n return new Command('uninstall')\n .description('Uninstall gateway OS service')\n .option('--json', 'Output JSON')\n .action(async (options) => {\n const { executeDaemonUninstall } = await import('./lifecycle-core.js');\n await executeDaemonUninstall(options);\n });\n}\n\n/**\n * Create service start subcommand - starts via daemon service manager\n */\nexport function createServiceStartCommand(): Command {\n return new Command('start')\n .description('Start gateway via OS service manager')\n .option('--json', 'Output JSON')\n .action(async (options) => {\n const [{ resolveGatewayService, startGatewayService, isDaemonAvailableAsync }] =\n await Promise.all([import('../../../daemon/service.js')]);\n\n const available = await isDaemonAvailableAsync();\n if (!available) {\n console.error('❌ Daemon not available on this platform');\n process.exit(1);\n }\n\n const service = await resolveGatewayService();\n const result = await startGatewayService({ service });\n\n if (options.json) {\n console.log(JSON.stringify({ ok: result.outcome === 'started', outcome: result.outcome }));\n return;\n }\n\n switch (result.outcome) {\n case 'started':\n console.log('✅ Gateway service started');\n break;\n case 'missing-install':\n console.error('❌ Service not installed. Run: xopc gateway service install');\n process.exit(1);\n break;\n case 'repair-required':\n console.error('⚠️ Service needs repair:');\n for (const issue of result.issues || []) {\n console.error(` - ${issue.message}`);\n }\n console.log('💡 Run: xopc gateway service install --force');\n process.exit(1);\n break;\n default:\n console.log(`ℹ️ Service start outcome: ${result.outcome}`);\n }\n });\n}\n\n/**\n * Create service status subcommand\n */\nexport function createServiceStatusCommand(): Command {\n return new Command('status')\n .description('Show OS service status')\n .option('--json', 'Output JSON')\n .action(async (options) => {\n const [{ resolveGatewayService, isDaemonAvailableAsync, getPlatformName }] =\n await Promise.all([import('../../../daemon/service.js')]);\n\n const available = await isDaemonAvailableAsync();\n if (!available) {\n if (options.json) {\n console.log(JSON.stringify({ available: false, platform: process.platform }));\n } else {\n console.log(`ℹ️ Daemon not available on ${getPlatformName()}`);\n }\n return;\n }\n\n const service = await resolveGatewayService();\n const [loaded, runtime, command] = await Promise.all([\n service.isLoaded({ env: process.env }),\n service.readRuntime(),\n service.readCommand(),\n ]);\n\n if (options.json) {\n console.log(JSON.stringify({ available: true, loaded, runtime, command, label: service.label }, null, 2));\n return;\n }\n\n console.log('📊 Gateway Service Status');\n console.log('');\n console.log(` Platform: ${getPlatformName()}`);\n console.log(` Service: ${loaded ? service.loadedText : service.notLoadedText}`);\n console.log(` Runtime: ${runtime.status}${runtime.pid ? ` (pid ${runtime.pid})` : ''}`);\n\n if (command) {\n const portMatch = command.programArguments.join(' ').match(/--port\\s+(\\d+)/);\n if (portMatch) {\n console.log(` Port: ${portMatch[1]}`);\n }\n const version = command.environment?.XOPC_SERVICE_VERSION;\n if (version) {\n console.log(` Version: ${version}`);\n }\n }\n\n if (!loaded) {\n console.log('');\n console.log('💡 Install with: xopc gateway service install');\n }\n });\n}\n\n/**\n * Gateway OS service command group (`xopc gateway service …`).\n */\nexport function createServiceCommand(): Command {\n const cmd = new Command('service').description(\n 'Manage gateway OS service (LaunchAgent / systemd / Task)',\n );\n cmd.addCommand(createInstallCommand());\n cmd.addCommand(createUninstallCommand());\n cmd.addCommand(createServiceStartCommand());\n cmd.addCommand(createServiceStatusCommand());\n cmd.addCommand(createStopCommand());\n cmd.addCommand(createRestartCommand());\n return cmd;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { init_paths, resolveConfigPath } from "../../../config/paths.js";
|
|
2
|
+
import { loadConfig } from "../../../config/loader.js";
|
|
3
|
+
import "../../../config/index.js";
|
|
4
|
+
import { resolveGatewayLaunchAgentLabel, resolveGatewaySystemdServiceName, resolveGatewayWindowsTaskName } from "../../../daemon/constants.js";
|
|
5
|
+
//#region src/cli/commands/gateway/shared.ts
|
|
6
|
+
init_paths();
|
|
7
|
+
function parsePortFromArgs(programArguments) {
|
|
8
|
+
if (!programArguments?.length) return null;
|
|
9
|
+
for (let i = 0; i < programArguments.length; i += 1) {
|
|
10
|
+
const arg = programArguments[i];
|
|
11
|
+
if (arg === "--port") {
|
|
12
|
+
const next = programArguments[i + 1];
|
|
13
|
+
const parsed = parseInt(String(next), 10);
|
|
14
|
+
if (Number.isFinite(parsed) && parsed > 0) return parsed;
|
|
15
|
+
}
|
|
16
|
+
if (arg?.startsWith("--port=")) {
|
|
17
|
+
const parsed = parseInt(arg.split("=", 2)[1] ?? "", 10);
|
|
18
|
+
if (Number.isFinite(parsed) && parsed > 0) return parsed;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
function resolveGatewayPortFromConfig(configPath) {
|
|
24
|
+
const config = loadConfig(configPath ?? resolveConfigPath());
|
|
25
|
+
return typeof config.gateway?.port === "number" ? config.gateway.port : 18790;
|
|
26
|
+
}
|
|
27
|
+
function renderGatewayServiceStartHints(env = process.env) {
|
|
28
|
+
const profile = env.XOPC_PROFILE;
|
|
29
|
+
const systemdName = resolveGatewaySystemdServiceName(profile);
|
|
30
|
+
const launchAgent = resolveGatewayLaunchAgentLabel(profile);
|
|
31
|
+
const windowsTask = resolveGatewayWindowsTaskName(profile);
|
|
32
|
+
switch (process.platform) {
|
|
33
|
+
case "darwin": return [
|
|
34
|
+
"xopc gateway service install",
|
|
35
|
+
"xopc gateway",
|
|
36
|
+
`LaunchAgent: ~/Library/LaunchAgents/${launchAgent}.plist`
|
|
37
|
+
];
|
|
38
|
+
case "linux": return [
|
|
39
|
+
"xopc gateway service install",
|
|
40
|
+
"xopc gateway",
|
|
41
|
+
`systemd user service: ${systemdName}.service`
|
|
42
|
+
];
|
|
43
|
+
case "win32": return [
|
|
44
|
+
"xopc gateway service install",
|
|
45
|
+
"xopc gateway",
|
|
46
|
+
`Scheduled task: ${windowsTask}`
|
|
47
|
+
];
|
|
48
|
+
default: return ["xopc gateway service install", "xopc gateway"];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
export { parsePortFromArgs, renderGatewayServiceStartHints, resolveGatewayPortFromConfig };
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","names":[],"sources":["../../../../../src/cli/commands/gateway/shared.ts"],"sourcesContent":["import { loadConfig } from '../../../config/index.js';\nimport { resolveConfigPath } from '../../../config/paths.js';\nimport {\n resolveGatewayLaunchAgentLabel,\n resolveGatewaySystemdServiceName,\n resolveGatewayWindowsTaskName,\n} from '../../../daemon/constants.js';\n\nexport function parsePortFromArgs(programArguments: string[] | undefined): number | null {\n if (!programArguments?.length) {\n return null;\n }\n for (let i = 0; i < programArguments.length; i += 1) {\n const arg = programArguments[i];\n if (arg === '--port') {\n const next = programArguments[i + 1];\n const parsed = parseInt(String(next), 10);\n if (Number.isFinite(parsed) && parsed > 0) {\n return parsed;\n }\n }\n if (arg?.startsWith('--port=')) {\n const parsed = parseInt(arg.split('=', 2)[1] ?? '', 10);\n if (Number.isFinite(parsed) && parsed > 0) {\n return parsed;\n }\n }\n }\n return null;\n}\n\nexport function resolveGatewayPortFromConfig(configPath?: string): number {\n const config = loadConfig(configPath ?? resolveConfigPath());\n return typeof config.gateway?.port === 'number' ? config.gateway.port : 18790;\n}\n\nexport function renderGatewayServiceStartHints(env: NodeJS.ProcessEnv = process.env): string[] {\n const profile = env.XOPC_PROFILE;\n const systemdName = resolveGatewaySystemdServiceName(profile);\n const launchAgent = resolveGatewayLaunchAgentLabel(profile);\n const windowsTask = resolveGatewayWindowsTaskName(profile);\n\n switch (process.platform) {\n case 'darwin':\n return [\n 'xopc gateway service install',\n 'xopc gateway',\n `LaunchAgent: ~/Library/LaunchAgents/${launchAgent}.plist`,\n ];\n case 'linux':\n return [\n 'xopc gateway service install',\n 'xopc gateway',\n `systemd user service: ${systemdName}.service`,\n ];\n case 'win32':\n return [\n 'xopc gateway service install',\n 'xopc gateway',\n `Scheduled task: ${windowsTask}`,\n ];\n default:\n return ['xopc gateway service install', 'xopc gateway'];\n }\n}\n"],"mappings":";;;;;YAC6D;AAO7D,SAAgB,kBAAkB,kBAAuD;AACvF,KAAI,CAAC,kBAAkB,OACrB,QAAO;AAET,MAAK,IAAI,IAAI,GAAG,IAAI,iBAAiB,QAAQ,KAAK,GAAG;EACnD,MAAM,MAAM,iBAAiB;AAC7B,MAAI,QAAQ,UAAU;GACpB,MAAM,OAAO,iBAAiB,IAAI;GAClC,MAAM,SAAS,SAAS,OAAO,KAAK,EAAE,GAAG;AACzC,OAAI,OAAO,SAAS,OAAO,IAAI,SAAS,EACtC,QAAO;;AAGX,MAAI,KAAK,WAAW,UAAU,EAAE;GAC9B,MAAM,SAAS,SAAS,IAAI,MAAM,KAAK,EAAE,CAAC,MAAM,IAAI,GAAG;AACvD,OAAI,OAAO,SAAS,OAAO,IAAI,SAAS,EACtC,QAAO;;;AAIb,QAAO;;AAGT,SAAgB,6BAA6B,YAA6B;CACxE,MAAM,SAAS,WAAW,cAAc,mBAAmB,CAAC;AAC5D,QAAO,OAAO,OAAO,SAAS,SAAS,WAAW,OAAO,QAAQ,OAAO;;AAG1E,SAAgB,+BAA+B,MAAyB,QAAQ,KAAe;CAC7F,MAAM,UAAU,IAAI;CACpB,MAAM,cAAc,iCAAiC,QAAQ;CAC7D,MAAM,cAAc,+BAA+B,QAAQ;CAC3D,MAAM,cAAc,8BAA8B,QAAQ;AAE1D,SAAQ,QAAQ,UAAhB;EACE,KAAK,SACH,QAAO;GACL;GACA;GACA,uCAAuC,YAAY;GACpD;EACH,KAAK,QACH,QAAO;GACL;GACA;GACA,yBAAyB,YAAY;GACtC;EACH,KAAK,QACH,QAAO;GACL;GACA;GACA,mBAAmB;GACpB;EACH,QACE,QAAO,CAAC,gCAAgC,eAAe"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { init_paths, resolveConfigPath } from "../../../config/paths.js";
|
|
2
|
-
import { getContextWithOpts } from "../../
|
|
2
|
+
import { getContextWithOpts } from "../../context.js";
|
|
3
3
|
import { addGatewayClientOptions, parseGatewayClientOptions } from "../../utils/gateway-client-options.js";
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
//#region src/cli/commands/gateway/status.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","names":["optsProbe"],"sources":["../../../../../src/cli/commands/gateway/status.ts"],"sourcesContent":["import { Command } from 'commander';\n\nimport { resolveConfigPath } from '../../../config/paths.js';\nimport { getContextWithOpts } from '../../index.js';\nimport {\n addGatewayClientOptions,\n parseGatewayClientOptions,\n} from '../../utils/gateway-client-options.js';\n\ninterface StatusResponse {\n status: string;\n version?: string;\n channels?: Record<string, { status: string }>;\n uptime?: number;\n}\n\nfunction formatUptime(seconds?: number): string {\n if (!seconds || seconds <= 0) return 'unknown';\n const days = Math.floor(seconds / 86400);\n const hours = Math.floor((seconds % 86400) / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const parts: string[] = [];\n if (days > 0) parts.push(`${days}d`);\n if (hours > 0) parts.push(`${hours}h`);\n parts.push(`${minutes}m`);\n return parts.join(' ');\n}\n\nexport function createStatusCommand(): Command {\n const cmd = new Command('status').description('Check gateway status (service + connectivity)');\n\n addGatewayClientOptions(cmd);\n cmd.option('--no-probe', 'Skip HTTP probe (only check service/lock)');\n\n cmd.action(async (options) => {\n const ctx = getContextWithOpts();\n const configPath = ctx.configPath || resolveConfigPath();\n const [\n { loadConfig },\n { acquireGatewayLock, GatewayLockError },\n { callGatewayApi, resolveGatewayUrl },\n { resolveGatewayService, isDaemonAvailableAsync, getPlatformName },\n ] = await Promise.all([\n import('../../../config/index.js'),\n import('../../../gateway/lock.js'),\n import('../../utils/gateway-client.js'),\n import('../../../daemon/service.js'),\n ]);\n const config = loadConfig(configPath);\n const port = config?.gateway?.port ?? 18790;\n const clientOpts = { ...parseGatewayClientOptions(options as Record<string, unknown>), configPath };\n const gatewayUrl = resolveGatewayUrl({ url: clientOpts.url, configPath });\n\n // ─── Service Status ───\n let serviceLoaded = false;\n let serviceRuntime: { status: string; pid?: number; lastExitStatus?: number } | null = null;\n let serviceVersion: string | undefined;\n\n const daemonAvailable = await isDaemonAvailableAsync();\n if (daemonAvailable) {\n try {\n const service = await resolveGatewayService();\n serviceLoaded = await service.isLoaded({ env: process.env });\n if (serviceLoaded) {\n serviceRuntime = await service.readRuntime();\n const command = await service.readCommand();\n serviceVersion = command?.environment?.XOPC_SERVICE_VERSION;\n }\n } catch {\n // Best-effort service check\n }\n }\n\n // ─── Lock Check ───\n let lockAlive = false;\n let lockPid: number | undefined;\n\n try {\n const lock = await acquireGatewayLock(configPath, { timeoutMs: 100, port });\n await lock.release();\n lockAlive = false;\n } catch (err) {\n if (err instanceof GatewayLockError) {\n lockAlive = true;\n const pidMatch = err.message.match(/pid\\s+(\\d+)/);\n if (pidMatch) lockPid = parseInt(pidMatch[1], 10);\n } else {\n console.error('❌ Failed to check status:', err);\n process.exit(1);\n }\n }\n\n // ─── HTTP Probe ───\n const optsProbe = options as { probe?: boolean };\n const shouldProbe = optsProbe.probe !== false;\n\n let probeResult: {\n ok: boolean;\n data?: StatusResponse;\n error?: string;\n durationMs: number;\n } | null = null;\n\n if (shouldProbe) {\n const healthProbe = await callGatewayApi<{ status: string }>('GET', '/api/health', {\n ...clientOpts,\n timeoutMs: clientOpts.timeoutMs ?? 5000,\n });\n\n if (healthProbe.ok) {\n const statusProbe = await callGatewayApi<StatusResponse>('GET', '/api/status', clientOpts);\n probeResult = statusProbe.ok\n ? statusProbe\n : { ok: true, durationMs: healthProbe.durationMs, data: { status: 'ok' } };\n } else {\n probeResult = { ok: false, error: healthProbe.error, durationMs: healthProbe.durationMs };\n }\n }\n\n // ─── JSON Output ───\n if (clientOpts.json) {\n console.log(\n JSON.stringify(\n {\n running: lockAlive || (probeResult?.ok ?? false),\n service: daemonAvailable\n ? {\n platform: getPlatformName(),\n loaded: serviceLoaded,\n runtime: serviceRuntime,\n version: serviceVersion,\n }\n : null,\n lock: { alive: lockAlive, pid: lockPid },\n probe: probeResult\n ? {\n reachable: probeResult.ok,\n durationMs: probeResult.durationMs,\n ...(probeResult.data ?? {}),\n ...(probeResult.error ? { error: probeResult.error } : {}),\n }\n : null,\n url: gatewayUrl,\n port,\n },\n null,\n 2,\n ),\n );\n process.exit(probeResult?.ok || lockAlive ? 0 : 1);\n }\n\n // ─── Human Output ───\n const isRunning = lockAlive || (probeResult?.ok ?? false) || serviceRuntime?.status === 'running';\n\n if (!isRunning) {\n console.log('⚠️ Gateway is not running');\n if (daemonAvailable) {\n console.log(` Service: ${serviceLoaded ? 'installed (not running)' : 'not installed'}`);\n }\n if (probeResult && !probeResult.ok) {\n console.log(` Probe: ${probeResult.error} (${probeResult.durationMs}ms)`);\n }\n console.log('');\n console.log('💡 Start with: xopc gateway');\n if (!serviceLoaded && daemonAvailable) {\n console.log(' Or install service: xopc gateway service install');\n }\n process.exit(1);\n }\n\n console.log('Gateway Status');\n console.log('');\n\n // Service info\n if (daemonAvailable && serviceLoaded) {\n const runtimeStatus = serviceRuntime?.status ?? 'unknown';\n const pid = serviceRuntime?.pid || lockPid;\n console.log(` Service: ${getPlatformName()} (loaded)`);\n console.log(` Runtime: ${runtimeStatus}${pid ? ` (pid ${pid})` : ''}`);\n } else if (lockPid) {\n console.log(` PID: ${lockPid}`);\n }\n\n console.log(` Port: ${port}`);\n console.log(` URL: ${gatewayUrl}`);\n\n // Version from service or probe\n const version = probeResult?.data?.version || serviceVersion;\n if (version) {\n console.log(` Version: ${version}`);\n }\n\n // Uptime from probe\n if (probeResult?.ok && probeResult.data?.uptime != null) {\n console.log(` Uptime: ${formatUptime(probeResult.data.uptime)}`);\n }\n\n // Probe result\n if (probeResult?.ok) {\n console.log(` Probe: OK (${probeResult.durationMs}ms)`);\n } else if (probeResult && !probeResult.ok) {\n console.log(` Probe: Failed (${probeResult.error})`);\n } else if (!shouldProbe) {\n console.log(' Probe: skipped');\n }\n\n // Token\n const token = config?.gateway?.auth?.token;\n if (token) {\n console.log(` Token: configured ✓`);\n }\n\n // Channels\n if (probeResult?.ok && probeResult.data?.channels) {\n const channels = probeResult.data.channels;\n if (Object.keys(channels).length > 0) {\n console.log('');\n console.log('Channels:');\n for (const [name, info] of Object.entries(channels)) {\n const icon = info.status === 'connected' ? '✅' : info.status === 'disabled' ? '⚪' : '❌';\n console.log(` ${icon} ${name}: ${info.status}`);\n }\n }\n }\n\n process.exit(0);\n });\n\n return cmd;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"status.js","names":["optsProbe"],"sources":["../../../../../src/cli/commands/gateway/status.ts"],"sourcesContent":["import { Command } from 'commander';\n\nimport { resolveConfigPath } from '../../../config/paths.js';\nimport { getContextWithOpts } from '../../context.js';\nimport {\n addGatewayClientOptions,\n parseGatewayClientOptions,\n} from '../../utils/gateway-client-options.js';\n\ninterface StatusResponse {\n status: string;\n version?: string;\n channels?: Record<string, { status: string }>;\n uptime?: number;\n}\n\nfunction formatUptime(seconds?: number): string {\n if (!seconds || seconds <= 0) return 'unknown';\n const days = Math.floor(seconds / 86400);\n const hours = Math.floor((seconds % 86400) / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const parts: string[] = [];\n if (days > 0) parts.push(`${days}d`);\n if (hours > 0) parts.push(`${hours}h`);\n parts.push(`${minutes}m`);\n return parts.join(' ');\n}\n\nexport function createStatusCommand(): Command {\n const cmd = new Command('status').description('Check gateway status (service + connectivity)');\n\n addGatewayClientOptions(cmd);\n cmd.option('--no-probe', 'Skip HTTP probe (only check service/lock)');\n\n cmd.action(async (options) => {\n const ctx = getContextWithOpts();\n const configPath = ctx.configPath || resolveConfigPath();\n const [\n { loadConfig },\n { acquireGatewayLock, GatewayLockError },\n { callGatewayApi, resolveGatewayUrl },\n { resolveGatewayService, isDaemonAvailableAsync, getPlatformName },\n ] = await Promise.all([\n import('../../../config/index.js'),\n import('../../../gateway/lock.js'),\n import('../../utils/gateway-client.js'),\n import('../../../daemon/service.js'),\n ]);\n const config = loadConfig(configPath);\n const port = config?.gateway?.port ?? 18790;\n const clientOpts = { ...parseGatewayClientOptions(options as Record<string, unknown>), configPath };\n const gatewayUrl = resolveGatewayUrl({ url: clientOpts.url, configPath });\n\n // ─── Service Status ───\n let serviceLoaded = false;\n let serviceRuntime: { status: string; pid?: number; lastExitStatus?: number } | null = null;\n let serviceVersion: string | undefined;\n\n const daemonAvailable = await isDaemonAvailableAsync();\n if (daemonAvailable) {\n try {\n const service = await resolveGatewayService();\n serviceLoaded = await service.isLoaded({ env: process.env });\n if (serviceLoaded) {\n serviceRuntime = await service.readRuntime();\n const command = await service.readCommand();\n serviceVersion = command?.environment?.XOPC_SERVICE_VERSION;\n }\n } catch {\n // Best-effort service check\n }\n }\n\n // ─── Lock Check ───\n let lockAlive = false;\n let lockPid: number | undefined;\n\n try {\n const lock = await acquireGatewayLock(configPath, { timeoutMs: 100, port });\n await lock.release();\n lockAlive = false;\n } catch (err) {\n if (err instanceof GatewayLockError) {\n lockAlive = true;\n const pidMatch = err.message.match(/pid\\s+(\\d+)/);\n if (pidMatch) lockPid = parseInt(pidMatch[1], 10);\n } else {\n console.error('❌ Failed to check status:', err);\n process.exit(1);\n }\n }\n\n // ─── HTTP Probe ───\n const optsProbe = options as { probe?: boolean };\n const shouldProbe = optsProbe.probe !== false;\n\n let probeResult: {\n ok: boolean;\n data?: StatusResponse;\n error?: string;\n durationMs: number;\n } | null = null;\n\n if (shouldProbe) {\n const healthProbe = await callGatewayApi<{ status: string }>('GET', '/api/health', {\n ...clientOpts,\n timeoutMs: clientOpts.timeoutMs ?? 5000,\n });\n\n if (healthProbe.ok) {\n const statusProbe = await callGatewayApi<StatusResponse>('GET', '/api/status', clientOpts);\n probeResult = statusProbe.ok\n ? statusProbe\n : { ok: true, durationMs: healthProbe.durationMs, data: { status: 'ok' } };\n } else {\n probeResult = { ok: false, error: healthProbe.error, durationMs: healthProbe.durationMs };\n }\n }\n\n // ─── JSON Output ───\n if (clientOpts.json) {\n console.log(\n JSON.stringify(\n {\n running: lockAlive || (probeResult?.ok ?? false),\n service: daemonAvailable\n ? {\n platform: getPlatformName(),\n loaded: serviceLoaded,\n runtime: serviceRuntime,\n version: serviceVersion,\n }\n : null,\n lock: { alive: lockAlive, pid: lockPid },\n probe: probeResult\n ? {\n reachable: probeResult.ok,\n durationMs: probeResult.durationMs,\n ...(probeResult.data ?? {}),\n ...(probeResult.error ? { error: probeResult.error } : {}),\n }\n : null,\n url: gatewayUrl,\n port,\n },\n null,\n 2,\n ),\n );\n process.exit(probeResult?.ok || lockAlive ? 0 : 1);\n }\n\n // ─── Human Output ───\n const isRunning = lockAlive || (probeResult?.ok ?? false) || serviceRuntime?.status === 'running';\n\n if (!isRunning) {\n console.log('⚠️ Gateway is not running');\n if (daemonAvailable) {\n console.log(` Service: ${serviceLoaded ? 'installed (not running)' : 'not installed'}`);\n }\n if (probeResult && !probeResult.ok) {\n console.log(` Probe: ${probeResult.error} (${probeResult.durationMs}ms)`);\n }\n console.log('');\n console.log('💡 Start with: xopc gateway');\n if (!serviceLoaded && daemonAvailable) {\n console.log(' Or install service: xopc gateway service install');\n }\n process.exit(1);\n }\n\n console.log('Gateway Status');\n console.log('');\n\n // Service info\n if (daemonAvailable && serviceLoaded) {\n const runtimeStatus = serviceRuntime?.status ?? 'unknown';\n const pid = serviceRuntime?.pid || lockPid;\n console.log(` Service: ${getPlatformName()} (loaded)`);\n console.log(` Runtime: ${runtimeStatus}${pid ? ` (pid ${pid})` : ''}`);\n } else if (lockPid) {\n console.log(` PID: ${lockPid}`);\n }\n\n console.log(` Port: ${port}`);\n console.log(` URL: ${gatewayUrl}`);\n\n // Version from service or probe\n const version = probeResult?.data?.version || serviceVersion;\n if (version) {\n console.log(` Version: ${version}`);\n }\n\n // Uptime from probe\n if (probeResult?.ok && probeResult.data?.uptime != null) {\n console.log(` Uptime: ${formatUptime(probeResult.data.uptime)}`);\n }\n\n // Probe result\n if (probeResult?.ok) {\n console.log(` Probe: OK (${probeResult.durationMs}ms)`);\n } else if (probeResult && !probeResult.ok) {\n console.log(` Probe: Failed (${probeResult.error})`);\n } else if (!shouldProbe) {\n console.log(' Probe: skipped');\n }\n\n // Token\n const token = config?.gateway?.auth?.token;\n if (token) {\n console.log(` Token: configured ✓`);\n }\n\n // Channels\n if (probeResult?.ok && probeResult.data?.channels) {\n const channels = probeResult.data.channels;\n if (Object.keys(channels).length > 0) {\n console.log('');\n console.log('Channels:');\n for (const [name, info] of Object.entries(channels)) {\n const icon = info.status === 'connected' ? '✅' : info.status === 'disabled' ? '⚪' : '❌';\n console.log(` ${icon} ${name}: ${info.status}`);\n }\n }\n }\n\n process.exit(0);\n });\n\n return cmd;\n}\n"],"mappings":"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"}
|
|
@@ -5,8 +5,8 @@ import { Command } from "commander";
|
|
|
5
5
|
*/
|
|
6
6
|
function createStopCommand() {
|
|
7
7
|
return new Command("stop").description("Stop the gateway service").option("--disable", "Disable KeepAlive so gateway does not respawn").option("--json", "Output JSON").action(async (options) => {
|
|
8
|
-
const {
|
|
9
|
-
await
|
|
8
|
+
const { runDaemonStop } = await import("./lifecycle.js");
|
|
9
|
+
await runDaemonStop(options);
|
|
10
10
|
});
|
|
11
11
|
}
|
|
12
12
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stop.js","names":[],"sources":["../../../../../src/cli/commands/gateway/stop.ts"],"sourcesContent":["import { Command } from 'commander';\n\n/**\n * Create stop subcommand - delegates to daemon lifecycle core\n */\nexport function createStopCommand(): Command {\n return new Command('stop')\n .description('Stop the gateway service')\n .option('--disable', 'Disable KeepAlive so gateway does not respawn')\n .option('--json', 'Output JSON')\n .action(async (options) => {\n const {
|
|
1
|
+
{"version":3,"file":"stop.js","names":[],"sources":["../../../../../src/cli/commands/gateway/stop.ts"],"sourcesContent":["import { Command } from 'commander';\n\n/**\n * Create stop subcommand - delegates to daemon lifecycle core\n */\nexport function createStopCommand(): Command {\n return new Command('stop')\n .description('Stop the gateway service')\n .option('--disable', 'Disable KeepAlive so gateway does not respawn')\n .option('--json', 'Output JSON')\n .action(async (options) => {\n const { runDaemonStop } = await import('./lifecycle.js');\n await runDaemonStop(options);\n });\n}\n"],"mappings":";;;;;AAKA,SAAgB,oBAA6B;AAC3C,QAAO,IAAI,QAAQ,OAAO,CACvB,YAAY,2BAA2B,CACvC,OAAO,aAAa,gDAAgD,CACpE,OAAO,UAAU,cAAc,CAC/B,OAAO,OAAO,YAAY;EACzB,MAAM,EAAE,kBAAkB,MAAM,OAAO;AACvC,QAAM,cAAc,QAAQ;GAC5B"}
|
|
@@ -10,10 +10,7 @@ const GATEWAY_SUBCOMMAND_LOADERS = {
|
|
|
10
10
|
stop: async () => (await import("./stop.js")).createStopCommand(),
|
|
11
11
|
restart: async () => (await import("./restart.js")).createRestartCommand(),
|
|
12
12
|
logs: async () => (await import("./logs.js")).createLogsCommand(),
|
|
13
|
-
|
|
14
|
-
uninstall: async () => (await import("./service.js")).createUninstallCommand(),
|
|
15
|
-
start: async () => (await import("./service.js")).createServiceStartCommand(),
|
|
16
|
-
"service-status": async () => (await import("./service.js")).createServiceStatusCommand()
|
|
13
|
+
service: async () => (await import("./service.js")).createServiceCommand()
|
|
17
14
|
};
|
|
18
15
|
async function attachAllGatewaySubcommands(cmd, ctx) {
|
|
19
16
|
for (const loader of Object.values(GATEWAY_SUBCOMMAND_LOADERS)) cmd.addCommand(await loader());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subcommands.js","names":[],"sources":["../../../../../src/cli/commands/gateway/subcommands.ts"],"sourcesContent":["import type { Command } from 'commander';\n\nimport type { CLIContext } from '../../registry.js';\nimport {\n isKnownGatewaySubcommand,\n resolveGatewaySubcommandName,\n} from '../../gateway-run-argv.js';\nimport { resolveCliArgvInvocation } from '../../argv-invocation.js';\n\ntype GatewaySubcommandLoader = () => Promise<Command>;\n\nconst GATEWAY_SUBCOMMAND_LOADERS: Record<string, GatewaySubcommandLoader> = {\n token: async () => (await import('./token.js')).createTokenCommand(),\n status: async () => (await import('./status.js')).createStatusCommand(),\n health: async () => (await import('./health.js')).createHealthCommand(),\n call: async () => (await import('./call.js')).createCallCommand(),\n probe: async () => (await import('./probe.js')).createProbeCommand(),\n stop: async () => (await import('./stop.js')).createStopCommand(),\n restart: async () => (await import('./restart.js')).createRestartCommand(),\n logs: async () => (await import('./logs.js')).createLogsCommand(),\n
|
|
1
|
+
{"version":3,"file":"subcommands.js","names":[],"sources":["../../../../../src/cli/commands/gateway/subcommands.ts"],"sourcesContent":["import type { Command } from 'commander';\n\nimport type { CLIContext } from '../../registry.js';\nimport {\n isKnownGatewaySubcommand,\n resolveGatewaySubcommandName,\n} from '../../gateway-run-argv.js';\nimport { resolveCliArgvInvocation } from '../../argv-invocation.js';\n\ntype GatewaySubcommandLoader = () => Promise<Command>;\n\nconst GATEWAY_SUBCOMMAND_LOADERS: Record<string, GatewaySubcommandLoader> = {\n token: async () => (await import('./token.js')).createTokenCommand(),\n status: async () => (await import('./status.js')).createStatusCommand(),\n health: async () => (await import('./health.js')).createHealthCommand(),\n call: async () => (await import('./call.js')).createCallCommand(),\n probe: async () => (await import('./probe.js')).createProbeCommand(),\n stop: async () => (await import('./stop.js')).createStopCommand(),\n restart: async () => (await import('./restart.js')).createRestartCommand(),\n logs: async () => (await import('./logs.js')).createLogsCommand(),\n service: async () => (await import('./service.js')).createServiceCommand(),\n};\n\nasync function attachAllGatewaySubcommands(cmd: Command, ctx: CLIContext): Promise<void> {\n for (const loader of Object.values(GATEWAY_SUBCOMMAND_LOADERS)) {\n cmd.addCommand(await loader());\n }\n const { registerGatewaySshTunnelCommand } = await import('../gateway-ssh-tunnel.js');\n registerGatewaySshTunnelCommand(cmd, ctx);\n}\n\nfunction shouldEagerLoadGatewaySubcommands(argv: string[]): boolean {\n const invocation = resolveCliArgvInvocation(argv);\n if (!invocation.hasHelpOrVersion) {\n return false;\n }\n const gatewayPath = resolveGatewaySubcommandName(argv);\n return gatewayPath === undefined;\n}\n\nexport async function prepareGatewayCommandForArgv(cmd: Command, ctx: CLIContext): Promise<void> {\n const subcommand = resolveGatewaySubcommandName(ctx.argv);\n if (subcommand === 'ssh-tunnel') {\n const { registerGatewaySshTunnelCommand } = await import('../gateway-ssh-tunnel.js');\n registerGatewaySshTunnelCommand(cmd, ctx);\n return;\n }\n if (subcommand && isKnownGatewaySubcommand(subcommand)) {\n const loader = GATEWAY_SUBCOMMAND_LOADERS[subcommand];\n if (loader) {\n cmd.addCommand(await loader());\n }\n return;\n }\n if (shouldEagerLoadGatewaySubcommands(ctx.argv)) {\n await attachAllGatewaySubcommands(cmd, ctx);\n }\n}\n"],"mappings":";;;AAWA,MAAM,6BAAsE;CAC1E,OAAO,aAAa,MAAM,OAAO,eAAe,oBAAoB;CACpE,QAAQ,aAAa,MAAM,OAAO,gBAAgB,qBAAqB;CACvE,QAAQ,aAAa,MAAM,OAAO,gBAAgB,qBAAqB;CACvE,MAAM,aAAa,MAAM,OAAO,cAAc,mBAAmB;CACjE,OAAO,aAAa,MAAM,OAAO,eAAe,oBAAoB;CACpE,MAAM,aAAa,MAAM,OAAO,cAAc,mBAAmB;CACjE,SAAS,aAAa,MAAM,OAAO,iBAAiB,sBAAsB;CAC1E,MAAM,aAAa,MAAM,OAAO,cAAc,mBAAmB;CACjE,SAAS,aAAa,MAAM,OAAO,iBAAiB,sBAAsB;CAC3E;AAED,eAAe,4BAA4B,KAAc,KAAgC;AACvF,MAAK,MAAM,UAAU,OAAO,OAAO,2BAA2B,CAC5D,KAAI,WAAW,MAAM,QAAQ,CAAC;CAEhC,MAAM,EAAE,oCAAoC,MAAM,OAAO;AACzD,iCAAgC,KAAK,IAAI;;AAG3C,SAAS,kCAAkC,MAAyB;AAElE,KAAI,CADe,yBAAyB,KAC7B,CAAC,iBACd,QAAO;AAGT,QADoB,6BAA6B,KAC/B,KAAK,KAAA;;AAGzB,eAAsB,6BAA6B,KAAc,KAAgC;CAC/F,MAAM,aAAa,6BAA6B,IAAI,KAAK;AACzD,KAAI,eAAe,cAAc;EAC/B,MAAM,EAAE,oCAAoC,MAAM,OAAO;AACzD,kCAAgC,KAAK,IAAI;AACzC;;AAEF,KAAI,cAAc,yBAAyB,WAAW,EAAE;EACtD,MAAM,SAAS,2BAA2B;AAC1C,MAAI,OACF,KAAI,WAAW,MAAM,QAAQ,CAAC;AAEhC;;AAEF,KAAI,kCAAkC,IAAI,KAAK,CAC7C,OAAM,4BAA4B,KAAK,IAAI"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { init_paths, resolveConfigPath } from "../../../config/paths.js";
|
|
2
|
-
import { getContextWithOpts } from "../../
|
|
2
|
+
import { getContextWithOpts } from "../../context.js";
|
|
3
3
|
import crypto from "crypto";
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
//#region src/cli/commands/gateway/token.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.js","names":[],"sources":["../../../../../src/cli/commands/gateway/token.ts"],"sourcesContent":["import { Command } from 'commander';\nimport crypto from 'crypto';\nimport { resolveConfigPath } from '../../../config/paths.js';\nimport { getContextWithOpts } from '../../
|
|
1
|
+
{"version":3,"file":"token.js","names":[],"sources":["../../../../../src/cli/commands/gateway/token.ts"],"sourcesContent":["import { Command } from 'commander';\nimport crypto from 'crypto';\nimport { resolveConfigPath } from '../../../config/paths.js';\nimport { getContextWithOpts } from '../../context.js';\n\n/**\n * Create the token subcommand for managing gateway authentication token.\n */\nexport function createTokenCommand(): Command {\n return new Command('token')\n .description('Manage gateway authentication token')\n .option('--generate', 'Generate a new token and save to config')\n .option('--mode <mode>', 'Auth mode: token or none', 'token')\n .action(async (options) => {\n const ctx = getContextWithOpts();\n const configPath = ctx.configPath || resolveConfigPath();\n const [{ loadConfig, saveConfig }, { createLogger }] = await Promise.all([\n import('../../../config/index.js'),\n import('../../../utils/logger.js'),\n ]);\n const log = createLogger('GatewayTokenCommand');\n\n try {\n const config = loadConfig(configPath);\n\n if (options.generate) {\n const newToken = crypto.randomBytes(24).toString('hex');\n\n config.gateway = config.gateway || {};\n config.gateway.auth = {\n mode: 'token',\n token: newToken,\n };\n\n await saveConfig(config, configPath);\n\n console.log('✅ Generated new gateway token:');\n console.log('');\n console.log(` ${newToken}`);\n console.log('');\n console.log('📝 Saved to config file. Use this token in the X-Api-Key header or as:');\n console.log(` xopc gateway --token ${newToken}`);\n console.log('');\n console.log('Or set environment variable:');\n console.log(` export XOPC_GATEWAY_TOKEN=${newToken}`);\n process.exit(0);\n } else {\n const currentToken = config.gateway?.auth?.token;\n const mode = config.gateway?.auth?.mode || 'token';\n\n if (mode === 'none') {\n console.log('⚠️ Gateway authentication is disabled (mode: none)');\n console.log('');\n console.log('To enable authentication, run:');\n console.log(' xopc gateway token --generate');\n } else if (currentToken) {\n const tokenPreview = `${currentToken.slice(0, 8)}...${currentToken.slice(-8)}`;\n console.log('🔑 Current gateway token:');\n console.log('');\n console.log(` ${currentToken}`);\n console.log('');\n console.log(`Preview: ${tokenPreview}`);\n console.log('');\n console.log('Usage:');\n console.log(` xopc gateway --token ${currentToken}`);\n console.log('');\n console.log('Or set environment variable:');\n console.log(` export XOPC_GATEWAY_TOKEN=${currentToken}`);\n } else {\n console.log('⚠️ No token configured. A token will be auto-generated on startup.');\n console.log('');\n console.log('To set a persistent token, run:');\n console.log(' xopc gateway token --generate');\n }\n process.exit(0);\n }\n } catch (error) {\n log.error({ err: error }, 'Failed to manage token');\n process.exit(1);\n }\n });\n}\n"],"mappings":";;;;;YAE6D;;;;AAM7D,SAAgB,qBAA8B;AAC5C,QAAO,IAAI,QAAQ,QAAQ,CACxB,YAAY,sCAAsC,CAClD,OAAO,cAAc,0CAA0C,CAC/D,OAAO,iBAAiB,4BAA4B,QAAQ,CAC5D,OAAO,OAAO,YAAY;EAEzB,MAAM,aADM,oBACU,CAAC,cAAc,mBAAmB;EACxD,MAAM,CAAC,EAAE,YAAY,cAAc,EAAE,kBAAkB,MAAM,QAAQ,IAAI,CACvE,OAAO,6BACP,OAAO,4BACR,CAAC;EACF,MAAM,MAAM,aAAa,sBAAsB;AAE/C,MAAI;GACF,MAAM,SAAS,WAAW,WAAW;AAErC,OAAI,QAAQ,UAAU;IACpB,MAAM,WAAW,OAAO,YAAY,GAAG,CAAC,SAAS,MAAM;AAEvD,WAAO,UAAU,OAAO,WAAW,EAAE;AACrC,WAAO,QAAQ,OAAO;KACpB,MAAM;KACN,OAAO;KACR;AAED,UAAM,WAAW,QAAQ,WAAW;AAEpC,YAAQ,IAAI,iCAAiC;AAC7C,YAAQ,IAAI,GAAG;AACf,YAAQ,IAAI,MAAM,WAAW;AAC7B,YAAQ,IAAI,GAAG;AACf,YAAQ,IAAI,yEAAyE;AACrF,YAAQ,IAAI,2BAA2B,WAAW;AAClD,YAAQ,IAAI,GAAG;AACf,YAAQ,IAAI,+BAA+B;AAC3C,YAAQ,IAAI,gCAAgC,WAAW;AACvD,YAAQ,KAAK,EAAE;UACV;IACL,MAAM,eAAe,OAAO,SAAS,MAAM;AAG3C,SAFa,OAAO,SAAS,MAAM,QAAQ,aAE9B,QAAQ;AACnB,aAAQ,IAAI,sDAAsD;AAClE,aAAQ,IAAI,GAAG;AACf,aAAQ,IAAI,iCAAiC;AAC7C,aAAQ,IAAI,mCAAmC;eACtC,cAAc;KACvB,MAAM,eAAe,GAAG,aAAa,MAAM,GAAG,EAAE,CAAC,KAAK,aAAa,MAAM,GAAG;AAC5E,aAAQ,IAAI,4BAA4B;AACxC,aAAQ,IAAI,GAAG;AACf,aAAQ,IAAI,MAAM,eAAe;AACjC,aAAQ,IAAI,GAAG;AACf,aAAQ,IAAI,YAAY,eAAe;AACvC,aAAQ,IAAI,GAAG;AACf,aAAQ,IAAI,SAAS;AACrB,aAAQ,IAAI,2BAA2B,eAAe;AACtD,aAAQ,IAAI,GAAG;AACf,aAAQ,IAAI,+BAA+B;AAC3C,aAAQ,IAAI,gCAAgC,eAAe;WACtD;AACL,aAAQ,IAAI,sEAAsE;AAClF,aAAQ,IAAI,GAAG;AACf,aAAQ,IAAI,kCAAkC;AAC9C,aAAQ,IAAI,mCAAmC;;AAEjD,YAAQ,KAAK,EAAE;;WAEV,OAAO;AACd,OAAI,MAAM,EAAE,KAAK,OAAO,EAAE,yBAAyB;AACnD,WAAQ,KAAK,EAAE;;GAEjB"}
|