@xopcai/xopc 0.0.82 → 0.0.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +2 -3
- package/dist/extensions/feishu/src/outbound/media-load.js.map +1 -1
- package/dist/extensions/feishu/src/schema/config-schema.d.ts +6 -6
- package/dist/extensions/telegram/src/config-schema.d.ts +6 -6
- package/dist/extensions/telegram/src/plugin.d.ts +1 -1
- package/dist/extensions/telegram/src/plugin.js +1 -1
- package/dist/extensions/telegram/src/routing-integration.js +2 -2
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/api/api.js +3 -3
- package/dist/extensions/weixin/src/auth/accounts.js +1 -1
- package/dist/extensions/weixin/src/cdn/upload.js +1 -1
- package/dist/extensions/weixin/src/config-schema.d.ts +3 -3
- package/dist/extensions/weixin/src/media/data-url.js +1 -1
- package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
- package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.js +1 -1
- package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
- package/dist/gateway/static/root/assets/agents-CrpYTHJS.js +222 -0
- package/dist/gateway/static/root/assets/{apps-page-pJ27dsqn.js → apps-page-1mcKh5Rh.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-zd6QNKPx.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-D1KYmOmi.js → channels-status-swr-uRAuhiUo.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-api-Y2wfSJVI.js → cron-api-O2Q_ruV6.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-page-B97KU_RG.js → cron-page-By09AQD-.js} +1 -1
- package/dist/gateway/static/root/assets/{dist-CboA_Css.js → dist-BpQxde0t.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DN_zNmpo.js → extension-debug-page-CY27wj_p.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BUXtOzv5.js → extension-page-C-Ed5ZmP.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-C2dX4KCW.js → extension-settings-page-raLux7E7.js} +1 -1
- package/dist/gateway/static/root/assets/fetch-2iRFmd3n.js +3 -0
- package/dist/gateway/static/root/assets/{field-primitives-B9rOLqdm.js → field-primitives-fa_hiQcX.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-DvfiRVrc.js → heartbeat-config-api-BVl5VHvL.js} +1 -1
- package/dist/gateway/static/root/assets/index-BuFldCsB.css +1 -0
- package/dist/gateway/static/root/assets/{index-DQuaMye9.js → index-Y-iqo-gL.js} +94 -85
- package/dist/gateway/static/root/assets/{logs-page-BQuBpHcc.js → logs-page-BdH2n7ZW.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-Vpchzdp-.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-2Yu-FASs.js → settings-form-section-Kk1yAGBl.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-KBm0u6Dz.js +3 -0
- package/dist/gateway/static/root/assets/skills-page-BjeXXaOn.js +2 -0
- package/dist/gateway/static/root/assets/{theme-store-DnwYutiX.js → theme-store-D01dJt95.js} +1 -1
- package/dist/gateway/static/root/assets/{utils-D2Gn2qod.js → utils-DpTxN4AF.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-CwO8Cf01.js +1 -0
- package/dist/gateway/static/root/index.html +4 -4
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-instance-gateway.d.ts +50 -0
- package/dist/src/agent/agent-instance-gateway.js +1 -0
- package/dist/src/agent/agent-manager.d.ts +20 -14
- package/dist/src/agent/agent-manager.js +74 -186
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/background-review/coordinator.d.ts +61 -0
- package/dist/src/agent/background-review/coordinator.js +120 -0
- package/dist/src/agent/background-review/coordinator.js.map +1 -0
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
- package/dist/src/agent/child-agent-factory.d.ts +14 -0
- package/dist/src/agent/child-agent-factory.js +2 -8
- package/dist/src/agent/child-agent-factory.js.map +1 -1
- package/dist/src/agent/context/workspace-seed.js +3 -3
- package/dist/src/agent/embedded/index.d.ts +1 -2
- package/dist/src/agent/embedded/index.js +2 -3
- package/dist/src/agent/embedded/run-for-session.d.ts +2 -2
- package/dist/src/agent/embedded/run-for-session.js.map +1 -1
- package/dist/src/agent/embedded/runs.d.ts +32 -0
- package/dist/src/agent/embedded/runs.js +79 -19
- package/dist/src/agent/embedded/runs.js.map +1 -1
- package/dist/src/agent/embedded/session-manager-cache.d.ts +14 -0
- package/dist/src/agent/embedded/session-manager-cache.js +32 -11
- package/dist/src/agent/embedded/session-manager-cache.js.map +1 -1
- package/dist/src/agent/embedded/session-runner.d.ts +37 -7
- package/dist/src/agent/embedded/session-runner.js +184 -153
- package/dist/src/agent/embedded/session-runner.js.map +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.d.ts +57 -9
- package/dist/src/agent/embedded/session-tool-result-guard.js +159 -67
- package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
- package/dist/src/agent/goals/goal-run-store.js +4 -4
- package/dist/src/agent/goals/persistent-goal-service.d.ts +84 -0
- package/dist/src/agent/goals/persistent-goal-service.js +139 -0
- package/dist/src/agent/goals/persistent-goal-service.js.map +1 -0
- package/dist/src/agent/goals/post-turn.js +2 -2
- package/dist/src/agent/goals/state.d.ts +1 -1
- package/dist/src/agent/goals/state.js.map +1 -1
- package/dist/src/agent/image/load-image-media.js +1 -1
- package/dist/src/agent/inbound/inbound-loop.d.ts +77 -0
- package/dist/src/agent/inbound/inbound-loop.js +226 -0
- package/dist/src/agent/inbound/inbound-loop.js.map +1 -0
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +80 -0
- package/dist/src/agent/inbound/turn-dispatcher.js +138 -0
- package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -0
- package/dist/src/agent/ipc/bus.js +1 -1
- package/dist/src/agent/ipc/inbox.js +2 -2
- package/dist/src/agent/ipc/socket.js +1 -1
- package/dist/src/agent/lifecycle/handlers/compaction.d.ts +1 -1
- package/dist/src/agent/lifecycle/handlers/compaction.js.map +1 -1
- package/dist/src/agent/lifecycle/manager.d.ts +1 -1
- package/dist/src/agent/lifecycle/manager.js.map +1 -1
- package/dist/src/agent/lifecycle/types.d.ts +1 -1
- package/dist/src/agent/memory/builtin-memory-store.js +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
- package/dist/src/agent/memory/dreaming/events.js +1 -1
- package/dist/src/agent/memory/dreaming/last-run.js +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
- package/dist/src/agent/memory/dreaming/preview.js +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.d.ts +12 -2
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js.map +1 -1
- package/dist/src/agent/memory/index.js +3 -3
- package/dist/src/agent/memory/plugin-discovery.js +1 -1
- package/dist/src/agent/memory/prefetch-coordinator.d.ts +37 -0
- package/dist/src/agent/memory/prefetch-coordinator.js +45 -0
- package/dist/src/agent/memory/prefetch-coordinator.js.map +1 -0
- package/dist/src/agent/messaging/command-handler.d.ts +5 -1
- package/dist/src/agent/messaging/command-handler.js +24 -96
- package/dist/src/agent/messaging/command-handler.js.map +1 -1
- package/dist/src/agent/messaging/index.d.ts +1 -0
- package/dist/src/agent/messaging/index.js +2 -1
- package/dist/src/agent/messaging/message-router.d.ts +1 -1
- package/dist/src/agent/messaging/message-router.js.map +1 -1
- package/dist/src/agent/messaging/outbound-coordinator.d.ts +82 -0
- package/dist/src/agent/messaging/outbound-coordinator.js +123 -0
- package/dist/src/agent/messaging/outbound-coordinator.js.map +1 -0
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/orchestration/agent-event-handler.d.ts +36 -33
- package/dist/src/agent/orchestration/agent-event-handler.js +212 -174
- package/dist/src/agent/orchestration/agent-event-handler.js.map +1 -1
- package/dist/src/agent/orchestration/agent-orchestrator.d.ts +4 -4
- package/dist/src/agent/orchestration/agent-orchestrator.js +4 -8
- package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
- package/dist/src/agent/orchestration/index.d.ts +1 -1
- package/dist/src/agent/orchestration/index.js +2 -2
- package/dist/src/agent/prompt/service-prompt-builder.js +4 -4
- package/dist/src/agent/reply/post-compaction-context.js +1 -1
- package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
- package/dist/src/agent/sandbox/path-policy.js +1 -1
- package/dist/src/agent/service/async-queue.d.ts +20 -0
- package/dist/src/agent/service/async-queue.js +53 -0
- package/dist/src/agent/service/async-queue.js.map +1 -0
- package/dist/src/agent/service/build-direct-message-content.d.ts +2 -2
- package/dist/src/agent/service/build-direct-message-content.js.map +1 -1
- package/dist/src/agent/service/direct-turn-helpers.d.ts +70 -0
- package/dist/src/agent/service/direct-turn-helpers.js +90 -0
- package/dist/src/agent/service/direct-turn-helpers.js.map +1 -0
- package/dist/src/agent/service/process-direct-one-shot.d.ts +3 -3
- package/dist/src/agent/service/process-direct-one-shot.js +17 -34
- package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.d.ts +2 -2
- package/dist/src/agent/service/process-direct-streaming.js +122 -168
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service/webchat-tts.d.ts +2 -2
- package/dist/src/agent/service/webchat-tts.js +1 -1
- package/dist/src/agent/service/webchat-tts.js.map +1 -1
- package/dist/src/agent/service.d.ts +62 -167
- package/dist/src/agent/service.js +177 -786
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/session/index.d.ts +4 -0
- package/dist/src/agent/session/index.js +5 -1
- package/dist/src/agent/session/session-config-service.d.ts +68 -0
- package/dist/src/agent/session/session-config-service.js +172 -0
- package/dist/src/agent/session/session-config-service.js.map +1 -0
- package/dist/src/agent/session/session-context.d.ts +27 -19
- package/dist/src/agent/session/session-context.js +39 -24
- package/dist/src/agent/session/session-context.js.map +1 -1
- package/dist/src/agent/session/session-hydrator.d.ts +42 -0
- package/dist/src/agent/session/session-hydrator.js +66 -0
- package/dist/src/agent/session/session-hydrator.js.map +1 -0
- package/dist/src/agent/session/session-inspector.d.ts +80 -0
- package/dist/src/agent/session/session-inspector.js +119 -0
- package/dist/src/agent/session/session-inspector.js.map +1 -0
- package/dist/src/agent/session/session-state-bag.d.ts +83 -0
- package/dist/src/agent/session/session-state-bag.js +192 -0
- package/dist/src/agent/session/session-state-bag.js.map +1 -0
- package/dist/src/agent/skills/config.js +1 -1
- package/dist/src/agent/skills/hub-hash.js +2 -2
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +2 -2
- package/dist/src/agent/skills/index.d.ts +0 -2
- package/dist/src/agent/skills/index.js +3 -5
- package/dist/src/agent/skills/index.js.map +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js +11 -6
- package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js.map +1 -1
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js +35 -7
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js.map +1 -1
- package/dist/src/agent/skills/scanner.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +2 -2
- package/dist/src/agent/skills/skill-manager.js +1 -1
- package/dist/src/agent/tools/browser/tool/browser-use-tool.d.ts +7 -0
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js +37 -0
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
- package/dist/src/agent/tools/delegate-tool.d.ts +7 -0
- package/dist/src/agent/tools/delegate-tool.js +2 -1
- package/dist/src/agent/tools/delegate-tool.js.map +1 -1
- package/dist/src/agent/tools/dreaming-tool.js +1 -1
- package/dist/src/agent/tools/executor.d.ts +34 -15
- package/dist/src/agent/tools/executor.js +44 -79
- package/dist/src/agent/tools/executor.js.map +1 -1
- package/dist/src/agent/tools/factory.d.ts +6 -0
- package/dist/src/agent/tools/factory.js +63 -4
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +1 -1
- package/dist/src/agent/tools/send-media.js +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js +1 -1
- package/dist/src/agent/tools/skills-tools.js +1 -1
- package/dist/src/agent/tools/tts-tool.js +1 -1
- package/dist/src/agent/tools/write.js +1 -1
- package/dist/src/agent/workspace-runtime/registry.d.ts +48 -0
- package/dist/src/agent/workspace-runtime/registry.js +59 -0
- package/dist/src/agent/workspace-runtime/registry.js.map +1 -0
- package/dist/src/auth/credentials.js +3 -3
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/browser/cdp-local-launcher.js +4 -3
- package/dist/src/browser/cdp-local-launcher.js.map +1 -1
- package/dist/src/browser/index.d.ts +1 -0
- package/dist/src/browser/index.js +2 -1
- package/dist/src/browser/manager.js +3 -2
- package/dist/src/browser/manager.js.map +1 -1
- package/dist/src/browser/providers/browser-ext-install.js +4 -4
- package/dist/src/browser/providers/browser-use.js +2 -1
- package/dist/src/browser/providers/browser-use.js.map +1 -1
- package/dist/src/browser/providers/browserbase.js +2 -1
- package/dist/src/browser/providers/browserbase.js.map +1 -1
- package/dist/src/browser/providers/cloakbrowser.js +7 -6
- package/dist/src/browser/providers/cloakbrowser.js.map +1 -1
- package/dist/src/browser/providers/playwright-doctor.d.ts +2 -0
- package/dist/src/browser/providers/playwright-doctor.js +7 -3
- package/dist/src/browser/providers/playwright-doctor.js.map +1 -1
- package/dist/src/browser/readiness.d.ts +33 -0
- package/dist/src/browser/readiness.js +138 -0
- package/dist/src/browser/readiness.js.map +1 -0
- package/dist/src/browser/stealth.js +2 -2
- package/dist/src/channels/attachments/inbound-persist.js +1 -1
- package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
- package/dist/src/channels/channel-domain.d.ts +1 -1
- package/dist/src/channels/config-helpers.d.ts +1 -1
- package/dist/src/channels/config-helpers.js.map +1 -1
- package/dist/src/channels/heartbeat-scheduler.d.ts +40 -0
- package/dist/src/channels/heartbeat-scheduler.js +94 -0
- package/dist/src/channels/heartbeat-scheduler.js.map +1 -0
- package/dist/src/channels/lifecycle-supervisor.d.ts +81 -0
- package/dist/src/channels/lifecycle-supervisor.js +263 -0
- package/dist/src/channels/lifecycle-supervisor.js.map +1 -0
- package/dist/src/channels/manager.d.ts +34 -68
- package/dist/src/channels/manager.js +107 -477
- package/dist/src/channels/manager.js.map +1 -1
- package/dist/src/channels/outbound/deliver.d.ts +1 -1
- package/dist/src/channels/outbound/deliver.js.map +1 -1
- package/dist/src/channels/outbound/persist-store.js +1 -1
- package/dist/src/channels/outbound-sender.d.ts +51 -0
- package/dist/src/channels/outbound-sender.js +125 -0
- package/dist/src/channels/outbound-sender.js.map +1 -0
- package/dist/src/channels/pairing/allow-from-file.js +1 -1
- package/dist/src/channels/pairing/pairing-service.d.ts +3 -10
- package/dist/src/channels/pairing/pairing-service.js.map +1 -1
- package/dist/src/channels/pairing/pairing-store.js +2 -2
- package/dist/src/channels/pairing/pairing-types.d.ts +15 -0
- package/dist/src/channels/pairing/pairing-types.js +1 -0
- package/dist/src/channels/plugin-registry.d.ts +22 -0
- package/dist/src/channels/plugin-registry.js +44 -0
- package/dist/src/channels/plugin-registry.js.map +1 -0
- package/dist/src/channels/plugin-types.d.ts +1 -1
- package/dist/src/channels/plugins/types.adapters.d.ts +2 -2
- package/dist/src/channels/security-helpers.d.ts +1 -1
- package/dist/src/channels/security-helpers.js.map +1 -1
- package/dist/src/channels/setup-wizard.d.ts +1 -1
- package/dist/src/chat-commands/builtins/config.js +2 -2
- package/dist/src/chat-commands/context.js +1 -1
- package/dist/src/cli/commands/agent/stream-renderer.js +1 -1
- package/dist/src/cli/commands/agent/stream-renderer.js.map +1 -1
- package/dist/src/cli/commands/agent.js +4 -4
- package/dist/src/cli/commands/agent.js.map +1 -1
- package/dist/src/cli/commands/browser-cli-helpers.js +2 -1
- package/dist/src/cli/commands/browser-cli-helpers.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
- package/dist/src/cli/commands/extension-dev.js +2 -2
- package/dist/src/cli/commands/extension-dev.js.map +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +2 -2
- package/dist/src/cli/commands/extension-marketplace.js.map +1 -1
- package/dist/src/cli/commands/extension-pack.js +1 -1
- package/dist/src/cli/commands/gateway/call.js +1 -1
- package/dist/src/cli/commands/gateway/call.js.map +1 -1
- package/dist/src/cli/commands/gateway/health.js +1 -1
- package/dist/src/cli/commands/gateway/health.js.map +1 -1
- package/dist/src/cli/commands/gateway/lifecycle-core.d.ts +31 -12
- package/dist/src/cli/commands/gateway/lifecycle-core.js +167 -116
- package/dist/src/cli/commands/gateway/lifecycle-core.js.map +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.d.ts +11 -0
- package/dist/src/cli/commands/gateway/lifecycle.js +102 -0
- package/dist/src/cli/commands/gateway/lifecycle.js.map +1 -0
- package/dist/src/cli/commands/gateway/logs.js +1 -1
- package/dist/src/cli/commands/gateway/logs.js.map +1 -1
- package/dist/src/cli/commands/gateway/probe.js +1 -1
- package/dist/src/cli/commands/gateway/probe.js.map +1 -1
- package/dist/src/cli/commands/gateway/restart-health.d.ts +12 -0
- package/dist/src/cli/commands/gateway/restart-health.js +45 -1
- package/dist/src/cli/commands/gateway/restart-health.js.map +1 -1
- package/dist/src/cli/commands/gateway/restart.js +3 -3
- package/dist/src/cli/commands/gateway/restart.js.map +1 -1
- package/dist/src/cli/commands/gateway/run-foreground.d.ts +0 -1
- package/dist/src/cli/commands/gateway/run-foreground.js +0 -35
- package/dist/src/cli/commands/gateway/run-foreground.js.map +1 -1
- package/dist/src/cli/commands/gateway/service.js +1 -1
- package/dist/src/cli/commands/gateway/service.js.map +1 -1
- package/dist/src/cli/commands/gateway/shared.d.ts +3 -0
- package/dist/src/cli/commands/gateway/shared.js +54 -0
- package/dist/src/cli/commands/gateway/shared.js.map +1 -0
- package/dist/src/cli/commands/gateway/status.js +1 -1
- package/dist/src/cli/commands/gateway/status.js.map +1 -1
- package/dist/src/cli/commands/gateway/stop.js +2 -2
- package/dist/src/cli/commands/gateway/stop.js.map +1 -1
- package/dist/src/cli/commands/gateway/token.js +1 -1
- package/dist/src/cli/commands/gateway/token.js.map +1 -1
- package/dist/src/cli/commands/gateway.js +5 -5
- package/dist/src/cli/commands/gateway.js.map +1 -1
- package/dist/src/cli/commands/image.js +2 -2
- package/dist/src/cli/commands/image.js.map +1 -1
- package/dist/src/cli/commands/init.js +4 -4
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/models.js.map +1 -1
- package/dist/src/cli/commands/onboard/gateway.d.ts +0 -8
- package/dist/src/cli/commands/onboard/gateway.js +48 -49
- package/dist/src/cli/commands/onboard/gateway.js.map +1 -1
- package/dist/src/cli/commands/onboard.js +9 -64
- package/dist/src/cli/commands/onboard.js.map +1 -1
- package/dist/src/cli/commands/session/utils.js +1 -1
- package/dist/src/cli/commands/session/utils.js.map +1 -1
- package/dist/src/cli/commands/skills.js +1 -1
- package/dist/src/cli/commands/tailscale.js +1 -1
- package/dist/src/cli/commands/tailscale.js.map +1 -1
- package/dist/src/cli/context.d.ts +20 -0
- package/dist/src/cli/context.js +23 -0
- package/dist/src/cli/context.js.map +1 -0
- package/dist/src/cli/extension-cli-register.js +3 -3
- package/dist/src/cli/gateway-run-argv.js +1 -4
- package/dist/src/cli/gateway-run-argv.js.map +1 -1
- package/dist/src/cli/gateway-run-fast-path.js +1 -1
- package/dist/src/cli/gateway-run-fast-path.js.map +1 -1
- package/dist/src/cli/index.d.ts +1 -7
- package/dist/src/cli/index.js +4 -6
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -2
- package/dist/src/config/commands.flags.d.ts +3 -0
- package/dist/src/config/commands.flags.js +11 -0
- package/dist/src/config/commands.flags.js.map +1 -0
- package/dist/src/config/index.d.ts +1 -0
- package/dist/src/config/index.js +6 -5
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/profile.js +2 -2
- package/dist/src/config/schema.d.ts +11 -4
- package/dist/src/config/schema.js +13 -12
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/workspace-path-helpers.d.ts +15 -0
- package/dist/src/config/workspace-path-helpers.js +14 -0
- package/dist/src/config/workspace-path-helpers.js.map +1 -0
- package/dist/src/cron/executor.js +4 -4
- package/dist/src/cron/executor.js.map +1 -1
- package/dist/src/cron/persistence.js +1 -1
- package/dist/src/cron/run-log-store.js +1 -1
- package/dist/src/daemon/index.d.ts +0 -1
- package/dist/src/daemon/index.js +1 -2
- package/dist/src/daemon/install-plan.js +3 -2
- package/dist/src/daemon/install-plan.js.map +1 -1
- package/dist/src/daemon/launchd.js +2 -2
- package/dist/src/daemon/systemd.js +2 -2
- package/dist/src/daemon/types.d.ts +0 -6
- package/dist/src/extensions/api.d.ts +1 -1
- package/dist/src/extensions/api.js +2 -2
- package/dist/src/extensions/api.js.map +1 -1
- package/dist/src/extensions/bundle-mcp.js +1 -1
- package/dist/src/extensions/discover-extensions.js +1 -1
- package/dist/src/extensions/extension-registry-impl.d.ts +51 -0
- package/dist/src/extensions/extension-registry-impl.js +117 -0
- package/dist/src/extensions/extension-registry-impl.js.map +1 -0
- package/dist/src/extensions/health.js +1 -1
- package/dist/src/extensions/index.js +3 -2
- package/dist/src/extensions/loader.d.ts +3 -43
- package/dist/src/extensions/loader.js +3 -110
- package/dist/src/extensions/loader.js.map +1 -1
- package/dist/src/extensions/lockfile.js +2 -2
- package/dist/src/extensions/sdk/index.js +2 -1
- package/dist/src/extensions/sdk/index.js.map +1 -1
- package/dist/src/extensions/types/events.d.ts +7 -1
- package/dist/src/gateway/agents-admin.js +2 -2
- package/dist/src/gateway/file-path-classifier.js +2 -2
- package/dist/src/gateway/heartbeat/service.js +2 -2
- package/dist/src/gateway/heartbeat/service.js.map +1 -1
- package/dist/src/gateway/hono/app.js +5 -53
- package/dist/src/gateway/hono/app.js.map +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +1 -1
- package/dist/src/gateway/hono/lib/static-ui.js +2 -2
- package/dist/src/gateway/hono/middleware/auth.d.ts +5 -14
- package/dist/src/gateway/hono/middleware/auth.js +89 -126
- package/dist/src/gateway/hono/middleware/auth.js.map +1 -1
- package/dist/src/gateway/hono/middleware/logger.js +1 -1
- package/dist/src/gateway/hono/middleware/logger.js.map +1 -1
- package/dist/src/gateway/hono/middleware/strict-rate-limit.d.ts +14 -0
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js +62 -0
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js.map +1 -0
- package/dist/src/gateway/hono/oauth.js +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +4 -4
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js.map +1 -1
- package/dist/src/gateway/hono/routes/browser.d.ts +20 -0
- package/dist/src/gateway/hono/routes/browser.js +626 -0
- package/dist/src/gateway/hono/routes/browser.js.map +1 -0
- package/dist/src/gateway/hono/routes/commands-skills.js +13 -13
- package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/agents.d.ts +18 -0
- package/dist/src/gateway/hono/routes/config-patch/agents.js +418 -0
- package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -0
- package/dist/src/gateway/hono/routes/config-patch/channels.d.ts +12 -0
- package/dist/src/gateway/hono/routes/config-patch/channels.js +186 -0
- package/dist/src/gateway/hono/routes/config-patch/channels.js.map +1 -0
- package/dist/src/gateway/hono/routes/config-patch/gateway.d.ts +18 -0
- package/dist/src/gateway/hono/routes/config-patch/gateway.js +264 -0
- package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -0
- package/dist/src/gateway/hono/routes/config-patch/index.d.ts +9 -0
- package/dist/src/gateway/hono/routes/config-patch/index.js +6 -0
- package/dist/src/gateway/hono/routes/config-patch/misc.d.ts +23 -0
- package/dist/src/gateway/hono/routes/config-patch/misc.js +139 -0
- package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -0
- package/dist/src/gateway/hono/routes/config-patch/result.d.ts +18 -0
- package/dist/src/gateway/hono/routes/config-patch/result.js +13 -0
- package/dist/src/gateway/hono/routes/config-patch/result.js.map +1 -0
- package/dist/src/gateway/hono/routes/config.js +20 -1764
- package/dist/src/gateway/hono/routes/config.js.map +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +2 -3
- package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
- package/dist/src/gateway/hono/routes/host-fs.js +1 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +10 -5
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/mcp.js +1 -2
- package/dist/src/gateway/hono/routes/mcp.js.map +1 -1
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +32 -32
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/hono/routes/shares.js +4 -4
- package/dist/src/gateway/hono/routes/shares.js.map +1 -1
- package/dist/src/gateway/hono/routes/tunnel.js +1 -1
- package/dist/src/gateway/hono/routes/tunnel.js.map +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +6 -7
- package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
- package/dist/src/gateway/hono/sse.js +2 -2
- package/dist/src/gateway/index.d.ts +1 -1
- package/dist/src/gateway/index.js +4 -2
- package/dist/src/gateway/lock.js +3 -3
- package/dist/src/gateway/rate-limit/auth-policy.d.ts +34 -0
- package/dist/src/gateway/rate-limit/auth-policy.js +49 -0
- package/dist/src/gateway/rate-limit/auth-policy.js.map +1 -0
- package/dist/src/gateway/rate-limit/buckets.d.ts +63 -0
- package/dist/src/gateway/rate-limit/buckets.js +143 -0
- package/dist/src/gateway/rate-limit/buckets.js.map +1 -0
- package/dist/src/gateway/rate-limit/env-flags.d.ts +13 -0
- package/dist/src/gateway/rate-limit/env-flags.js +16 -0
- package/dist/src/gateway/rate-limit/env-flags.js.map +1 -0
- package/dist/src/gateway/rate-limit/index.d.ts +3 -0
- package/dist/src/gateway/rate-limit/index.js +4 -0
- package/dist/src/gateway/run-loop.d.ts +1 -1
- package/dist/src/gateway/run-loop.js +24 -4
- package/dist/src/gateway/run-loop.js.map +1 -1
- package/dist/src/gateway/runtime-config.js +2 -1
- package/dist/src/gateway/runtime-config.js.map +1 -1
- package/dist/src/gateway/security/audit.js +2 -1
- package/dist/src/gateway/security/audit.js.map +1 -1
- package/dist/src/gateway/security/index.d.ts +0 -1
- package/dist/src/gateway/security/index.js +1 -2
- package/dist/src/gateway/security/loopback.d.ts +13 -0
- package/dist/src/gateway/security/loopback.js +45 -0
- package/dist/src/gateway/security/loopback.js.map +1 -0
- package/dist/src/gateway/service/agent-runner.d.ts +108 -0
- package/dist/src/gateway/service/agent-runner.js +184 -0
- package/dist/src/gateway/service/agent-runner.js.map +1 -0
- package/dist/src/gateway/service/config-coordinator.d.ts +119 -0
- package/dist/src/gateway/service/config-coordinator.js +351 -0
- package/dist/src/gateway/service/config-coordinator.js.map +1 -0
- package/dist/src/gateway/service/marketplace-service.d.ts +85 -0
- package/dist/src/gateway/service/marketplace-service.js +239 -0
- package/dist/src/gateway/service/marketplace-service.js.map +1 -0
- package/dist/src/gateway/service/run-gateway-agent.js +5 -5
- package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
- package/dist/src/gateway/service/sessions-api.d.ts +125 -0
- package/dist/src/gateway/service/sessions-api.js +135 -0
- package/dist/src/gateway/service/sessions-api.js.map +1 -0
- package/dist/src/gateway/service.d.ts +30 -360
- package/dist/src/gateway/service.js +121 -903
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/workspace-fs-file-list.js +1 -1
- package/dist/src/gateway/workspace-heartbeat-path.js +1 -2
- package/dist/src/gateway/workspace-heartbeat-path.js.map +1 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/infra/gateway-process-argv.d.ts +4 -0
- package/dist/src/infra/gateway-process-argv.js +26 -0
- package/dist/src/infra/gateway-process-argv.js.map +1 -0
- package/dist/src/infra/gateway-processes.d.ts +5 -0
- package/dist/src/infra/gateway-processes.js +65 -0
- package/dist/src/infra/gateway-processes.js.map +1 -0
- package/dist/src/infra/rate-limit/failure-limiter.d.ts +50 -0
- package/dist/src/infra/rate-limit/failure-limiter.js +100 -0
- package/dist/src/infra/rate-limit/failure-limiter.js.map +1 -0
- package/dist/src/infra/rate-limit/index.d.ts +5 -0
- package/dist/src/infra/rate-limit/index.js +3 -0
- package/dist/src/infra/rate-limit/keyed-store.d.ts +34 -0
- package/dist/src/infra/rate-limit/keyed-store.js +44 -0
- package/dist/src/infra/rate-limit/keyed-store.js.map +1 -0
- package/dist/src/infra/rate-limit/rate-limiter.d.ts +39 -0
- package/dist/src/infra/rate-limit/rate-limiter.js +65 -0
- package/dist/src/infra/rate-limit/rate-limiter.js.map +1 -0
- package/dist/src/infra/restart.d.ts +21 -0
- package/dist/src/infra/restart.js +122 -0
- package/dist/src/infra/restart.js.map +1 -0
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/infra/update-lock.js +3 -3
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/infra/update-startup.js +2 -2
- package/dist/src/infra/write-file-atomic.js +2 -2
- package/dist/src/mcp/channel-bridge.d.ts +0 -6
- package/dist/src/mcp/channel-bridge.js +1 -5
- package/dist/src/mcp/channel-bridge.js.map +1 -1
- package/dist/src/media-shared/http/ssrf-guard.js +1 -1
- package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/session/config-store.js +2 -2
- package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
- package/dist/src/session/parity/sessions-json-file-read.d.ts +2 -1
- package/dist/src/session/parity/sessions-json-file-read.js.map +1 -1
- package/dist/src/session/parity/sessions-json-file.js +1 -1
- package/dist/src/session/parity/transcript-file-lock.js +2 -2
- package/dist/src/session/parity/transcript-paths.js +1 -1
- package/dist/src/session/search-index-cache.js +1 -1
- package/dist/src/session/search-index.js +1 -1
- package/dist/src/session/session-title.js +1 -1
- package/dist/src/session/store.js +5 -5
- package/dist/src/share/share-rate-limit.d.ts +10 -2
- package/dist/src/share/share-rate-limit.js +33 -42
- package/dist/src/share/share-rate-limit.js.map +1 -1
- package/dist/src/share/share-store.js +3 -3
- package/dist/src/tui/backends/embedded-backend.js +16 -12
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/clipboard-image.js +2 -2
- package/dist/src/tui/extension-host/load-extensions.js +1 -1
- package/dist/src/tui/format-tui-hotkeys.js +1 -1
- package/dist/src/tui/theme-manager.js +1 -1
- package/dist/src/tui/tui-keybindings-file.js +1 -1
- package/dist/src/tui/tui-scoped-models.js +1 -1
- package/dist/src/tui/tui-settings.js +1 -1
- package/dist/src/tui/tui-skills-autocomplete.js +1 -1
- package/dist/src/tui/tui.js +1 -2
- package/dist/src/tui/tui.js.map +1 -1
- package/dist/src/tui/xopc-tui-keybindings.d.ts +0 -1
- package/dist/src/tui/xopc-tui-keybindings.js +1 -2
- package/dist/src/tui/xopc-tui-keybindings.js.map +1 -1
- package/dist/src/tunnel/frpc-binary.js +2 -2
- package/dist/src/tunnel/frpc-config.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/pairing-rate-limit.d.ts +10 -2
- package/dist/src/tunnel/pairing-rate-limit.js +19 -15
- package/dist/src/tunnel/pairing-rate-limit.js.map +1 -1
- package/dist/src/tunnel/tunnel-rate-limit.d.ts +6 -3
- package/dist/src/tunnel/tunnel-rate-limit.js +11 -22
- package/dist/src/tunnel/tunnel-rate-limit.js.map +1 -1
- package/dist/src/tunnel/tunnel-state.js +1 -1
- package/dist/src/utils/logger/audit.js +1 -1
- package/dist/src/utils/logger/log-store.js +1 -1
- package/dist/src/utils/logger/rotation.js +1 -1
- package/dist/src/utils/logger/stats.d.ts +1 -1
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/voice/tts/factory.js +1 -1
- package/dist/src/voice/tts/index.js +2 -2
- package/dist/src/voice/tts/merge-config.js +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +1 -1
- package/dist/src/voice/tts/service.js +1 -1
- package/dist/src/voice/tts/service.js.map +1 -1
- package/dist/src/voice/tts/speak-core.js +1 -1
- package/package.json +10 -5
- package/dist/gateway/static/root/assets/agents-Cqh1ts38.js +0 -222
- package/dist/gateway/static/root/assets/channels-settings-wTiWStg9.js +0 -1
- package/dist/gateway/static/root/assets/fetch-BAAh_kXG.js +0 -3
- package/dist/gateway/static/root/assets/index-C8yHX-AA.css +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BeiFm0Ms.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-RPAz_Wg_.js +0 -3
- package/dist/gateway/static/root/assets/skills-page-Wu4aNWDx.js +0 -2
- package/dist/gateway/static/root/assets/voice-api-key-field-BxIGhhEL.js +0 -1
- package/dist/src/agent/embedded/session-raw-append-message.d.ts +0 -11
- package/dist/src/agent/embedded/session-raw-append-message.js +0 -15
- package/dist/src/agent/embedded/session-raw-append-message.js.map +0 -1
- package/dist/src/agent/embedded/session-tool-result-guard-wrapper.d.ts +0 -15
- package/dist/src/agent/embedded/session-tool-result-guard-wrapper.js +0 -24
- package/dist/src/agent/embedded/session-tool-result-guard-wrapper.js.map +0 -1
- package/dist/src/agent/embedded/session-tool-result-state.d.ts +0 -17
- package/dist/src/agent/embedded/session-tool-result-state.js +0 -26
- package/dist/src/agent/embedded/session-tool-result-state.js.map +0 -1
- package/dist/src/daemon/launchd-restart-handoff.d.ts +0 -25
- package/dist/src/daemon/launchd-restart-handoff.js +0 -132
- package/dist/src/daemon/launchd-restart-handoff.js.map +0 -1
- package/dist/src/gateway/auth-rate-limit.d.ts +0 -71
- package/dist/src/gateway/auth-rate-limit.js +0 -192
- package/dist/src/gateway/auth-rate-limit.js.map +0 -1
- package/dist/src/gateway/restart-handler.d.ts +0 -14
- package/dist/src/gateway/restart-handler.js +0 -64
- package/dist/src/gateway/restart-handler.js.map +0 -1
- package/dist/src/gateway/security/flood-guard.d.ts +0 -28
- package/dist/src/gateway/security/flood-guard.js +0 -42
- package/dist/src/gateway/security/flood-guard.js.map +0 -1
- package/dist/src/infra/rate-limit.d.ts +0 -38
- package/dist/src/infra/rate-limit.js +0 -60
- package/dist/src/infra/rate-limit.js.map +0 -1
- package/dist/src/infra/restart-intent.d.ts +0 -13
- package/dist/src/infra/restart-intent.js +0 -40
- package/dist/src/infra/restart-intent.js.map +0 -1
- package/dist/src/infra/restart-sentinel.d.ts +0 -23
- package/dist/src/infra/restart-sentinel.js +0 -75
- package/dist/src/infra/restart-sentinel.js.map +0 -1
- package/skills/creative/canvas-design/LICENSE.txt +0 -202
- package/skills/creative/canvas-design/SKILL-zh.md +0 -130
- package/skills/creative/canvas-design/SKILL.md +0 -130
- package/skills/creative/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BigShoulders-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Boldonse-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/DMMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/EricaOne-OFL.txt +0 -94
- package/skills/creative/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/GeistMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Gloock-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Italiana-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Jura-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/NationalPark-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Outfit-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/PixelifySans-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/PoiretOne-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/RedHatMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Silkscreen-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/SmoochSans-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Tektur-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/YoungSerif-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { resolveStateDir } from "../config/paths-state.js";
|
|
2
2
|
import { init_paths } from "../config/paths.js";
|
|
3
3
|
import { XOPC_TUI_KEYBINDINGS } from "./xopc-tui-keybindings.js";
|
|
4
|
-
import { join } from "node:path";
|
|
5
4
|
import { existsSync, readFileSync } from "node:fs";
|
|
5
|
+
import { join } from "node:path";
|
|
6
6
|
import { KeybindingsManager } from "@earendil-works/pi-tui";
|
|
7
7
|
//#region src/tui/tui-keybindings-file.ts
|
|
8
8
|
init_paths();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
1
2
|
import { join } from "node:path";
|
|
2
3
|
import { homedir } from "node:os";
|
|
3
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
4
|
//#region src/tui/tui-scoped-models.ts
|
|
5
5
|
const STORE_PATH = join(homedir(), ".xopc", "tui-scoped-models.json");
|
|
6
6
|
function normalizeWorkspaceKey(cwd) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolveStateDir } from "../config/paths-state.js";
|
|
2
2
|
import { init_paths } from "../config/paths.js";
|
|
3
|
-
import { join } from "node:path";
|
|
4
3
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
5
|
//#region src/tui/tui-settings.ts
|
|
6
6
|
init_paths();
|
|
7
7
|
const DEFAULT_TUI_SETTINGS = {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { resolveStateDir } from "../config/paths-state.js";
|
|
2
|
-
import { getWorkspacePath } from "../config/schema.js";
|
|
3
2
|
import { init_paths, resolveBundledSkillsDir } from "../config/paths.js";
|
|
4
3
|
import { loadConfig } from "../config/loader.js";
|
|
5
4
|
import { loadSkills } from "../agent/skills/index.js";
|
|
5
|
+
import { getWorkspacePath } from "../config/workspace-path-helpers.js";
|
|
6
6
|
import "../config/index.js";
|
|
7
7
|
//#region src/tui/tui-skills-autocomplete.ts
|
|
8
8
|
init_paths();
|
package/dist/src/tui/tui.js
CHANGED
|
@@ -2,7 +2,6 @@ import { version } from "../../package.js";
|
|
|
2
2
|
import { appendHistoryToChatLog } from "./chat-history.js";
|
|
3
3
|
import { saveClipboardImageToTempFile } from "./clipboard-image.js";
|
|
4
4
|
import { createXopcTuiKeybindingsManager } from "./tui-keybindings-file.js";
|
|
5
|
-
import "./xopc-tui-keybindings.js";
|
|
6
5
|
import { StreamAssembler } from "./stream-assembler.js";
|
|
7
6
|
import { applyThemeById, getBashExcludeBorderColor, getBashModeBorderColor, getThinkingBorderColor, initTuiTheme } from "./theme-manager.js";
|
|
8
7
|
import { editorTheme, theme } from "./theme.js";
|
|
@@ -27,9 +26,9 @@ import { TuiBottomBar } from "./components/tui-bottom-bar.js";
|
|
|
27
26
|
import { TuiHeader } from "./components/tui-header.js";
|
|
28
27
|
import { loadExtensionsForTuiLocalMode } from "./extension-host/load-extensions.js";
|
|
29
28
|
import { createTuiExtensionRuntime } from "./extension-host/runtime.js";
|
|
29
|
+
import { mkdtempSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
30
30
|
import { join } from "node:path";
|
|
31
31
|
import { tmpdir } from "node:os";
|
|
32
|
-
import { mkdtempSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
33
32
|
import { spawnSync } from "node:child_process";
|
|
34
33
|
import { Container, Loader, ProcessTerminal, TUI, setKeybindings } from "@earendil-works/pi-tui";
|
|
35
34
|
//#region src/tui/tui.ts
|
package/dist/src/tui/tui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tui.js","names":["packageJson.version"],"sources":["../../../src/tui/tui.ts"],"sourcesContent":["import {\n Container,\n Loader,\n ProcessTerminal,\n setKeybindings,\n TUI,\n} from '@earendil-works/pi-tui';\nimport { mkdtempSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { spawnSync } from 'node:child_process';\n\nimport type { ThinkLevel } from '../agent/transcript/thinking-types.js';\nimport type { TuiBackend, TuiEvent, TuiModelChoice } from './tui-backend.js';\nimport { EmbeddedBackend } from './backends/embedded-backend.js';\nimport { GatewaySseBackend } from './backends/gateway-sse-backend.js';\nimport {\n clearPendingToolCallIds,\n DEFAULT_STREAMING_WATCHDOG_MS,\n dispatchAgentSSE,\n} from './tui-agent-events.js';\nimport { ChatLog } from './components/chat-log.js';\nimport { CustomEditor } from './components/custom-editor.js';\nimport { TuiBottomBar } from './components/tui-bottom-bar.js';\nimport { TuiHeader } from './components/tui-header.js';\nimport { StreamAssembler } from './stream-assembler.js';\nimport { createTuiCommandHandler, getSlashCommands } from './tui-commands.js';\nimport { createLocalShellRunner } from './tui-local-shell.js';\nimport {\n createBackspaceDeduper,\n drainAndStopTuiSafely,\n resolveCtrlCAction,\n} from './tui-lifecycle.js';\nimport {\n openModelPickerOverlay,\n openScopedModelsOverlay,\n openSessionPickerOverlay,\n openSettingsOverlay,\n} from './tui-picker-overlay.js';\nimport { createOverlayHandlers } from './tui-overlays.js';\nimport {\n createEditorSubmitHandler,\n createSubmitBurstCoalescer,\n shouldEnableWindowsGitBashPasteFallback,\n} from './tui-submit.js';\nimport { appendHistoryToChatLog } from './chat-history.js';\nimport { installTuiStdioFilter } from './tui-stdio-filter.js';\nimport { withTuiSuspended } from './tui-suspend.js';\nimport { saveClipboardImageToTempFile } from './clipboard-image.js';\nimport {\n applyThemeById,\n getBashExcludeBorderColor,\n getBashModeBorderColor,\n getThinkingBorderColor,\n initTuiTheme,\n} from './theme-manager.js';\nimport { editorTheme, theme } from './theme.js';\nimport { loadTuiSettings, saveTuiSettings, type TuiSettings } from './tui-settings.js';\nimport { resolveFdPath } from './tui-fd-path.js';\nimport packageJson from '../../package.json' with { type: 'json' };\nimport { createInitialState, type TuiOptions, type TuiResult, type TuiState } from './tui-types.js';\nimport { createXopcTuiKeybindingsManager } from './xopc-tui-keybindings.js';\nimport {\n filterModelsForCycle,\n loadScopedModelRefs,\n saveScopedModelRefs,\n} from './tui-scoped-models.js';\nimport { loadExtensionsForTuiLocalMode } from './extension-host/load-extensions.js';\nimport { createTuiExtensionRuntime } from './extension-host/runtime.js';\nimport type { ExtensionRegistryImpl } from '../extensions/loader.js';\n\nexport type { TuiOptions, TuiResult };\n\nexport {\n createBackspaceDeduper,\n drainAndStopTuiSafely,\n type DrainableTui,\n isIgnorableTuiStopError,\n resolveCtrlCAction,\n stopTuiSafely,\n} from './tui-lifecycle.js';\n\nexport { withTuiSuspended } from './tui-suspend.js';\n\nconst THINK_LEVEL_CYCLE: ThinkLevel[] = [\n 'off',\n 'minimal',\n 'low',\n 'medium',\n 'high',\n 'xhigh',\n 'adaptive',\n];\n\nfunction nextThinkLevel(current: string | undefined): ThinkLevel {\n const c = (current ?? 'medium').toLowerCase();\n const idx = THINK_LEVEL_CYCLE.indexOf(c as ThinkLevel);\n const mediumIdx = THINK_LEVEL_CYCLE.indexOf('medium');\n const base = idx >= 0 ? idx : mediumIdx >= 0 ? mediumIdx : 0;\n return THINK_LEVEL_CYCLE[(base + 1) % THINK_LEVEL_CYCLE.length]!;\n}\n\nconst DOUBLE_ESCAPE_WINDOW_MS = 500;\n\nexport async function runTui(opts: TuiOptions): Promise<TuiResult> {\n const stdioFilter = installTuiStdioFilter();\n const restoreStdio = () => stdioFilter.restore();\n\n const isLocalMode = opts.local === true;\n const sessionKey = opts.session ?? 'cli:tui';\n let tuiSettings = loadTuiSettings();\n initTuiTheme({ themeId: opts.theme ?? tuiSettings.theme });\n const state = createInitialState(sessionKey);\n state.scopedModelRefs = loadScopedModelRefs();\n state.showThinking = tuiSettings.showThinking;\n state.toolsExpanded = tuiSettings.toolsExpanded;\n const assembler = new StreamAssembler();\n\n let extensionRegistry: ExtensionRegistryImpl | undefined;\n if (isLocalMode) {\n extensionRegistry = await loadExtensionsForTuiLocalMode();\n }\n\n const client: TuiBackend = isLocalMode\n ? new EmbeddedBackend({ extensionRegistry })\n : new GatewaySseBackend({ url: opts.url ?? 'http://localhost:3120', token: opts.token });\n\n const keybindings = createXopcTuiKeybindingsManager();\n setKeybindings(keybindings);\n\n let modelChoices: TuiModelChoice[] = [];\n const cycleModelChoices = (): TuiModelChoice[] =>\n filterModelsForCycle(modelChoices, state.scopedModelRefs);\n\n const refreshCycleModels = () => {\n bottomBar.invalidate();\n tui.requestRender();\n };\n\n const tui = new TUI(new ProcessTerminal());\n const dedupeBackspace = createBackspaceDeduper();\n tui.addInputListener((data) => {\n const next = dedupeBackspace(data);\n if (next.length === 0) {\n return { consume: true };\n }\n return { data: next };\n });\n\n const header = new TuiHeader(() => ({\n version: packageJson.version ?? 'dev',\n connectionLabel: client.connectionLabel,\n sessionKey: state.currentSessionKey,\n showHints: tuiSettings.showStartupHints,\n }));\n const statusContainer = new Container();\n const bottomBar = new TuiBottomBar(() => state, () => opts.thinking);\n const chatLog = new ChatLog();\n chatLog.setToolsExpanded(state.toolsExpanded);\n const editor = new CustomEditor(tui, editorTheme, keybindings);\n const root = new Container();\n root.addChild(header);\n root.addChild(chatLog);\n root.addChild(statusContainer);\n root.addChild(editor);\n root.addChild(bottomBar);\n tui.addChild(root);\n tui.setFocus(editor);\n\n let isBashMode = false;\n let isBashExcludeContext = false;\n\n const updateEditorBorderColor = () => {\n if (isBashMode) {\n editor.borderColor = isBashExcludeContext\n ? getBashExcludeBorderColor()\n : getBashModeBorderColor();\n } else {\n const level = state.sessionInfo.thinkingLevel ?? opts.thinking ?? 'off';\n editor.borderColor = getThinkingBorderColor(level);\n }\n tui.requestRender();\n };\n\n editor.onChange = (text: string) => {\n const trimmed = text.trimStart();\n const nextExclude = trimmed.startsWith('!!');\n const nextBash = trimmed.startsWith('!');\n if (nextBash !== isBashMode || nextExclude !== isBashExcludeContext) {\n isBashMode = nextBash;\n isBashExcludeContext = nextExclude;\n updateEditorBorderColor();\n }\n };\n\n const { openOverlay, closeOverlay } = createOverlayHandlers(tui, editor);\n\n const slashCommands = getSlashCommands(isLocalMode);\n\n const extensionRuntime = createTuiExtensionRuntime({\n registry: extensionRegistry,\n tui,\n chatLog,\n header,\n bottomBar,\n getState: () => state,\n baseSlashCommands: slashCommands,\n cwd: process.cwd(),\n fdPath: resolveFdPath(),\n openOverlay,\n closeOverlay,\n onInvalidate: () => {\n updateHeader();\n updateFooter();\n tui.requestRender();\n },\n });\n\n editor.setAutocompleteProvider(extensionRuntime.autocompleteProvider);\n\n let statusLoader: Loader | null = null;\n let statusStartedAt: number | null = null;\n let lastActivityStatus = '';\n let elapsedTimerId: ReturnType<typeof setInterval> | null = null;\n const busyStates = new Set(['sending', 'waiting', 'streaming', 'running', 'compacting']);\n\n const syncTerminalProgress = () => {\n if (!tuiSettings.showTerminalProgress) {\n tui.terminal.setProgress(false);\n return;\n }\n tui.terminal.setProgress(busyStates.has(state.activityStatus));\n };\n\n let lastStreamActivityAt = Date.now();\n let streamWatchdogId: ReturnType<typeof setInterval> | null = null;\n\n const touchStreamingActivity = () => {\n lastStreamActivityAt = Date.now();\n };\n\n const formatElapsed = (startMs: number) => {\n const totalSeconds = Math.max(0, Math.floor((Date.now() - startMs) / 1000));\n if (totalSeconds < 60) return `${totalSeconds}s`;\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return `${minutes}m ${seconds}s`;\n };\n\n const renderStatus = () => {\n const isBusy = busyStates.has(state.activityStatus);\n if (isBusy) {\n if (!statusStartedAt || lastActivityStatus !== state.activityStatus) {\n statusStartedAt = Date.now();\n }\n if (!statusLoader) {\n statusContainer.clear();\n statusLoader = new Loader(\n tui,\n (spinner) => theme.accent(spinner),\n (text) => theme.bold(theme.accentSoft(text)),\n '',\n );\n statusContainer.addChild(statusLoader);\n }\n const elapsed = formatElapsed(statusStartedAt);\n statusLoader.setMessage(\n `${state.progressMessage ?? state.activityStatus} • ${elapsed} | ${state.connectionStatus}`,\n );\n if (!elapsedTimerId) {\n elapsedTimerId = setInterval(() => {\n if (statusStartedAt && statusLoader) {\n const el = formatElapsed(statusStartedAt);\n statusLoader.setMessage(\n `${state.progressMessage ?? state.activityStatus} • ${el} | ${state.connectionStatus}`,\n );\n }\n }, 1000);\n }\n } else {\n state.progressMessage = null;\n statusStartedAt = null;\n if (elapsedTimerId) {\n clearInterval(elapsedTimerId);\n elapsedTimerId = null;\n }\n statusLoader?.stop();\n statusLoader = null;\n statusContainer.clear();\n }\n lastActivityStatus = state.activityStatus;\n bottomBar.invalidate();\n syncTerminalProgress();\n tui.requestRender();\n };\n\n const setActivityStatus = (status: string) => {\n state.activityStatus = status as TuiState['activityStatus'];\n renderStatus();\n };\n\n const setConnectionStatus = (text: string) => {\n state.connectionStatus = text;\n renderStatus();\n };\n\n const updateHeader = () => {\n header.invalidate();\n syncTerminalTitle();\n };\n\n const syncTerminalTitle = () => {\n const shortKey =\n state.currentSessionKey.length > 48\n ? `${state.currentSessionKey.slice(0, 45)}…`\n : state.currentSessionKey;\n tui.terminal.setTitle(`xopc · ${shortKey}`);\n };\n\n const updateFooter = () => {\n bottomBar.invalidate();\n };\n\n const refreshModelChoices = async () => {\n try {\n modelChoices = await client.listModels();\n } catch {\n modelChoices = [];\n }\n bottomBar.invalidate();\n tui.requestRender();\n };\n\n const refreshSessionInfo = async () => {\n try {\n state.sessionInfo = await client.getSessionInfo(state.currentSessionKey);\n updateEditorBorderColor();\n updateFooter();\n tui.requestRender();\n } catch {\n // ignore\n }\n };\n\n let finishTui: (() => void) | null = null;\n let exitResult: TuiResult = { exitReason: 'exit' };\n\n const requestExit = () => {\n if (state.exitRequested) return;\n state.exitRequested = true;\n if (elapsedTimerId) {\n clearInterval(elapsedTimerId);\n elapsedTimerId = null;\n }\n if (streamWatchdogId) {\n clearInterval(streamWatchdogId);\n streamWatchdogId = null;\n }\n client.stop();\n tui.terminal.setProgress(false);\n void drainAndStopTuiSafely(tui).then(() => {\n restoreStdio();\n finishTui?.();\n process.exit(0);\n });\n };\n\n const abortActive = async () => {\n if (!state.activeRunId) return;\n const runId = state.activeRunId;\n state.activeRunId = null;\n assembler.drop(runId);\n chatLog.dropAssistant(runId);\n setActivityStatus('idle');\n tui.requestRender();\n await client.abortChat({ sessionKey: state.currentSessionKey, runId }).catch(() => {});\n };\n\n const resolveModelChoiceIndex = (): number => {\n const choices = cycleModelChoices();\n if (choices.length === 0) return -1;\n const p = state.sessionInfo.modelProvider;\n const m = state.sessionInfo.model;\n if (p && m) {\n const byParts = choices.findIndex((x) => x.provider === p && x.id === m);\n if (byParts >= 0) return byParts;\n }\n if (m?.includes('/')) {\n const [a, b] = m.split('/', 2);\n const bySlash = choices.findIndex((x) => x.provider === a && x.id === b);\n if (bySlash >= 0) return bySlash;\n }\n return 0;\n };\n\n const cycleModel = (dir: 'forward' | 'backward') => {\n const choices = cycleModelChoices();\n if (choices.length === 0) {\n void refreshModelChoices().then(() => {\n if (cycleModelChoices().length === 0) {\n chatLog.addSystem('No models available to cycle.');\n tui.requestRender();\n return;\n }\n cycleModel(dir);\n });\n return;\n }\n const idx = resolveModelChoiceIndex();\n const base = idx >= 0 ? idx : 0;\n const delta = dir === 'forward' ? 1 : -1;\n const next = choices[(base + delta + choices.length) % choices.length]!;\n sendMessage(`/switch ${next.provider}/${next.id}`);\n };\n\n const handleCtrlZ = () => {\n if (process.platform === 'win32') {\n chatLog.addSystem('Suspend (Ctrl+Z) is not supported on Windows.');\n tui.requestRender();\n return;\n }\n const suspendKeepAlive = setInterval(() => {}, 2 ** 30);\n const ignoreSigint = () => {};\n process.on('SIGINT', ignoreSigint);\n process.once('SIGCONT', () => {\n clearInterval(suspendKeepAlive);\n process.removeListener('SIGINT', ignoreSigint);\n tui.start();\n tui.setFocus(editor);\n tui.requestRender(true);\n });\n try {\n tui.stop();\n process.kill(0, 'SIGTSTP');\n } catch {\n clearInterval(suspendKeepAlive);\n process.removeListener('SIGINT', ignoreSigint);\n }\n };\n\n const openExternalEditor = () => {\n const dir = mkdtempSync(join(tmpdir(), 'xopc-tui-edit-'));\n const filePath = join(dir, 'message.md');\n writeFileSync(filePath, editor.getText(), 'utf8');\n const editorBin = process.env.EDITOR || process.env.VISUAL || 'vi';\n void (async () => {\n await withTuiSuspended(tui, async () => {\n spawnSync(editorBin, [filePath], { stdio: 'inherit' });\n });\n try {\n const next = readFileSync(filePath, 'utf8');\n editor.setText(next.replace(/\\r\\n/g, '\\n'));\n } catch {\n // ignore\n }\n try {\n unlinkSync(filePath);\n } catch {\n // ignore\n }\n tui.setFocus(editor);\n tui.requestRender(true);\n })();\n };\n\n const isAgentBusy = () =>\n state.activeRunId != null || state.isCompacting || busyStates.has(state.activityStatus);\n\n const steerMessage = (text: string) => {\n chatLog.addUser(text);\n touchStreamingActivity();\n tui.requestRender();\n void client\n .steerChat({ sessionKey: state.currentSessionKey, message: text })\n .then(({ ok }) => {\n if (!ok) {\n chatLog.addSystem(\n theme.dim(\n 'Could not steer — no active run or steer failed. Press Escape to abort, or Alt+Enter to queue a follow-up.',\n ),\n );\n } else {\n chatLog.addSystem(\n theme.dim('Steered — message injects at the next tool boundary (pi-style).'),\n );\n }\n tui.requestRender();\n })\n .catch((error: unknown) => {\n const errorMessage = error instanceof Error ? error.message : String(error);\n chatLog.addSystem(theme.dim(`Steer failed: ${errorMessage}`));\n tui.requestRender();\n });\n };\n\n const sendMessage = (text: string) => {\n if (state.isCompacting) {\n state.compactionQueue.push(text);\n chatLog.addSystem(\n theme.dim(`Queued during compaction (${state.compactionQueue.length}). Sends when compact finishes.`),\n );\n bottomBar.invalidate();\n tui.requestRender();\n return;\n }\n\n if (state.activeRunId) {\n chatLog.addSystem(\n 'A response is still in progress. Press Enter to steer, Alt+Enter to queue, or Escape to abort.',\n );\n tui.requestRender();\n return;\n }\n\n chatLog.addUser(text);\n setActivityStatus('sending');\n touchStreamingActivity();\n tui.requestRender();\n\n void client\n .sendChat({\n sessionKey: state.currentSessionKey,\n message: text,\n thinking: opts.thinking,\n })\n .catch((error: unknown) => {\n const errorMessage = error instanceof Error ? error.message : String(error);\n chatLog.addSystem(`❌ Failed to send: ${errorMessage}`);\n setActivityStatus('idle');\n tui.requestRender();\n });\n };\n\n const runCompaction = async () => {\n if (state.isCompacting) return;\n state.isCompacting = true;\n setActivityStatus('compacting');\n chatLog.addSystem(theme.dim('Compacting session…'));\n tui.requestRender();\n try {\n const result = await client.compactSession(state.currentSessionKey, { force: true });\n chatLog.addSystem(result.summary ?? (result.compacted ? 'Session compacted' : 'Nothing to compact'));\n if (result.compacted) {\n assembler.clear();\n clearPendingToolCallIds();\n state.historyLoaded = false;\n await loadSessionHistory();\n }\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n chatLog.addSystem(`❌ Compaction failed: ${errorMessage}`);\n } finally {\n state.isCompacting = false;\n setActivityStatus('idle');\n await refreshSessionInfo();\n const queued = state.compactionQueue.shift();\n if (queued && !state.activeRunId) {\n sendMessage(queued);\n }\n updateFooter();\n tui.requestRender();\n }\n };\n\n const applyTuiSettings = (settings: TuiSettings) => {\n tuiSettings = { ...settings };\n saveTuiSettings(tuiSettings);\n state.showThinking = tuiSettings.showThinking;\n state.toolsExpanded = tuiSettings.toolsExpanded;\n chatLog.setToolsExpanded(tuiSettings.toolsExpanded);\n applyThemeById(tuiSettings.theme);\n header.invalidate();\n updateEditorBorderColor();\n syncTerminalProgress();\n bottomBar.invalidate();\n tui.requestRender();\n };\n\n const previewTheme = (themeId: string) => {\n applyThemeById(themeId);\n updateEditorBorderColor();\n tui.requestRender();\n };\n\n const reloadKeybindings = () => {\n keybindings.reload();\n setKeybindings(keybindings);\n tui.requestRender();\n };\n\n const uiOverlays = {\n openSessionPicker: () => {},\n openScopedModels: () => {},\n openSettings: () => {},\n reloadKeybindings: () => reloadKeybindings(),\n };\n\n const handleCommand = createTuiCommandHandler({\n state,\n chatLog,\n tui,\n assembler,\n isLocalMode,\n abortActive,\n sendMessage,\n requestExit,\n updateFooter,\n keybindings,\n uiOverlays,\n runCompaction,\n extensionSlashCommands: extensionRuntime.slashCommands,\n });\n\n const { runLocalShellLine } = createLocalShellRunner({\n chatLog,\n tui,\n editor,\n openOverlay,\n closeOverlay,\n pauseStdioFilter: () => stdioFilter.pause(),\n resumeStdioFilter: () => stdioFilter.resume(),\n runWithInheritedStdio: async (work) => {\n await withTuiSuspended(tui, work);\n },\n });\n\n const submitCore = createEditorSubmitHandler({\n editor,\n handleCommand,\n sendMessage,\n handleBangLine: runLocalShellLine,\n isAgentBusy,\n steerWhileBusy: steerMessage,\n });\n\n const submitBurst = createSubmitBurstCoalescer({\n submit: submitCore,\n enabled: shouldEnableWindowsGitBashPasteFallback(),\n });\n editor.onSubmit = submitBurst;\n\n const flushFollowUpQueue = () => {\n if (state.exitRequested) return;\n if (state.activeRunId) return;\n const next = state.messageFollowUpQueue.shift();\n if (next === undefined) return;\n sendMessage(next);\n };\n\n const handleFollowUp = () => {\n const text = editor.getText().trim();\n if (!text) return;\n if (isAgentBusy()) {\n editor.addToHistory(text);\n state.messageFollowUpQueue.push(text);\n editor.setText('');\n chatLog.addSystem(\n theme.dim(\n `Queued follow-up (${state.messageFollowUpQueue.length} in queue). Next sends when this reply finishes.`,\n ),\n );\n bottomBar.invalidate();\n tui.requestRender();\n return;\n }\n submitBurst(text);\n };\n\n const handleDequeue = () => {\n if (state.messageFollowUpQueue.length === 0) {\n chatLog.addSystem(theme.dim('No queued messages to restore.'));\n tui.requestRender();\n return;\n }\n const queued = [...state.messageFollowUpQueue];\n state.messageFollowUpQueue.length = 0;\n const current = editor.getText().trim();\n const combined = [queued.join('\\n\\n'), current].filter(Boolean).join('\\n\\n');\n editor.setText(combined);\n chatLog.addSystem(\n theme.dim(\n `Restored ${queued.length} queued message${queued.length > 1 ? 's' : ''} to editor.`,\n ),\n );\n bottomBar.invalidate();\n tui.requestRender();\n };\n\n const setSessionKey = (key: string) => {\n state.currentSessionKey = key;\n };\n\n const clearChatForSessionSwitch = () => {\n assembler.clear();\n chatLog.clearAll();\n clearPendingToolCallIds();\n state.historyLoaded = false;\n state.messageFollowUpQueue.length = 0;\n };\n\n const loadSessionHistory = async () => {\n try {\n const { messages } = await client.loadHistory({\n sessionKey: state.currentSessionKey,\n limit: 200,\n });\n appendHistoryToChatLog(chatLog, messages, state.toolsExpanded);\n } catch {\n // ignore; footer already hints on disconnect\n } finally {\n state.historyLoaded = true;\n tui.requestRender();\n }\n };\n\n let ctrlCHandling = false;\n const handleCtrlC = () => {\n if (ctrlCHandling) return;\n ctrlCHandling = true;\n try {\n const now = Date.now();\n const decision = resolveCtrlCAction({\n hasInput: editor.getText().trim().length > 0,\n now,\n lastCtrlCAt: state.lastCtrlCAt,\n });\n state.lastCtrlCAt = decision.nextLastCtrlCAt;\n if (decision.action === 'clear') {\n editor.setText('');\n setActivityStatus('cleared input; press ctrl+c again to exit');\n tui.requestRender();\n return;\n }\n if (decision.action === 'exit') {\n requestExit();\n return;\n }\n setActivityStatus('press ctrl+c again to exit');\n tui.requestRender();\n } finally {\n ctrlCHandling = false;\n }\n };\n\n const setModelChoices = (models: TuiModelChoice[]) => {\n modelChoices = models;\n };\n\n const pickerSvc = {\n tui,\n editor,\n openOverlay,\n closeOverlay,\n chatLog,\n client,\n sendMessage,\n refreshSessionInfo,\n updateHeader,\n state,\n setSessionKey,\n clearChatForSessionSwitch,\n loadSessionHistory,\n setModelChoices,\n getScopedModelRefs: () => state.scopedModelRefs,\n setScopedModelRefs: (refs: string[] | null) => {\n state.scopedModelRefs = refs;\n saveScopedModelRefs(refs);\n },\n refreshCycleModels,\n getTuiSettings: () => ({ ...tuiSettings }),\n applyTuiSettings,\n previewTheme,\n reloadKeybindings,\n };\n\n uiOverlays.openSessionPicker = () => void openSessionPickerOverlay(pickerSvc);\n uiOverlays.openScopedModels = () => void openScopedModelsOverlay(pickerSvc);\n uiOverlays.openSettings = () => openSettingsOverlay(pickerSvc);\n\n const handleDoubleEscape = () => {\n switch (tuiSettings.doubleEscapeAction) {\n case 'tree':\n chatLog.addSystem(theme.dim('Session tree is not available in xopc TUI yet.'));\n break;\n case 'fork':\n chatLog.addSystem(theme.dim('Session fork is not available in xopc TUI yet.'));\n break;\n default:\n break;\n }\n tui.requestRender();\n };\n\n editor.onEscape = () => {\n if (state.activeRunId) {\n void abortActive();\n return;\n }\n if (editor.getText().trim().length > 0) return;\n const now = Date.now();\n if (now - state.lastEscapeAt <= DOUBLE_ESCAPE_WINDOW_MS) {\n state.lastEscapeAt = 0;\n handleDoubleEscape();\n return;\n }\n state.lastEscapeAt = now;\n };\n editor.onCtrlD = () => requestExit();\n\n editor.onAction('app.clear', handleCtrlC);\n editor.onAction('app.exit', () => requestExit());\n editor.onAction('app.suspend', handleCtrlZ);\n editor.onAction('app.thinking.cycle', () => {\n const cur = state.sessionInfo.thinkingLevel ?? opts.thinking ?? 'medium';\n sendMessage(`/think ${nextThinkLevel(cur)}`);\n updateEditorBorderColor();\n });\n editor.onAction('app.model.cycleForward', () => cycleModel('forward'));\n editor.onAction('app.model.cycleBackward', () => cycleModel('backward'));\n editor.onAction('app.model.select', () => void openModelPickerOverlay(pickerSvc));\n editor.onAction('app.session.resume', () => void openSessionPickerOverlay(pickerSvc));\n editor.onAction('app.tools.expand', () => {\n state.toolsExpanded = !state.toolsExpanded;\n tuiSettings = { ...tuiSettings, toolsExpanded: state.toolsExpanded };\n saveTuiSettings(tuiSettings);\n chatLog.setToolsExpanded(state.toolsExpanded);\n setActivityStatus(state.toolsExpanded ? 'tools expanded' : 'tools collapsed');\n tui.requestRender();\n });\n editor.onAction('app.thinking.toggle', () => {\n state.showThinking = !state.showThinking;\n tuiSettings = { ...tuiSettings, showThinking: state.showThinking };\n saveTuiSettings(tuiSettings);\n updateFooter();\n tui.requestRender();\n });\n editor.onAction('app.editor.external', openExternalEditor);\n editor.onPasteImage = () => {\n void (async () => {\n const filePath = await saveClipboardImageToTempFile();\n if (!filePath) return;\n editor.insertTextAtCursor(filePath);\n chatLog.addSystem(theme.dim(`Pasted image path: ${filePath}`));\n tui.requestRender();\n })();\n };\n editor.onAction('app.message.followUp', handleFollowUp);\n editor.onAction('app.message.dequeue', handleDequeue);\n\n streamWatchdogId = setInterval(() => {\n if (!state.activeRunId) return;\n if (!busyStates.has(state.activityStatus)) return;\n if (Date.now() - lastStreamActivityAt < DEFAULT_STREAMING_WATCHDOG_MS) return;\n\n const rid = state.activeRunId;\n const finalText = assembler.finalize(rid, state.showThinking);\n if (finalText) {\n chatLog.finalizeAssistant(finalText, rid);\n }\n chatLog.addSystem(\n '⚠️ No stream activity for 30s; UI reset (connection may have stalled). Retry or check gateway.',\n );\n state.activeRunId = null;\n setActivityStatus('idle');\n void refreshSessionInfo().finally(() => {\n updateFooter();\n tui.requestRender();\n });\n flushFollowUpQueue();\n tui.requestRender();\n }, 5000);\n\n const onAgentRunEnded = () => {\n state.progressMessage = null;\n void refreshSessionInfo().finally(() => {\n updateFooter();\n tui.requestRender();\n });\n flushFollowUpQueue();\n };\n\n client.onEvent = (evt: TuiEvent) => {\n const data = (evt.data ?? {}) as Record<string, unknown>;\n dispatchAgentSSE(\n evt.event,\n data,\n state,\n chatLog,\n assembler,\n tui,\n setActivityStatus,\n touchStreamingActivity,\n onAgentRunEnded,\n );\n };\n\n client.onConnected = () => {\n state.isConnected = true;\n setConnectionStatus(isLocalMode ? 'local ready' : 'gateway connected');\n touchStreamingActivity();\n void (async () => {\n await refreshSessionInfo();\n await refreshModelChoices();\n await loadSessionHistory();\n updateHeader();\n updateFooter();\n tui.requestRender();\n if (!state.autoMessageSent && opts.message) {\n state.autoMessageSent = true;\n sendMessage(opts.message);\n }\n })();\n };\n\n client.onDisconnected = (reason: string) => {\n const wasConnected = state.isConnected;\n state.isConnected = false;\n touchStreamingActivity();\n if (isLocalMode) {\n setConnectionStatus(`local stopped: ${reason}`);\n } else {\n const hint =\n wasConnected || state.historyLoaded\n ? ` (${reason}). Reconnecting broadcast stream…`\n : `. Ensure gateway is running (xopc gateway) or use --local.`;\n setConnectionStatus(`disconnected${hint}`);\n if (!wasConnected && !state.historyLoaded) {\n const gatewayUrl = opts.url ?? 'http://localhost:3120';\n chatLog.addSystem(\n `Cannot reach gateway at ${gatewayUrl}.\\n` +\n 'Start the gateway (`xopc gateway`) or run `xopc tui --local` for embedded mode.',\n );\n }\n }\n tui.requestRender();\n };\n\n client.onGap = (info) => {\n chatLog.addSystem(\n `⚠️ Event gap: expected ${info.expected}, received ${info.received}. Some updates may be missing.`,\n );\n setConnectionStatus(`event gap: expected ${info.expected}, got ${info.received}`);\n tui.requestRender();\n };\n\n const sigintHandler = () => handleCtrlC();\n const sigtermHandler = () => requestExit();\n process.on('SIGINT', sigintHandler);\n process.on('SIGTERM', sigtermHandler);\n\n updateHeader();\n updateEditorBorderColor();\n setConnectionStatus(isLocalMode ? 'starting local runtime' : 'connecting');\n updateFooter();\n await extensionRuntime.activate();\n tui.start();\n client.start();\n\n await new Promise<void>((resolve) => {\n finishTui = () => {\n process.removeListener('SIGINT', sigintHandler);\n process.removeListener('SIGTERM', sigtermHandler);\n if (streamWatchdogId) {\n clearInterval(streamWatchdogId);\n streamWatchdogId = null;\n }\n finishTui = null;\n resolve();\n };\n });\n\n return exitResult;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tui.js","names":["packageJson.version"],"sources":["../../../src/tui/tui.ts"],"sourcesContent":["import {\n Container,\n Loader,\n ProcessTerminal,\n setKeybindings,\n TUI,\n} from '@earendil-works/pi-tui';\nimport { mkdtempSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { spawnSync } from 'node:child_process';\n\nimport type { ThinkLevel } from '../agent/transcript/thinking-types.js';\nimport type { TuiBackend, TuiEvent, TuiModelChoice } from './tui-backend.js';\nimport { EmbeddedBackend } from './backends/embedded-backend.js';\nimport { GatewaySseBackend } from './backends/gateway-sse-backend.js';\nimport {\n clearPendingToolCallIds,\n DEFAULT_STREAMING_WATCHDOG_MS,\n dispatchAgentSSE,\n} from './tui-agent-events.js';\nimport { ChatLog } from './components/chat-log.js';\nimport { CustomEditor } from './components/custom-editor.js';\nimport { TuiBottomBar } from './components/tui-bottom-bar.js';\nimport { TuiHeader } from './components/tui-header.js';\nimport { StreamAssembler } from './stream-assembler.js';\nimport { createTuiCommandHandler, getSlashCommands } from './tui-commands.js';\nimport { createLocalShellRunner } from './tui-local-shell.js';\nimport {\n createBackspaceDeduper,\n drainAndStopTuiSafely,\n resolveCtrlCAction,\n} from './tui-lifecycle.js';\nimport {\n openModelPickerOverlay,\n openScopedModelsOverlay,\n openSessionPickerOverlay,\n openSettingsOverlay,\n} from './tui-picker-overlay.js';\nimport { createOverlayHandlers } from './tui-overlays.js';\nimport {\n createEditorSubmitHandler,\n createSubmitBurstCoalescer,\n shouldEnableWindowsGitBashPasteFallback,\n} from './tui-submit.js';\nimport { appendHistoryToChatLog } from './chat-history.js';\nimport { installTuiStdioFilter } from './tui-stdio-filter.js';\nimport { withTuiSuspended } from './tui-suspend.js';\nimport { saveClipboardImageToTempFile } from './clipboard-image.js';\nimport {\n applyThemeById,\n getBashExcludeBorderColor,\n getBashModeBorderColor,\n getThinkingBorderColor,\n initTuiTheme,\n} from './theme-manager.js';\nimport { editorTheme, theme } from './theme.js';\nimport { loadTuiSettings, saveTuiSettings, type TuiSettings } from './tui-settings.js';\nimport { resolveFdPath } from './tui-fd-path.js';\nimport packageJson from '../../package.json' with { type: 'json' };\nimport { createInitialState, type TuiOptions, type TuiResult, type TuiState } from './tui-types.js';\nimport { createXopcTuiKeybindingsManager } from './tui-keybindings-file.js';\nimport {\n filterModelsForCycle,\n loadScopedModelRefs,\n saveScopedModelRefs,\n} from './tui-scoped-models.js';\nimport { loadExtensionsForTuiLocalMode } from './extension-host/load-extensions.js';\nimport { createTuiExtensionRuntime } from './extension-host/runtime.js';\nimport type { ExtensionRegistryImpl } from '../extensions/loader.js';\n\nexport type { TuiOptions, TuiResult };\n\nexport {\n createBackspaceDeduper,\n drainAndStopTuiSafely,\n type DrainableTui,\n isIgnorableTuiStopError,\n resolveCtrlCAction,\n stopTuiSafely,\n} from './tui-lifecycle.js';\n\nexport { withTuiSuspended } from './tui-suspend.js';\n\nconst THINK_LEVEL_CYCLE: ThinkLevel[] = [\n 'off',\n 'minimal',\n 'low',\n 'medium',\n 'high',\n 'xhigh',\n 'adaptive',\n];\n\nfunction nextThinkLevel(current: string | undefined): ThinkLevel {\n const c = (current ?? 'medium').toLowerCase();\n const idx = THINK_LEVEL_CYCLE.indexOf(c as ThinkLevel);\n const mediumIdx = THINK_LEVEL_CYCLE.indexOf('medium');\n const base = idx >= 0 ? idx : mediumIdx >= 0 ? mediumIdx : 0;\n return THINK_LEVEL_CYCLE[(base + 1) % THINK_LEVEL_CYCLE.length]!;\n}\n\nconst DOUBLE_ESCAPE_WINDOW_MS = 500;\n\nexport async function runTui(opts: TuiOptions): Promise<TuiResult> {\n const stdioFilter = installTuiStdioFilter();\n const restoreStdio = () => stdioFilter.restore();\n\n const isLocalMode = opts.local === true;\n const sessionKey = opts.session ?? 'cli:tui';\n let tuiSettings = loadTuiSettings();\n initTuiTheme({ themeId: opts.theme ?? tuiSettings.theme });\n const state = createInitialState(sessionKey);\n state.scopedModelRefs = loadScopedModelRefs();\n state.showThinking = tuiSettings.showThinking;\n state.toolsExpanded = tuiSettings.toolsExpanded;\n const assembler = new StreamAssembler();\n\n let extensionRegistry: ExtensionRegistryImpl | undefined;\n if (isLocalMode) {\n extensionRegistry = await loadExtensionsForTuiLocalMode();\n }\n\n const client: TuiBackend = isLocalMode\n ? new EmbeddedBackend({ extensionRegistry })\n : new GatewaySseBackend({ url: opts.url ?? 'http://localhost:3120', token: opts.token });\n\n const keybindings = createXopcTuiKeybindingsManager();\n setKeybindings(keybindings);\n\n let modelChoices: TuiModelChoice[] = [];\n const cycleModelChoices = (): TuiModelChoice[] =>\n filterModelsForCycle(modelChoices, state.scopedModelRefs);\n\n const refreshCycleModels = () => {\n bottomBar.invalidate();\n tui.requestRender();\n };\n\n const tui = new TUI(new ProcessTerminal());\n const dedupeBackspace = createBackspaceDeduper();\n tui.addInputListener((data) => {\n const next = dedupeBackspace(data);\n if (next.length === 0) {\n return { consume: true };\n }\n return { data: next };\n });\n\n const header = new TuiHeader(() => ({\n version: packageJson.version ?? 'dev',\n connectionLabel: client.connectionLabel,\n sessionKey: state.currentSessionKey,\n showHints: tuiSettings.showStartupHints,\n }));\n const statusContainer = new Container();\n const bottomBar = new TuiBottomBar(() => state, () => opts.thinking);\n const chatLog = new ChatLog();\n chatLog.setToolsExpanded(state.toolsExpanded);\n const editor = new CustomEditor(tui, editorTheme, keybindings);\n const root = new Container();\n root.addChild(header);\n root.addChild(chatLog);\n root.addChild(statusContainer);\n root.addChild(editor);\n root.addChild(bottomBar);\n tui.addChild(root);\n tui.setFocus(editor);\n\n let isBashMode = false;\n let isBashExcludeContext = false;\n\n const updateEditorBorderColor = () => {\n if (isBashMode) {\n editor.borderColor = isBashExcludeContext\n ? getBashExcludeBorderColor()\n : getBashModeBorderColor();\n } else {\n const level = state.sessionInfo.thinkingLevel ?? opts.thinking ?? 'off';\n editor.borderColor = getThinkingBorderColor(level);\n }\n tui.requestRender();\n };\n\n editor.onChange = (text: string) => {\n const trimmed = text.trimStart();\n const nextExclude = trimmed.startsWith('!!');\n const nextBash = trimmed.startsWith('!');\n if (nextBash !== isBashMode || nextExclude !== isBashExcludeContext) {\n isBashMode = nextBash;\n isBashExcludeContext = nextExclude;\n updateEditorBorderColor();\n }\n };\n\n const { openOverlay, closeOverlay } = createOverlayHandlers(tui, editor);\n\n const slashCommands = getSlashCommands(isLocalMode);\n\n const extensionRuntime = createTuiExtensionRuntime({\n registry: extensionRegistry,\n tui,\n chatLog,\n header,\n bottomBar,\n getState: () => state,\n baseSlashCommands: slashCommands,\n cwd: process.cwd(),\n fdPath: resolveFdPath(),\n openOverlay,\n closeOverlay,\n onInvalidate: () => {\n updateHeader();\n updateFooter();\n tui.requestRender();\n },\n });\n\n editor.setAutocompleteProvider(extensionRuntime.autocompleteProvider);\n\n let statusLoader: Loader | null = null;\n let statusStartedAt: number | null = null;\n let lastActivityStatus = '';\n let elapsedTimerId: ReturnType<typeof setInterval> | null = null;\n const busyStates = new Set(['sending', 'waiting', 'streaming', 'running', 'compacting']);\n\n const syncTerminalProgress = () => {\n if (!tuiSettings.showTerminalProgress) {\n tui.terminal.setProgress(false);\n return;\n }\n tui.terminal.setProgress(busyStates.has(state.activityStatus));\n };\n\n let lastStreamActivityAt = Date.now();\n let streamWatchdogId: ReturnType<typeof setInterval> | null = null;\n\n const touchStreamingActivity = () => {\n lastStreamActivityAt = Date.now();\n };\n\n const formatElapsed = (startMs: number) => {\n const totalSeconds = Math.max(0, Math.floor((Date.now() - startMs) / 1000));\n if (totalSeconds < 60) return `${totalSeconds}s`;\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return `${minutes}m ${seconds}s`;\n };\n\n const renderStatus = () => {\n const isBusy = busyStates.has(state.activityStatus);\n if (isBusy) {\n if (!statusStartedAt || lastActivityStatus !== state.activityStatus) {\n statusStartedAt = Date.now();\n }\n if (!statusLoader) {\n statusContainer.clear();\n statusLoader = new Loader(\n tui,\n (spinner) => theme.accent(spinner),\n (text) => theme.bold(theme.accentSoft(text)),\n '',\n );\n statusContainer.addChild(statusLoader);\n }\n const elapsed = formatElapsed(statusStartedAt);\n statusLoader.setMessage(\n `${state.progressMessage ?? state.activityStatus} • ${elapsed} | ${state.connectionStatus}`,\n );\n if (!elapsedTimerId) {\n elapsedTimerId = setInterval(() => {\n if (statusStartedAt && statusLoader) {\n const el = formatElapsed(statusStartedAt);\n statusLoader.setMessage(\n `${state.progressMessage ?? state.activityStatus} • ${el} | ${state.connectionStatus}`,\n );\n }\n }, 1000);\n }\n } else {\n state.progressMessage = null;\n statusStartedAt = null;\n if (elapsedTimerId) {\n clearInterval(elapsedTimerId);\n elapsedTimerId = null;\n }\n statusLoader?.stop();\n statusLoader = null;\n statusContainer.clear();\n }\n lastActivityStatus = state.activityStatus;\n bottomBar.invalidate();\n syncTerminalProgress();\n tui.requestRender();\n };\n\n const setActivityStatus = (status: string) => {\n state.activityStatus = status as TuiState['activityStatus'];\n renderStatus();\n };\n\n const setConnectionStatus = (text: string) => {\n state.connectionStatus = text;\n renderStatus();\n };\n\n const updateHeader = () => {\n header.invalidate();\n syncTerminalTitle();\n };\n\n const syncTerminalTitle = () => {\n const shortKey =\n state.currentSessionKey.length > 48\n ? `${state.currentSessionKey.slice(0, 45)}…`\n : state.currentSessionKey;\n tui.terminal.setTitle(`xopc · ${shortKey}`);\n };\n\n const updateFooter = () => {\n bottomBar.invalidate();\n };\n\n const refreshModelChoices = async () => {\n try {\n modelChoices = await client.listModels();\n } catch {\n modelChoices = [];\n }\n bottomBar.invalidate();\n tui.requestRender();\n };\n\n const refreshSessionInfo = async () => {\n try {\n state.sessionInfo = await client.getSessionInfo(state.currentSessionKey);\n updateEditorBorderColor();\n updateFooter();\n tui.requestRender();\n } catch {\n // ignore\n }\n };\n\n let finishTui: (() => void) | null = null;\n let exitResult: TuiResult = { exitReason: 'exit' };\n\n const requestExit = () => {\n if (state.exitRequested) return;\n state.exitRequested = true;\n if (elapsedTimerId) {\n clearInterval(elapsedTimerId);\n elapsedTimerId = null;\n }\n if (streamWatchdogId) {\n clearInterval(streamWatchdogId);\n streamWatchdogId = null;\n }\n client.stop();\n tui.terminal.setProgress(false);\n void drainAndStopTuiSafely(tui).then(() => {\n restoreStdio();\n finishTui?.();\n process.exit(0);\n });\n };\n\n const abortActive = async () => {\n if (!state.activeRunId) return;\n const runId = state.activeRunId;\n state.activeRunId = null;\n assembler.drop(runId);\n chatLog.dropAssistant(runId);\n setActivityStatus('idle');\n tui.requestRender();\n await client.abortChat({ sessionKey: state.currentSessionKey, runId }).catch(() => {});\n };\n\n const resolveModelChoiceIndex = (): number => {\n const choices = cycleModelChoices();\n if (choices.length === 0) return -1;\n const p = state.sessionInfo.modelProvider;\n const m = state.sessionInfo.model;\n if (p && m) {\n const byParts = choices.findIndex((x) => x.provider === p && x.id === m);\n if (byParts >= 0) return byParts;\n }\n if (m?.includes('/')) {\n const [a, b] = m.split('/', 2);\n const bySlash = choices.findIndex((x) => x.provider === a && x.id === b);\n if (bySlash >= 0) return bySlash;\n }\n return 0;\n };\n\n const cycleModel = (dir: 'forward' | 'backward') => {\n const choices = cycleModelChoices();\n if (choices.length === 0) {\n void refreshModelChoices().then(() => {\n if (cycleModelChoices().length === 0) {\n chatLog.addSystem('No models available to cycle.');\n tui.requestRender();\n return;\n }\n cycleModel(dir);\n });\n return;\n }\n const idx = resolveModelChoiceIndex();\n const base = idx >= 0 ? idx : 0;\n const delta = dir === 'forward' ? 1 : -1;\n const next = choices[(base + delta + choices.length) % choices.length]!;\n sendMessage(`/switch ${next.provider}/${next.id}`);\n };\n\n const handleCtrlZ = () => {\n if (process.platform === 'win32') {\n chatLog.addSystem('Suspend (Ctrl+Z) is not supported on Windows.');\n tui.requestRender();\n return;\n }\n const suspendKeepAlive = setInterval(() => {}, 2 ** 30);\n const ignoreSigint = () => {};\n process.on('SIGINT', ignoreSigint);\n process.once('SIGCONT', () => {\n clearInterval(suspendKeepAlive);\n process.removeListener('SIGINT', ignoreSigint);\n tui.start();\n tui.setFocus(editor);\n tui.requestRender(true);\n });\n try {\n tui.stop();\n process.kill(0, 'SIGTSTP');\n } catch {\n clearInterval(suspendKeepAlive);\n process.removeListener('SIGINT', ignoreSigint);\n }\n };\n\n const openExternalEditor = () => {\n const dir = mkdtempSync(join(tmpdir(), 'xopc-tui-edit-'));\n const filePath = join(dir, 'message.md');\n writeFileSync(filePath, editor.getText(), 'utf8');\n const editorBin = process.env.EDITOR || process.env.VISUAL || 'vi';\n void (async () => {\n await withTuiSuspended(tui, async () => {\n spawnSync(editorBin, [filePath], { stdio: 'inherit' });\n });\n try {\n const next = readFileSync(filePath, 'utf8');\n editor.setText(next.replace(/\\r\\n/g, '\\n'));\n } catch {\n // ignore\n }\n try {\n unlinkSync(filePath);\n } catch {\n // ignore\n }\n tui.setFocus(editor);\n tui.requestRender(true);\n })();\n };\n\n const isAgentBusy = () =>\n state.activeRunId != null || state.isCompacting || busyStates.has(state.activityStatus);\n\n const steerMessage = (text: string) => {\n chatLog.addUser(text);\n touchStreamingActivity();\n tui.requestRender();\n void client\n .steerChat({ sessionKey: state.currentSessionKey, message: text })\n .then(({ ok }) => {\n if (!ok) {\n chatLog.addSystem(\n theme.dim(\n 'Could not steer — no active run or steer failed. Press Escape to abort, or Alt+Enter to queue a follow-up.',\n ),\n );\n } else {\n chatLog.addSystem(\n theme.dim('Steered — message injects at the next tool boundary (pi-style).'),\n );\n }\n tui.requestRender();\n })\n .catch((error: unknown) => {\n const errorMessage = error instanceof Error ? error.message : String(error);\n chatLog.addSystem(theme.dim(`Steer failed: ${errorMessage}`));\n tui.requestRender();\n });\n };\n\n const sendMessage = (text: string) => {\n if (state.isCompacting) {\n state.compactionQueue.push(text);\n chatLog.addSystem(\n theme.dim(`Queued during compaction (${state.compactionQueue.length}). Sends when compact finishes.`),\n );\n bottomBar.invalidate();\n tui.requestRender();\n return;\n }\n\n if (state.activeRunId) {\n chatLog.addSystem(\n 'A response is still in progress. Press Enter to steer, Alt+Enter to queue, or Escape to abort.',\n );\n tui.requestRender();\n return;\n }\n\n chatLog.addUser(text);\n setActivityStatus('sending');\n touchStreamingActivity();\n tui.requestRender();\n\n void client\n .sendChat({\n sessionKey: state.currentSessionKey,\n message: text,\n thinking: opts.thinking,\n })\n .catch((error: unknown) => {\n const errorMessage = error instanceof Error ? error.message : String(error);\n chatLog.addSystem(`❌ Failed to send: ${errorMessage}`);\n setActivityStatus('idle');\n tui.requestRender();\n });\n };\n\n const runCompaction = async () => {\n if (state.isCompacting) return;\n state.isCompacting = true;\n setActivityStatus('compacting');\n chatLog.addSystem(theme.dim('Compacting session…'));\n tui.requestRender();\n try {\n const result = await client.compactSession(state.currentSessionKey, { force: true });\n chatLog.addSystem(result.summary ?? (result.compacted ? 'Session compacted' : 'Nothing to compact'));\n if (result.compacted) {\n assembler.clear();\n clearPendingToolCallIds();\n state.historyLoaded = false;\n await loadSessionHistory();\n }\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n chatLog.addSystem(`❌ Compaction failed: ${errorMessage}`);\n } finally {\n state.isCompacting = false;\n setActivityStatus('idle');\n await refreshSessionInfo();\n const queued = state.compactionQueue.shift();\n if (queued && !state.activeRunId) {\n sendMessage(queued);\n }\n updateFooter();\n tui.requestRender();\n }\n };\n\n const applyTuiSettings = (settings: TuiSettings) => {\n tuiSettings = { ...settings };\n saveTuiSettings(tuiSettings);\n state.showThinking = tuiSettings.showThinking;\n state.toolsExpanded = tuiSettings.toolsExpanded;\n chatLog.setToolsExpanded(tuiSettings.toolsExpanded);\n applyThemeById(tuiSettings.theme);\n header.invalidate();\n updateEditorBorderColor();\n syncTerminalProgress();\n bottomBar.invalidate();\n tui.requestRender();\n };\n\n const previewTheme = (themeId: string) => {\n applyThemeById(themeId);\n updateEditorBorderColor();\n tui.requestRender();\n };\n\n const reloadKeybindings = () => {\n keybindings.reload();\n setKeybindings(keybindings);\n tui.requestRender();\n };\n\n const uiOverlays = {\n openSessionPicker: () => {},\n openScopedModels: () => {},\n openSettings: () => {},\n reloadKeybindings: () => reloadKeybindings(),\n };\n\n const handleCommand = createTuiCommandHandler({\n state,\n chatLog,\n tui,\n assembler,\n isLocalMode,\n abortActive,\n sendMessage,\n requestExit,\n updateFooter,\n keybindings,\n uiOverlays,\n runCompaction,\n extensionSlashCommands: extensionRuntime.slashCommands,\n });\n\n const { runLocalShellLine } = createLocalShellRunner({\n chatLog,\n tui,\n editor,\n openOverlay,\n closeOverlay,\n pauseStdioFilter: () => stdioFilter.pause(),\n resumeStdioFilter: () => stdioFilter.resume(),\n runWithInheritedStdio: async (work) => {\n await withTuiSuspended(tui, work);\n },\n });\n\n const submitCore = createEditorSubmitHandler({\n editor,\n handleCommand,\n sendMessage,\n handleBangLine: runLocalShellLine,\n isAgentBusy,\n steerWhileBusy: steerMessage,\n });\n\n const submitBurst = createSubmitBurstCoalescer({\n submit: submitCore,\n enabled: shouldEnableWindowsGitBashPasteFallback(),\n });\n editor.onSubmit = submitBurst;\n\n const flushFollowUpQueue = () => {\n if (state.exitRequested) return;\n if (state.activeRunId) return;\n const next = state.messageFollowUpQueue.shift();\n if (next === undefined) return;\n sendMessage(next);\n };\n\n const handleFollowUp = () => {\n const text = editor.getText().trim();\n if (!text) return;\n if (isAgentBusy()) {\n editor.addToHistory(text);\n state.messageFollowUpQueue.push(text);\n editor.setText('');\n chatLog.addSystem(\n theme.dim(\n `Queued follow-up (${state.messageFollowUpQueue.length} in queue). Next sends when this reply finishes.`,\n ),\n );\n bottomBar.invalidate();\n tui.requestRender();\n return;\n }\n submitBurst(text);\n };\n\n const handleDequeue = () => {\n if (state.messageFollowUpQueue.length === 0) {\n chatLog.addSystem(theme.dim('No queued messages to restore.'));\n tui.requestRender();\n return;\n }\n const queued = [...state.messageFollowUpQueue];\n state.messageFollowUpQueue.length = 0;\n const current = editor.getText().trim();\n const combined = [queued.join('\\n\\n'), current].filter(Boolean).join('\\n\\n');\n editor.setText(combined);\n chatLog.addSystem(\n theme.dim(\n `Restored ${queued.length} queued message${queued.length > 1 ? 's' : ''} to editor.`,\n ),\n );\n bottomBar.invalidate();\n tui.requestRender();\n };\n\n const setSessionKey = (key: string) => {\n state.currentSessionKey = key;\n };\n\n const clearChatForSessionSwitch = () => {\n assembler.clear();\n chatLog.clearAll();\n clearPendingToolCallIds();\n state.historyLoaded = false;\n state.messageFollowUpQueue.length = 0;\n };\n\n const loadSessionHistory = async () => {\n try {\n const { messages } = await client.loadHistory({\n sessionKey: state.currentSessionKey,\n limit: 200,\n });\n appendHistoryToChatLog(chatLog, messages, state.toolsExpanded);\n } catch {\n // ignore; footer already hints on disconnect\n } finally {\n state.historyLoaded = true;\n tui.requestRender();\n }\n };\n\n let ctrlCHandling = false;\n const handleCtrlC = () => {\n if (ctrlCHandling) return;\n ctrlCHandling = true;\n try {\n const now = Date.now();\n const decision = resolveCtrlCAction({\n hasInput: editor.getText().trim().length > 0,\n now,\n lastCtrlCAt: state.lastCtrlCAt,\n });\n state.lastCtrlCAt = decision.nextLastCtrlCAt;\n if (decision.action === 'clear') {\n editor.setText('');\n setActivityStatus('cleared input; press ctrl+c again to exit');\n tui.requestRender();\n return;\n }\n if (decision.action === 'exit') {\n requestExit();\n return;\n }\n setActivityStatus('press ctrl+c again to exit');\n tui.requestRender();\n } finally {\n ctrlCHandling = false;\n }\n };\n\n const setModelChoices = (models: TuiModelChoice[]) => {\n modelChoices = models;\n };\n\n const pickerSvc = {\n tui,\n editor,\n openOverlay,\n closeOverlay,\n chatLog,\n client,\n sendMessage,\n refreshSessionInfo,\n updateHeader,\n state,\n setSessionKey,\n clearChatForSessionSwitch,\n loadSessionHistory,\n setModelChoices,\n getScopedModelRefs: () => state.scopedModelRefs,\n setScopedModelRefs: (refs: string[] | null) => {\n state.scopedModelRefs = refs;\n saveScopedModelRefs(refs);\n },\n refreshCycleModels,\n getTuiSettings: () => ({ ...tuiSettings }),\n applyTuiSettings,\n previewTheme,\n reloadKeybindings,\n };\n\n uiOverlays.openSessionPicker = () => void openSessionPickerOverlay(pickerSvc);\n uiOverlays.openScopedModels = () => void openScopedModelsOverlay(pickerSvc);\n uiOverlays.openSettings = () => openSettingsOverlay(pickerSvc);\n\n const handleDoubleEscape = () => {\n switch (tuiSettings.doubleEscapeAction) {\n case 'tree':\n chatLog.addSystem(theme.dim('Session tree is not available in xopc TUI yet.'));\n break;\n case 'fork':\n chatLog.addSystem(theme.dim('Session fork is not available in xopc TUI yet.'));\n break;\n default:\n break;\n }\n tui.requestRender();\n };\n\n editor.onEscape = () => {\n if (state.activeRunId) {\n void abortActive();\n return;\n }\n if (editor.getText().trim().length > 0) return;\n const now = Date.now();\n if (now - state.lastEscapeAt <= DOUBLE_ESCAPE_WINDOW_MS) {\n state.lastEscapeAt = 0;\n handleDoubleEscape();\n return;\n }\n state.lastEscapeAt = now;\n };\n editor.onCtrlD = () => requestExit();\n\n editor.onAction('app.clear', handleCtrlC);\n editor.onAction('app.exit', () => requestExit());\n editor.onAction('app.suspend', handleCtrlZ);\n editor.onAction('app.thinking.cycle', () => {\n const cur = state.sessionInfo.thinkingLevel ?? opts.thinking ?? 'medium';\n sendMessage(`/think ${nextThinkLevel(cur)}`);\n updateEditorBorderColor();\n });\n editor.onAction('app.model.cycleForward', () => cycleModel('forward'));\n editor.onAction('app.model.cycleBackward', () => cycleModel('backward'));\n editor.onAction('app.model.select', () => void openModelPickerOverlay(pickerSvc));\n editor.onAction('app.session.resume', () => void openSessionPickerOverlay(pickerSvc));\n editor.onAction('app.tools.expand', () => {\n state.toolsExpanded = !state.toolsExpanded;\n tuiSettings = { ...tuiSettings, toolsExpanded: state.toolsExpanded };\n saveTuiSettings(tuiSettings);\n chatLog.setToolsExpanded(state.toolsExpanded);\n setActivityStatus(state.toolsExpanded ? 'tools expanded' : 'tools collapsed');\n tui.requestRender();\n });\n editor.onAction('app.thinking.toggle', () => {\n state.showThinking = !state.showThinking;\n tuiSettings = { ...tuiSettings, showThinking: state.showThinking };\n saveTuiSettings(tuiSettings);\n updateFooter();\n tui.requestRender();\n });\n editor.onAction('app.editor.external', openExternalEditor);\n editor.onPasteImage = () => {\n void (async () => {\n const filePath = await saveClipboardImageToTempFile();\n if (!filePath) return;\n editor.insertTextAtCursor(filePath);\n chatLog.addSystem(theme.dim(`Pasted image path: ${filePath}`));\n tui.requestRender();\n })();\n };\n editor.onAction('app.message.followUp', handleFollowUp);\n editor.onAction('app.message.dequeue', handleDequeue);\n\n streamWatchdogId = setInterval(() => {\n if (!state.activeRunId) return;\n if (!busyStates.has(state.activityStatus)) return;\n if (Date.now() - lastStreamActivityAt < DEFAULT_STREAMING_WATCHDOG_MS) return;\n\n const rid = state.activeRunId;\n const finalText = assembler.finalize(rid, state.showThinking);\n if (finalText) {\n chatLog.finalizeAssistant(finalText, rid);\n }\n chatLog.addSystem(\n '⚠️ No stream activity for 30s; UI reset (connection may have stalled). Retry or check gateway.',\n );\n state.activeRunId = null;\n setActivityStatus('idle');\n void refreshSessionInfo().finally(() => {\n updateFooter();\n tui.requestRender();\n });\n flushFollowUpQueue();\n tui.requestRender();\n }, 5000);\n\n const onAgentRunEnded = () => {\n state.progressMessage = null;\n void refreshSessionInfo().finally(() => {\n updateFooter();\n tui.requestRender();\n });\n flushFollowUpQueue();\n };\n\n client.onEvent = (evt: TuiEvent) => {\n const data = (evt.data ?? {}) as Record<string, unknown>;\n dispatchAgentSSE(\n evt.event,\n data,\n state,\n chatLog,\n assembler,\n tui,\n setActivityStatus,\n touchStreamingActivity,\n onAgentRunEnded,\n );\n };\n\n client.onConnected = () => {\n state.isConnected = true;\n setConnectionStatus(isLocalMode ? 'local ready' : 'gateway connected');\n touchStreamingActivity();\n void (async () => {\n await refreshSessionInfo();\n await refreshModelChoices();\n await loadSessionHistory();\n updateHeader();\n updateFooter();\n tui.requestRender();\n if (!state.autoMessageSent && opts.message) {\n state.autoMessageSent = true;\n sendMessage(opts.message);\n }\n })();\n };\n\n client.onDisconnected = (reason: string) => {\n const wasConnected = state.isConnected;\n state.isConnected = false;\n touchStreamingActivity();\n if (isLocalMode) {\n setConnectionStatus(`local stopped: ${reason}`);\n } else {\n const hint =\n wasConnected || state.historyLoaded\n ? ` (${reason}). Reconnecting broadcast stream…`\n : `. Ensure gateway is running (xopc gateway) or use --local.`;\n setConnectionStatus(`disconnected${hint}`);\n if (!wasConnected && !state.historyLoaded) {\n const gatewayUrl = opts.url ?? 'http://localhost:3120';\n chatLog.addSystem(\n `Cannot reach gateway at ${gatewayUrl}.\\n` +\n 'Start the gateway (`xopc gateway`) or run `xopc tui --local` for embedded mode.',\n );\n }\n }\n tui.requestRender();\n };\n\n client.onGap = (info) => {\n chatLog.addSystem(\n `⚠️ Event gap: expected ${info.expected}, received ${info.received}. Some updates may be missing.`,\n );\n setConnectionStatus(`event gap: expected ${info.expected}, got ${info.received}`);\n tui.requestRender();\n };\n\n const sigintHandler = () => handleCtrlC();\n const sigtermHandler = () => requestExit();\n process.on('SIGINT', sigintHandler);\n process.on('SIGTERM', sigtermHandler);\n\n updateHeader();\n updateEditorBorderColor();\n setConnectionStatus(isLocalMode ? 'starting local runtime' : 'connecting');\n updateFooter();\n await extensionRuntime.activate();\n tui.start();\n client.start();\n\n await new Promise<void>((resolve) => {\n finishTui = () => {\n process.removeListener('SIGINT', sigintHandler);\n process.removeListener('SIGTERM', sigtermHandler);\n if (streamWatchdogId) {\n clearInterval(streamWatchdogId);\n streamWatchdogId = null;\n }\n finishTui = null;\n resolve();\n };\n });\n\n return exitResult;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoFA,MAAM,oBAAkC;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAS,eAAe,SAAyC;CAC/D,MAAM,KAAK,WAAW,UAAU,aAAa;CAC7C,MAAM,MAAM,kBAAkB,QAAQ,EAAgB;CACtD,MAAM,YAAY,kBAAkB,QAAQ,SAAS;AAErD,QAAO,oBADM,OAAO,IAAI,MAAM,aAAa,IAAI,YAAY,KAC1B,KAAK,kBAAkB;;AAG1D,MAAM,0BAA0B;AAEhC,eAAsB,OAAO,MAAsC;CACjE,MAAM,cAAc,uBAAuB;CAC3C,MAAM,qBAAqB,YAAY,SAAS;CAEhD,MAAM,cAAc,KAAK,UAAU;CACnC,MAAM,aAAa,KAAK,WAAW;CACnC,IAAI,cAAc,iBAAiB;AACnC,cAAa,EAAE,SAAS,KAAK,SAAS,YAAY,OAAO,CAAC;CAC1D,MAAM,QAAQ,mBAAmB,WAAW;AAC5C,OAAM,kBAAkB,qBAAqB;AAC7C,OAAM,eAAe,YAAY;AACjC,OAAM,gBAAgB,YAAY;CAClC,MAAM,YAAY,IAAI,iBAAiB;CAEvC,IAAI;AACJ,KAAI,YACF,qBAAoB,MAAM,+BAA+B;CAG3D,MAAM,SAAqB,cACvB,IAAI,gBAAgB,EAAE,mBAAmB,CAAC,GAC1C,IAAI,kBAAkB;EAAE,KAAK,KAAK,OAAO;EAAyB,OAAO,KAAK;EAAO,CAAC;CAE1F,MAAM,cAAc,iCAAiC;AACrD,gBAAe,YAAY;CAE3B,IAAI,eAAiC,EAAE;CACvC,MAAM,0BACJ,qBAAqB,cAAc,MAAM,gBAAgB;CAE3D,MAAM,2BAA2B;AAC/B,YAAU,YAAY;AACtB,MAAI,eAAe;;CAGrB,MAAM,MAAM,IAAI,IAAI,IAAI,iBAAiB,CAAC;CAC1C,MAAM,kBAAkB,wBAAwB;AAChD,KAAI,kBAAkB,SAAS;EAC7B,MAAM,OAAO,gBAAgB,KAAK;AAClC,MAAI,KAAK,WAAW,EAClB,QAAO,EAAE,SAAS,MAAM;AAE1B,SAAO,EAAE,MAAM,MAAM;GACrB;CAEF,MAAM,SAAS,IAAI,iBAAiB;EAClC,SAASA,WAAuB;EAChC,iBAAiB,OAAO;EACxB,YAAY,MAAM;EAClB,WAAW,YAAY;EACxB,EAAE;CACH,MAAM,kBAAkB,IAAI,WAAW;CACvC,MAAM,YAAY,IAAI,mBAAmB,aAAa,KAAK,SAAS;CACpE,MAAM,UAAU,IAAI,SAAS;AAC7B,SAAQ,iBAAiB,MAAM,cAAc;CAC7C,MAAM,SAAS,IAAI,aAAa,KAAK,aAAa,YAAY;CAC9D,MAAM,OAAO,IAAI,WAAW;AAC5B,MAAK,SAAS,OAAO;AACrB,MAAK,SAAS,QAAQ;AACtB,MAAK,SAAS,gBAAgB;AAC9B,MAAK,SAAS,OAAO;AACrB,MAAK,SAAS,UAAU;AACxB,KAAI,SAAS,KAAK;AAClB,KAAI,SAAS,OAAO;CAEpB,IAAI,aAAa;CACjB,IAAI,uBAAuB;CAE3B,MAAM,gCAAgC;AACpC,MAAI,WACF,QAAO,cAAc,uBACjB,2BAA2B,GAC3B,wBAAwB;MAG5B,QAAO,cAAc,uBADP,MAAM,YAAY,iBAAiB,KAAK,YAAY,MAChB;AAEpD,MAAI,eAAe;;AAGrB,QAAO,YAAY,SAAiB;EAClC,MAAM,UAAU,KAAK,WAAW;EAChC,MAAM,cAAc,QAAQ,WAAW,KAAK;EAC5C,MAAM,WAAW,QAAQ,WAAW,IAAI;AACxC,MAAI,aAAa,cAAc,gBAAgB,sBAAsB;AACnE,gBAAa;AACb,0BAAuB;AACvB,4BAAyB;;;CAI7B,MAAM,EAAE,aAAa,iBAAiB,sBAAsB,KAAK,OAAO;CAExE,MAAM,gBAAgB,iBAAiB,YAAY;CAEnD,MAAM,mBAAmB,0BAA0B;EACjD,UAAU;EACV;EACA;EACA;EACA;EACA,gBAAgB;EAChB,mBAAmB;EACnB,KAAK,QAAQ,KAAK;EAClB,QAAQ,eAAe;EACvB;EACA;EACA,oBAAoB;AAClB,iBAAc;AACd,iBAAc;AACd,OAAI,eAAe;;EAEtB,CAAC;AAEF,QAAO,wBAAwB,iBAAiB,qBAAqB;CAErE,IAAI,eAA8B;CAClC,IAAI,kBAAiC;CACrC,IAAI,qBAAqB;CACzB,IAAI,iBAAwD;CAC5D,MAAM,aAAa,IAAI,IAAI;EAAC;EAAW;EAAW;EAAa;EAAW;EAAa,CAAC;CAExF,MAAM,6BAA6B;AACjC,MAAI,CAAC,YAAY,sBAAsB;AACrC,OAAI,SAAS,YAAY,MAAM;AAC/B;;AAEF,MAAI,SAAS,YAAY,WAAW,IAAI,MAAM,eAAe,CAAC;;CAGhE,IAAI,uBAAuB,KAAK,KAAK;CACrC,IAAI,mBAA0D;CAE9D,MAAM,+BAA+B;AACnC,yBAAuB,KAAK,KAAK;;CAGnC,MAAM,iBAAiB,YAAoB;EACzC,MAAM,eAAe,KAAK,IAAI,GAAG,KAAK,OAAO,KAAK,KAAK,GAAG,WAAW,IAAK,CAAC;AAC3E,MAAI,eAAe,GAAI,QAAO,GAAG,aAAa;AAG9C,SAAO,GAFS,KAAK,MAAM,eAAe,GAEzB,CAAC,IADF,eAAe,GACD;;CAGhC,MAAM,qBAAqB;AAEzB,MADe,WAAW,IAAI,MAAM,eAC1B,EAAE;AACV,OAAI,CAAC,mBAAmB,uBAAuB,MAAM,eACnD,mBAAkB,KAAK,KAAK;AAE9B,OAAI,CAAC,cAAc;AACjB,oBAAgB,OAAO;AACvB,mBAAe,IAAI,OACjB,MACC,YAAY,MAAM,OAAO,QAAQ,GACjC,SAAS,MAAM,KAAK,MAAM,WAAW,KAAK,CAAC,EAC5C,GACD;AACD,oBAAgB,SAAS,aAAa;;GAExC,MAAM,UAAU,cAAc,gBAAgB;AAC9C,gBAAa,WACX,GAAG,MAAM,mBAAmB,MAAM,eAAe,KAAK,QAAQ,KAAK,MAAM,mBAC1E;AACD,OAAI,CAAC,eACH,kBAAiB,kBAAkB;AACjC,QAAI,mBAAmB,cAAc;KACnC,MAAM,KAAK,cAAc,gBAAgB;AACzC,kBAAa,WACX,GAAG,MAAM,mBAAmB,MAAM,eAAe,KAAK,GAAG,KAAK,MAAM,mBACrE;;MAEF,IAAK;SAEL;AACL,SAAM,kBAAkB;AACxB,qBAAkB;AAClB,OAAI,gBAAgB;AAClB,kBAAc,eAAe;AAC7B,qBAAiB;;AAEnB,iBAAc,MAAM;AACpB,kBAAe;AACf,mBAAgB,OAAO;;AAEzB,uBAAqB,MAAM;AAC3B,YAAU,YAAY;AACtB,wBAAsB;AACtB,MAAI,eAAe;;CAGrB,MAAM,qBAAqB,WAAmB;AAC5C,QAAM,iBAAiB;AACvB,gBAAc;;CAGhB,MAAM,uBAAuB,SAAiB;AAC5C,QAAM,mBAAmB;AACzB,gBAAc;;CAGhB,MAAM,qBAAqB;AACzB,SAAO,YAAY;AACnB,qBAAmB;;CAGrB,MAAM,0BAA0B;EAC9B,MAAM,WACJ,MAAM,kBAAkB,SAAS,KAC7B,GAAG,MAAM,kBAAkB,MAAM,GAAG,GAAG,CAAC,KACxC,MAAM;AACZ,MAAI,SAAS,SAAS,UAAU,WAAW;;CAG7C,MAAM,qBAAqB;AACzB,YAAU,YAAY;;CAGxB,MAAM,sBAAsB,YAAY;AACtC,MAAI;AACF,kBAAe,MAAM,OAAO,YAAY;UAClC;AACN,kBAAe,EAAE;;AAEnB,YAAU,YAAY;AACtB,MAAI,eAAe;;CAGrB,MAAM,qBAAqB,YAAY;AACrC,MAAI;AACF,SAAM,cAAc,MAAM,OAAO,eAAe,MAAM,kBAAkB;AACxE,4BAAyB;AACzB,iBAAc;AACd,OAAI,eAAe;UACb;;CAKV,IAAI,YAAiC;CACrC,IAAI,aAAwB,EAAE,YAAY,QAAQ;CAElD,MAAM,oBAAoB;AACxB,MAAI,MAAM,cAAe;AACzB,QAAM,gBAAgB;AACtB,MAAI,gBAAgB;AAClB,iBAAc,eAAe;AAC7B,oBAAiB;;AAEnB,MAAI,kBAAkB;AACpB,iBAAc,iBAAiB;AAC/B,sBAAmB;;AAErB,SAAO,MAAM;AACb,MAAI,SAAS,YAAY,MAAM;AAC1B,wBAAsB,IAAI,CAAC,WAAW;AACzC,iBAAc;AACd,gBAAa;AACb,WAAQ,KAAK,EAAE;IACf;;CAGJ,MAAM,cAAc,YAAY;AAC9B,MAAI,CAAC,MAAM,YAAa;EACxB,MAAM,QAAQ,MAAM;AACpB,QAAM,cAAc;AACpB,YAAU,KAAK,MAAM;AACrB,UAAQ,cAAc,MAAM;AAC5B,oBAAkB,OAAO;AACzB,MAAI,eAAe;AACnB,QAAM,OAAO,UAAU;GAAE,YAAY,MAAM;GAAmB;GAAO,CAAC,CAAC,YAAY,GAAG;;CAGxF,MAAM,gCAAwC;EAC5C,MAAM,UAAU,mBAAmB;AACnC,MAAI,QAAQ,WAAW,EAAG,QAAO;EACjC,MAAM,IAAI,MAAM,YAAY;EAC5B,MAAM,IAAI,MAAM,YAAY;AAC5B,MAAI,KAAK,GAAG;GACV,MAAM,UAAU,QAAQ,WAAW,MAAM,EAAE,aAAa,KAAK,EAAE,OAAO,EAAE;AACxE,OAAI,WAAW,EAAG,QAAO;;AAE3B,MAAI,GAAG,SAAS,IAAI,EAAE;GACpB,MAAM,CAAC,GAAG,KAAK,EAAE,MAAM,KAAK,EAAE;GAC9B,MAAM,UAAU,QAAQ,WAAW,MAAM,EAAE,aAAa,KAAK,EAAE,OAAO,EAAE;AACxE,OAAI,WAAW,EAAG,QAAO;;AAE3B,SAAO;;CAGT,MAAM,cAAc,QAAgC;EAClD,MAAM,UAAU,mBAAmB;AACnC,MAAI,QAAQ,WAAW,GAAG;AACnB,wBAAqB,CAAC,WAAW;AACpC,QAAI,mBAAmB,CAAC,WAAW,GAAG;AACpC,aAAQ,UAAU,gCAAgC;AAClD,SAAI,eAAe;AACnB;;AAEF,eAAW,IAAI;KACf;AACF;;EAEF,MAAM,MAAM,yBAAyB;EAGrC,MAAM,OAAO,UAFA,OAAO,IAAI,MAAM,MAChB,QAAQ,YAAY,IAAI,MACD,QAAQ,UAAU,QAAQ;AAC/D,cAAY,WAAW,KAAK,SAAS,GAAG,KAAK,KAAK;;CAGpD,MAAM,oBAAoB;AACxB,MAAI,QAAQ,aAAa,SAAS;AAChC,WAAQ,UAAU,gDAAgD;AAClE,OAAI,eAAe;AACnB;;EAEF,MAAM,mBAAmB,kBAAkB,IAAI,KAAK,GAAG;EACvD,MAAM,qBAAqB;AAC3B,UAAQ,GAAG,UAAU,aAAa;AAClC,UAAQ,KAAK,iBAAiB;AAC5B,iBAAc,iBAAiB;AAC/B,WAAQ,eAAe,UAAU,aAAa;AAC9C,OAAI,OAAO;AACX,OAAI,SAAS,OAAO;AACpB,OAAI,cAAc,KAAK;IACvB;AACF,MAAI;AACF,OAAI,MAAM;AACV,WAAQ,KAAK,GAAG,UAAU;UACpB;AACN,iBAAc,iBAAiB;AAC/B,WAAQ,eAAe,UAAU,aAAa;;;CAIlD,MAAM,2BAA2B;EAE/B,MAAM,WAAW,KADL,YAAY,KAAK,QAAQ,EAAE,iBAAiB,CAC/B,EAAE,aAAa;AACxC,gBAAc,UAAU,OAAO,SAAS,EAAE,OAAO;EACjD,MAAM,YAAY,QAAQ,IAAI,UAAU,QAAQ,IAAI,UAAU;AAC9D,GAAM,YAAY;AAChB,SAAM,iBAAiB,KAAK,YAAY;AACtC,cAAU,WAAW,CAAC,SAAS,EAAE,EAAE,OAAO,WAAW,CAAC;KACtD;AACF,OAAI;IACF,MAAM,OAAO,aAAa,UAAU,OAAO;AAC3C,WAAO,QAAQ,KAAK,QAAQ,SAAS,KAAK,CAAC;WACrC;AAGR,OAAI;AACF,eAAW,SAAS;WACd;AAGR,OAAI,SAAS,OAAO;AACpB,OAAI,cAAc,KAAK;MACrB;;CAGN,MAAM,oBACJ,MAAM,eAAe,QAAQ,MAAM,gBAAgB,WAAW,IAAI,MAAM,eAAe;CAEzF,MAAM,gBAAgB,SAAiB;AACrC,UAAQ,QAAQ,KAAK;AACrB,0BAAwB;AACxB,MAAI,eAAe;AACd,SACF,UAAU;GAAE,YAAY,MAAM;GAAmB,SAAS;GAAM,CAAC,CACjE,MAAM,EAAE,SAAS;AAChB,OAAI,CAAC,GACH,SAAQ,UACN,MAAM,IACJ,6GACD,CACF;OAED,SAAQ,UACN,MAAM,IAAI,kEAAkE,CAC7E;AAEH,OAAI,eAAe;IACnB,CACD,OAAO,UAAmB;GACzB,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,WAAQ,UAAU,MAAM,IAAI,iBAAiB,eAAe,CAAC;AAC7D,OAAI,eAAe;IACnB;;CAGN,MAAM,eAAe,SAAiB;AACpC,MAAI,MAAM,cAAc;AACtB,SAAM,gBAAgB,KAAK,KAAK;AAChC,WAAQ,UACN,MAAM,IAAI,6BAA6B,MAAM,gBAAgB,OAAO,iCAAiC,CACtG;AACD,aAAU,YAAY;AACtB,OAAI,eAAe;AACnB;;AAGF,MAAI,MAAM,aAAa;AACrB,WAAQ,UACN,iGACD;AACD,OAAI,eAAe;AACnB;;AAGF,UAAQ,QAAQ,KAAK;AACrB,oBAAkB,UAAU;AAC5B,0BAAwB;AACxB,MAAI,eAAe;AAEd,SACF,SAAS;GACR,YAAY,MAAM;GAClB,SAAS;GACT,UAAU,KAAK;GAChB,CAAC,CACD,OAAO,UAAmB;GACzB,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,WAAQ,UAAU,qBAAqB,eAAe;AACtD,qBAAkB,OAAO;AACzB,OAAI,eAAe;IACnB;;CAGN,MAAM,gBAAgB,YAAY;AAChC,MAAI,MAAM,aAAc;AACxB,QAAM,eAAe;AACrB,oBAAkB,aAAa;AAC/B,UAAQ,UAAU,MAAM,IAAI,sBAAsB,CAAC;AACnD,MAAI,eAAe;AACnB,MAAI;GACF,MAAM,SAAS,MAAM,OAAO,eAAe,MAAM,mBAAmB,EAAE,OAAO,MAAM,CAAC;AACpF,WAAQ,UAAU,OAAO,YAAY,OAAO,YAAY,sBAAsB,sBAAsB;AACpG,OAAI,OAAO,WAAW;AACpB,cAAU,OAAO;AACjB,6BAAyB;AACzB,UAAM,gBAAgB;AACtB,UAAM,oBAAoB;;WAErB,OAAgB;GACvB,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,WAAQ,UAAU,wBAAwB,eAAe;YACjD;AACR,SAAM,eAAe;AACrB,qBAAkB,OAAO;AACzB,SAAM,oBAAoB;GAC1B,MAAM,SAAS,MAAM,gBAAgB,OAAO;AAC5C,OAAI,UAAU,CAAC,MAAM,YACnB,aAAY,OAAO;AAErB,iBAAc;AACd,OAAI,eAAe;;;CAIvB,MAAM,oBAAoB,aAA0B;AAClD,gBAAc,EAAE,GAAG,UAAU;AAC7B,kBAAgB,YAAY;AAC5B,QAAM,eAAe,YAAY;AACjC,QAAM,gBAAgB,YAAY;AAClC,UAAQ,iBAAiB,YAAY,cAAc;AACnD,iBAAe,YAAY,MAAM;AACjC,SAAO,YAAY;AACnB,2BAAyB;AACzB,wBAAsB;AACtB,YAAU,YAAY;AACtB,MAAI,eAAe;;CAGrB,MAAM,gBAAgB,YAAoB;AACxC,iBAAe,QAAQ;AACvB,2BAAyB;AACzB,MAAI,eAAe;;CAGrB,MAAM,0BAA0B;AAC9B,cAAY,QAAQ;AACpB,iBAAe,YAAY;AAC3B,MAAI,eAAe;;CAGrB,MAAM,aAAa;EACjB,yBAAyB;EACzB,wBAAwB;EACxB,oBAAoB;EACpB,yBAAyB,mBAAmB;EAC7C;CAED,MAAM,gBAAgB,wBAAwB;EAC5C;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,wBAAwB,iBAAiB;EAC1C,CAAC;CAEF,MAAM,EAAE,sBAAsB,uBAAuB;EACnD;EACA;EACA;EACA;EACA;EACA,wBAAwB,YAAY,OAAO;EAC3C,yBAAyB,YAAY,QAAQ;EAC7C,uBAAuB,OAAO,SAAS;AACrC,SAAM,iBAAiB,KAAK,KAAK;;EAEpC,CAAC;CAWF,MAAM,cAAc,2BAA2B;EAC7C,QAViB,0BAA0B;GAC3C;GACA;GACA;GACA,gBAAgB;GAChB;GACA,gBAAgB;GACjB,CAGmB;EAClB,SAAS,yCAAyC;EACnD,CAAC;AACF,QAAO,WAAW;CAElB,MAAM,2BAA2B;AAC/B,MAAI,MAAM,cAAe;AACzB,MAAI,MAAM,YAAa;EACvB,MAAM,OAAO,MAAM,qBAAqB,OAAO;AAC/C,MAAI,SAAS,KAAA,EAAW;AACxB,cAAY,KAAK;;CAGnB,MAAM,uBAAuB;EAC3B,MAAM,OAAO,OAAO,SAAS,CAAC,MAAM;AACpC,MAAI,CAAC,KAAM;AACX,MAAI,aAAa,EAAE;AACjB,UAAO,aAAa,KAAK;AACzB,SAAM,qBAAqB,KAAK,KAAK;AACrC,UAAO,QAAQ,GAAG;AAClB,WAAQ,UACN,MAAM,IACJ,qBAAqB,MAAM,qBAAqB,OAAO,kDACxD,CACF;AACD,aAAU,YAAY;AACtB,OAAI,eAAe;AACnB;;AAEF,cAAY,KAAK;;CAGnB,MAAM,sBAAsB;AAC1B,MAAI,MAAM,qBAAqB,WAAW,GAAG;AAC3C,WAAQ,UAAU,MAAM,IAAI,iCAAiC,CAAC;AAC9D,OAAI,eAAe;AACnB;;EAEF,MAAM,SAAS,CAAC,GAAG,MAAM,qBAAqB;AAC9C,QAAM,qBAAqB,SAAS;EACpC,MAAM,UAAU,OAAO,SAAS,CAAC,MAAM;EACvC,MAAM,WAAW,CAAC,OAAO,KAAK,OAAO,EAAE,QAAQ,CAAC,OAAO,QAAQ,CAAC,KAAK,OAAO;AAC5E,SAAO,QAAQ,SAAS;AACxB,UAAQ,UACN,MAAM,IACJ,YAAY,OAAO,OAAO,iBAAiB,OAAO,SAAS,IAAI,MAAM,GAAG,aACzE,CACF;AACD,YAAU,YAAY;AACtB,MAAI,eAAe;;CAGrB,MAAM,iBAAiB,QAAgB;AACrC,QAAM,oBAAoB;;CAG5B,MAAM,kCAAkC;AACtC,YAAU,OAAO;AACjB,UAAQ,UAAU;AAClB,2BAAyB;AACzB,QAAM,gBAAgB;AACtB,QAAM,qBAAqB,SAAS;;CAGtC,MAAM,qBAAqB,YAAY;AACrC,MAAI;GACF,MAAM,EAAE,aAAa,MAAM,OAAO,YAAY;IAC5C,YAAY,MAAM;IAClB,OAAO;IACR,CAAC;AACF,0BAAuB,SAAS,UAAU,MAAM,cAAc;UACxD,WAEE;AACR,SAAM,gBAAgB;AACtB,OAAI,eAAe;;;CAIvB,IAAI,gBAAgB;CACpB,MAAM,oBAAoB;AACxB,MAAI,cAAe;AACnB,kBAAgB;AAChB,MAAI;GACF,MAAM,MAAM,KAAK,KAAK;GACtB,MAAM,WAAW,mBAAmB;IAClC,UAAU,OAAO,SAAS,CAAC,MAAM,CAAC,SAAS;IAC3C;IACA,aAAa,MAAM;IACpB,CAAC;AACF,SAAM,cAAc,SAAS;AAC7B,OAAI,SAAS,WAAW,SAAS;AAC/B,WAAO,QAAQ,GAAG;AAClB,sBAAkB,4CAA4C;AAC9D,QAAI,eAAe;AACnB;;AAEF,OAAI,SAAS,WAAW,QAAQ;AAC9B,iBAAa;AACb;;AAEF,qBAAkB,6BAA6B;AAC/C,OAAI,eAAe;YACX;AACR,mBAAgB;;;CAIpB,MAAM,mBAAmB,WAA6B;AACpD,iBAAe;;CAGjB,MAAM,YAAY;EAChB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,0BAA0B,MAAM;EAChC,qBAAqB,SAA0B;AAC7C,SAAM,kBAAkB;AACxB,uBAAoB,KAAK;;EAE3B;EACA,uBAAuB,EAAE,GAAG,aAAa;EACzC;EACA;EACA;EACD;AAED,YAAW,0BAA0B,KAAK,yBAAyB,UAAU;AAC7E,YAAW,yBAAyB,KAAK,wBAAwB,UAAU;AAC3E,YAAW,qBAAqB,oBAAoB,UAAU;CAE9D,MAAM,2BAA2B;AAC/B,UAAQ,YAAY,oBAApB;GACE,KAAK;AACH,YAAQ,UAAU,MAAM,IAAI,iDAAiD,CAAC;AAC9E;GACF,KAAK;AACH,YAAQ,UAAU,MAAM,IAAI,iDAAiD,CAAC;AAC9E;GACF,QACE;;AAEJ,MAAI,eAAe;;AAGrB,QAAO,iBAAiB;AACtB,MAAI,MAAM,aAAa;AAChB,gBAAa;AAClB;;AAEF,MAAI,OAAO,SAAS,CAAC,MAAM,CAAC,SAAS,EAAG;EACxC,MAAM,MAAM,KAAK,KAAK;AACtB,MAAI,MAAM,MAAM,gBAAgB,yBAAyB;AACvD,SAAM,eAAe;AACrB,uBAAoB;AACpB;;AAEF,QAAM,eAAe;;AAEvB,QAAO,gBAAgB,aAAa;AAEpC,QAAO,SAAS,aAAa,YAAY;AACzC,QAAO,SAAS,kBAAkB,aAAa,CAAC;AAChD,QAAO,SAAS,eAAe,YAAY;AAC3C,QAAO,SAAS,4BAA4B;AAE1C,cAAY,UAAU,eADV,MAAM,YAAY,iBAAiB,KAAK,YAAY,SACvB,GAAG;AAC5C,2BAAyB;GACzB;AACF,QAAO,SAAS,gCAAgC,WAAW,UAAU,CAAC;AACtE,QAAO,SAAS,iCAAiC,WAAW,WAAW,CAAC;AACxE,QAAO,SAAS,0BAA0B,KAAK,uBAAuB,UAAU,CAAC;AACjF,QAAO,SAAS,4BAA4B,KAAK,yBAAyB,UAAU,CAAC;AACrF,QAAO,SAAS,0BAA0B;AACxC,QAAM,gBAAgB,CAAC,MAAM;AAC7B,gBAAc;GAAE,GAAG;GAAa,eAAe,MAAM;GAAe;AACpE,kBAAgB,YAAY;AAC5B,UAAQ,iBAAiB,MAAM,cAAc;AAC7C,oBAAkB,MAAM,gBAAgB,mBAAmB,kBAAkB;AAC7E,MAAI,eAAe;GACnB;AACF,QAAO,SAAS,6BAA6B;AAC3C,QAAM,eAAe,CAAC,MAAM;AAC5B,gBAAc;GAAE,GAAG;GAAa,cAAc,MAAM;GAAc;AAClE,kBAAgB,YAAY;AAC5B,gBAAc;AACd,MAAI,eAAe;GACnB;AACF,QAAO,SAAS,uBAAuB,mBAAmB;AAC1D,QAAO,qBAAqB;AAC1B,GAAM,YAAY;GAChB,MAAM,WAAW,MAAM,8BAA8B;AACrD,OAAI,CAAC,SAAU;AACf,UAAO,mBAAmB,SAAS;AACnC,WAAQ,UAAU,MAAM,IAAI,sBAAsB,WAAW,CAAC;AAC9D,OAAI,eAAe;MACjB;;AAEN,QAAO,SAAS,wBAAwB,eAAe;AACvD,QAAO,SAAS,uBAAuB,cAAc;AAErD,oBAAmB,kBAAkB;AACnC,MAAI,CAAC,MAAM,YAAa;AACxB,MAAI,CAAC,WAAW,IAAI,MAAM,eAAe,CAAE;AAC3C,MAAI,KAAK,KAAK,GAAG,uBAAA,IAAsD;EAEvE,MAAM,MAAM,MAAM;EAClB,MAAM,YAAY,UAAU,SAAS,KAAK,MAAM,aAAa;AAC7D,MAAI,UACF,SAAQ,kBAAkB,WAAW,IAAI;AAE3C,UAAQ,UACN,iGACD;AACD,QAAM,cAAc;AACpB,oBAAkB,OAAO;AACpB,sBAAoB,CAAC,cAAc;AACtC,iBAAc;AACd,OAAI,eAAe;IACnB;AACF,sBAAoB;AACpB,MAAI,eAAe;IAClB,IAAK;CAER,MAAM,wBAAwB;AAC5B,QAAM,kBAAkB;AACnB,sBAAoB,CAAC,cAAc;AACtC,iBAAc;AACd,OAAI,eAAe;IACnB;AACF,sBAAoB;;AAGtB,QAAO,WAAW,QAAkB;EAClC,MAAM,OAAQ,IAAI,QAAQ,EAAE;AAC5B,mBACE,IAAI,OACJ,MACA,OACA,SACA,WACA,KACA,mBACA,wBACA,gBACD;;AAGH,QAAO,oBAAoB;AACzB,QAAM,cAAc;AACpB,sBAAoB,cAAc,gBAAgB,oBAAoB;AACtE,0BAAwB;AACxB,GAAM,YAAY;AAChB,SAAM,oBAAoB;AAC1B,SAAM,qBAAqB;AAC3B,SAAM,oBAAoB;AAC1B,iBAAc;AACd,iBAAc;AACd,OAAI,eAAe;AACnB,OAAI,CAAC,MAAM,mBAAmB,KAAK,SAAS;AAC1C,UAAM,kBAAkB;AACxB,gBAAY,KAAK,QAAQ;;MAEzB;;AAGN,QAAO,kBAAkB,WAAmB;EAC1C,MAAM,eAAe,MAAM;AAC3B,QAAM,cAAc;AACpB,0BAAwB;AACxB,MAAI,YACF,qBAAoB,kBAAkB,SAAS;OAC1C;AAKL,uBAAoB,eAHlB,gBAAgB,MAAM,gBAClB,KAAK,OAAO,qCACZ,+DACoC;AAC1C,OAAI,CAAC,gBAAgB,CAAC,MAAM,eAAe;IACzC,MAAM,aAAa,KAAK,OAAO;AAC/B,YAAQ,UACN,2BAA2B,WAAW,wFAEvC;;;AAGL,MAAI,eAAe;;AAGrB,QAAO,SAAS,SAAS;AACvB,UAAQ,UACN,0BAA0B,KAAK,SAAS,aAAa,KAAK,SAAS,gCACpE;AACD,sBAAoB,uBAAuB,KAAK,SAAS,QAAQ,KAAK,WAAW;AACjF,MAAI,eAAe;;CAGrB,MAAM,sBAAsB,aAAa;CACzC,MAAM,uBAAuB,aAAa;AAC1C,SAAQ,GAAG,UAAU,cAAc;AACnC,SAAQ,GAAG,WAAW,eAAe;AAErC,eAAc;AACd,0BAAyB;AACzB,qBAAoB,cAAc,2BAA2B,aAAa;AAC1E,eAAc;AACd,OAAM,iBAAiB,UAAU;AACjC,KAAI,OAAO;AACX,QAAO,OAAO;AAEd,OAAM,IAAI,SAAe,YAAY;AACnC,oBAAkB;AAChB,WAAQ,eAAe,UAAU,cAAc;AAC/C,WAAQ,eAAe,WAAW,eAAe;AACjD,OAAI,kBAAkB;AACpB,kBAAc,iBAAiB;AAC/B,uBAAmB;;AAErB,eAAY;AACZ,YAAS;;GAEX;AAEF,QAAO"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export { createXopcTuiKeybindingsManager, XopcKeybindingsManager } from './tui-keybindings-file.js';
|
|
2
1
|
/** App-level bindings wired by xopc TUI (subset of pi coding-agent). */
|
|
3
2
|
export type XopcTuiAppKeybinding = 'app.interrupt' | 'app.clear' | 'app.exit' | 'app.suspend' | 'app.thinking.cycle' | 'app.model.cycleForward' | 'app.model.cycleBackward' | 'app.model.select' | 'app.tools.expand' | 'app.thinking.toggle' | 'app.session.resume' | 'app.editor.external' | 'app.clipboard.pasteImage' | 'app.message.followUp' | 'app.message.dequeue';
|
|
4
3
|
declare module '@earendil-works/pi-tui' {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { XopcKeybindingsManager, createXopcTuiKeybindingsManager } from "./tui-keybindings-file.js";
|
|
2
1
|
import { TUI_KEYBINDINGS } from "@earendil-works/pi-tui";
|
|
3
2
|
//#region src/tui/xopc-tui-keybindings.ts
|
|
4
3
|
const XOPC_TUI_KEYBINDINGS = {
|
|
@@ -83,6 +82,6 @@ const XOPC_TUI_HOTKEY_ORDER = [
|
|
|
83
82
|
"app.message.dequeue"
|
|
84
83
|
];
|
|
85
84
|
//#endregion
|
|
86
|
-
export { XOPC_TUI_HOTKEY_ORDER, XOPC_TUI_KEYBINDINGS
|
|
85
|
+
export { XOPC_TUI_HOTKEY_ORDER, XOPC_TUI_KEYBINDINGS };
|
|
87
86
|
|
|
88
87
|
//# sourceMappingURL=xopc-tui-keybindings.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xopc-tui-keybindings.js","names":[],"sources":["../../../src/tui/xopc-tui-keybindings.ts"],"sourcesContent":["import {\n TUI_KEYBINDINGS,\n type KeybindingDefinitions,\n} from '@earendil-works/pi-tui';\n\
|
|
1
|
+
{"version":3,"file":"xopc-tui-keybindings.js","names":[],"sources":["../../../src/tui/xopc-tui-keybindings.ts"],"sourcesContent":["import {\n TUI_KEYBINDINGS,\n type KeybindingDefinitions,\n} from '@earendil-works/pi-tui';\n\n// Re-export removed — `./tui-keybindings-file.js` imports `XOPC_TUI_KEYBINDINGS`\n// from this file, so re-exporting from it created a circular cycle. Callers\n// (tui.ts, test files) import the manager directly from `./tui-keybindings-file.js`.\n\n/** App-level bindings wired by xopc TUI (subset of pi coding-agent). */\nexport type XopcTuiAppKeybinding =\n | 'app.interrupt'\n | 'app.clear'\n | 'app.exit'\n | 'app.suspend'\n | 'app.thinking.cycle'\n | 'app.model.cycleForward'\n | 'app.model.cycleBackward'\n | 'app.model.select'\n | 'app.tools.expand'\n | 'app.thinking.toggle'\n | 'app.session.resume'\n | 'app.editor.external'\n | 'app.clipboard.pasteImage'\n | 'app.message.followUp'\n | 'app.message.dequeue';\n\ndeclare module '@earendil-works/pi-tui' {\n interface Keybindings {\n 'app.interrupt': true;\n 'app.clear': true;\n 'app.exit': true;\n 'app.suspend': true;\n 'app.thinking.cycle': true;\n 'app.model.cycleForward': true;\n 'app.model.cycleBackward': true;\n 'app.model.select': true;\n 'app.tools.expand': true;\n 'app.thinking.toggle': true;\n 'app.session.resume': true;\n 'app.editor.external': true;\n 'app.clipboard.pasteImage': true;\n 'app.message.followUp': true;\n 'app.message.dequeue': true;\n }\n}\n\nexport const XOPC_TUI_KEYBINDINGS = {\n ...TUI_KEYBINDINGS,\n 'app.interrupt': { defaultKeys: 'escape', description: 'Abort run (or cancel overlay)' },\n 'app.clear': { defaultKeys: 'ctrl+c', description: 'Clear input; repeat within 0.5s to exit' },\n 'app.exit': { defaultKeys: 'ctrl+d', description: 'Exit when input empty' },\n 'app.suspend': {\n defaultKeys: process.platform === 'win32' ? [] : 'ctrl+z',\n description: 'Suspend to shell (SIGTSTP)',\n },\n 'app.thinking.cycle': {\n defaultKeys: 'shift+tab',\n description: 'Cycle /think level',\n },\n 'app.model.cycleForward': {\n defaultKeys: 'ctrl+p',\n description: 'Next model (/switch)',\n },\n 'app.model.cycleBackward': {\n defaultKeys: 'shift+ctrl+p',\n description: 'Previous model (/switch)',\n },\n 'app.model.select': { defaultKeys: 'ctrl+l', description: 'Model picker' },\n 'app.tools.expand': { defaultKeys: 'ctrl+o', description: 'Toggle tool output' },\n 'app.thinking.toggle': {\n defaultKeys: 'ctrl+t',\n description: 'Toggle thinking block display',\n },\n 'app.session.resume': {\n defaultKeys: 'ctrl+shift+p',\n description: 'Session picker',\n },\n 'app.editor.external': {\n defaultKeys: 'ctrl+g',\n description: 'Edit input in $EDITOR',\n },\n 'app.clipboard.pasteImage': {\n defaultKeys: process.platform === 'win32' ? 'alt+v' : 'ctrl+v',\n description: 'Paste image from clipboard (placeholder)',\n },\n 'app.message.followUp': {\n defaultKeys: 'alt+enter',\n description: 'Queue message while busy (or submit when idle)',\n },\n 'app.message.dequeue': {\n defaultKeys: 'alt+up',\n description: 'Restore queued messages to editor',\n },\n} as const satisfies KeybindingDefinitions;\n\n/** Order for `/hotkeys` and docs (pi-style UX). */\nexport const XOPC_TUI_HOTKEY_ORDER: XopcTuiAppKeybinding[] = [\n 'app.interrupt',\n 'app.clear',\n 'app.exit',\n 'app.suspend',\n 'app.thinking.cycle',\n 'app.model.cycleForward',\n 'app.model.cycleBackward',\n 'app.model.select',\n 'app.session.resume',\n 'app.tools.expand',\n 'app.thinking.toggle',\n 'app.editor.external',\n 'app.clipboard.pasteImage',\n 'app.message.followUp',\n 'app.message.dequeue',\n];\n"],"mappings":";;AA+CA,MAAa,uBAAuB;CAClC,GAAG;CACH,iBAAiB;EAAE,aAAa;EAAU,aAAa;EAAiC;CACxF,aAAa;EAAE,aAAa;EAAU,aAAa;EAA2C;CAC9F,YAAY;EAAE,aAAa;EAAU,aAAa;EAAyB;CAC3E,eAAe;EACb,aAAa,QAAQ,aAAa,UAAU,EAAE,GAAG;EACjD,aAAa;EACd;CACD,sBAAsB;EACpB,aAAa;EACb,aAAa;EACd;CACD,0BAA0B;EACxB,aAAa;EACb,aAAa;EACd;CACD,2BAA2B;EACzB,aAAa;EACb,aAAa;EACd;CACD,oBAAoB;EAAE,aAAa;EAAU,aAAa;EAAgB;CAC1E,oBAAoB;EAAE,aAAa;EAAU,aAAa;EAAsB;CAChF,uBAAuB;EACrB,aAAa;EACb,aAAa;EACd;CACD,sBAAsB;EACpB,aAAa;EACb,aAAa;EACd;CACD,uBAAuB;EACrB,aAAa;EACb,aAAa;EACd;CACD,4BAA4B;EAC1B,aAAa,QAAQ,aAAa,UAAU,UAAU;EACtD,aAAa;EACd;CACD,wBAAwB;EACtB,aAAa;EACb,aAAa;EACd;CACD,uBAAuB;EACrB,aAAa;EACb,aAAa;EACd;CACF;;AAGD,MAAa,wBAAgD;CAC3D;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD"}
|
|
@@ -2,10 +2,10 @@ import { createLogger } from "../utils/logger/index.js";
|
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
3
|
import { init_paths, resolveBinDir } from "../config/paths.js";
|
|
4
4
|
import { extractFrpcFromReleaseArchive, frpcReleaseArchiveExtension, nodePlatformForFrpTarget } from "./frpc-extract.js";
|
|
5
|
+
import { randomBytes } from "node:crypto";
|
|
6
|
+
import { chmodSync, createWriteStream, existsSync, mkdirSync, rmSync } from "node:fs";
|
|
5
7
|
import { join } from "node:path";
|
|
6
8
|
import { tmpdir } from "node:os";
|
|
7
|
-
import { chmodSync, createWriteStream, existsSync, mkdirSync, rmSync } from "node:fs";
|
|
8
|
-
import { randomBytes } from "node:crypto";
|
|
9
9
|
import { Readable } from "node:stream";
|
|
10
10
|
import { pipeline } from "node:stream/promises";
|
|
11
11
|
//#region src/tunnel/frpc-binary.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolveStateDir } from "../config/paths-state.js";
|
|
2
2
|
import { init_paths } from "../config/paths.js";
|
|
3
|
-
import { join } from "node:path";
|
|
4
3
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
5
|
//#region src/tunnel/frpc-config.ts
|
|
6
6
|
init_paths();
|
|
7
7
|
function resolveFrpcConfigPath(tunnelId) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
-
import { dirname, join } from "node:path";
|
|
4
3
|
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
6
|
import AdmZip from "adm-zip";
|
|
7
7
|
import { gunzipSync } from "node:zlib";
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export type PairingFailureLimitResult = {
|
|
2
|
+
allowed: boolean;
|
|
3
|
+
retryAfterMs: number;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Records a failed pairing exchange and returns whether subsequent attempts
|
|
7
|
+
* are still permitted. Called from the route handler on every invalid /
|
|
8
|
+
* expired pairing secret — successful exchanges do NOT call this.
|
|
9
|
+
*/
|
|
10
|
+
export declare function consumePairingExchangeFailLimit(clientKey: string): PairingFailureLimitResult;
|
|
3
11
|
/** @internal */
|
|
4
12
|
export declare function resetPairingExchangeLimitsForTests(): void;
|
|
@@ -1,24 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { buckets } from "../gateway/rate-limit/buckets.js";
|
|
2
|
+
import "../gateway/rate-limit/index.js";
|
|
2
3
|
//#region src/tunnel/pairing-rate-limit.ts
|
|
3
|
-
/**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Records a failed pairing exchange and returns whether subsequent attempts
|
|
6
|
+
* are still permitted. Called from the route handler on every invalid /
|
|
7
|
+
* expired pairing secret — successful exchanges do NOT call this.
|
|
8
|
+
*/
|
|
7
9
|
function consumePairingExchangeFailLimit(clientKey) {
|
|
10
|
+
const fl = buckets.pairingExchange();
|
|
8
11
|
const key = clientKey.trim() || "unknown";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
fl.fail(key);
|
|
13
|
+
const status = fl.check(key);
|
|
14
|
+
if (status.blocked) return {
|
|
15
|
+
allowed: false,
|
|
16
|
+
retryAfterMs: status.retryAfterSec * 1e3
|
|
17
|
+
};
|
|
18
|
+
return {
|
|
19
|
+
allowed: true,
|
|
20
|
+
retryAfterMs: 0
|
|
21
|
+
};
|
|
18
22
|
}
|
|
19
23
|
/** @internal */
|
|
20
24
|
function resetPairingExchangeLimitsForTests() {
|
|
21
|
-
|
|
25
|
+
buckets.pairingExchange().resetForTests();
|
|
22
26
|
}
|
|
23
27
|
//#endregion
|
|
24
28
|
export { consumePairingExchangeFailLimit, resetPairingExchangeLimitsForTests };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pairing-rate-limit.js","names":[],"sources":["../../../src/tunnel/pairing-rate-limit.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"pairing-rate-limit.js","names":[],"sources":["../../../src/tunnel/pairing-rate-limit.ts"],"sourcesContent":["import { buckets } from '../gateway/rate-limit/index.js';\n\nexport type PairingFailureLimitResult = {\n allowed: boolean;\n retryAfterMs: number;\n};\n\n/**\n * Records a failed pairing exchange and returns whether subsequent attempts\n * are still permitted. Called from the route handler on every invalid /\n * expired pairing secret — successful exchanges do NOT call this.\n */\nexport function consumePairingExchangeFailLimit(clientKey: string): PairingFailureLimitResult {\n const fl = buckets.pairingExchange();\n const key = clientKey.trim() || 'unknown';\n fl.fail(key);\n const status = fl.check(key);\n if (status.blocked) {\n return { allowed: false, retryAfterMs: status.retryAfterSec * 1000 };\n }\n return { allowed: true, retryAfterMs: 0 };\n}\n\n/** @internal */\nexport function resetPairingExchangeLimitsForTests(): void {\n buckets.pairingExchange().resetForTests();\n}\n"],"mappings":";;;;;;;;AAYA,SAAgB,gCAAgC,WAA8C;CAC5F,MAAM,KAAK,QAAQ,iBAAiB;CACpC,MAAM,MAAM,UAAU,MAAM,IAAI;AAChC,IAAG,KAAK,IAAI;CACZ,MAAM,SAAS,GAAG,MAAM,IAAI;AAC5B,KAAI,OAAO,QACT,QAAO;EAAE,SAAS;EAAO,cAAc,OAAO,gBAAgB;EAAM;AAEtE,QAAO;EAAE,SAAS;EAAM,cAAc;EAAG;;;AAI3C,SAAgB,qCAA2C;AACzD,SAAQ,iBAAiB,CAAC,eAAe"}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export type TunnelMutationLimitResult = {
|
|
2
|
+
allowed: boolean;
|
|
3
|
+
retryAfterMs: number;
|
|
4
|
+
};
|
|
5
|
+
export declare function consumeTunnelMutationLimit(token: string): TunnelMutationLimitResult;
|
|
6
|
+
/** @internal */
|
|
4
7
|
export declare function resetTunnelMutationLimitsForTests(): void;
|
|
@@ -1,40 +1,29 @@
|
|
|
1
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
-
import {
|
|
3
|
+
import { buckets } from "../gateway/rate-limit/buckets.js";
|
|
4
|
+
import "../gateway/rate-limit/index.js";
|
|
4
5
|
import { createHash } from "node:crypto";
|
|
5
6
|
//#region src/tunnel/tunnel-rate-limit.ts
|
|
6
7
|
init_logger();
|
|
7
8
|
const log = createLogger("TunnelRateLimit");
|
|
8
|
-
|
|
9
|
-
const TUNNEL_MUTATION_MAX = 12;
|
|
10
|
-
const TUNNEL_MUTATION_WINDOW_MS = 5 * 6e4;
|
|
11
|
-
const limiters = /* @__PURE__ */ new Map();
|
|
12
|
-
function limiterKeyFromToken(token) {
|
|
9
|
+
function tokenKey(token) {
|
|
13
10
|
return createHash("sha256").update(token, "utf8").digest("hex").slice(0, 16);
|
|
14
11
|
}
|
|
15
12
|
function consumeTunnelMutationLimit(token) {
|
|
16
|
-
const
|
|
17
|
-
let limiter = limiters.get(key);
|
|
18
|
-
if (!limiter) {
|
|
19
|
-
limiter = createFixedWindowRateLimiter({
|
|
20
|
-
maxRequests: TUNNEL_MUTATION_MAX,
|
|
21
|
-
windowMs: TUNNEL_MUTATION_WINDOW_MS
|
|
22
|
-
});
|
|
23
|
-
limiters.set(key, limiter);
|
|
24
|
-
}
|
|
25
|
-
const result = limiter.consume();
|
|
13
|
+
const result = buckets.tunnelMutate().consume(tokenKey(token));
|
|
26
14
|
if (!result.allowed) log.warn({
|
|
27
15
|
tokenPrefix: token.slice(0, 8),
|
|
28
|
-
limit: TUNNEL_MUTATION_MAX,
|
|
29
|
-
windowSec: Math.round(TUNNEL_MUTATION_WINDOW_MS / 1e3),
|
|
30
16
|
retryAfterSec: Math.ceil(result.retryAfterMs / 1e3),
|
|
31
17
|
reason: "tunnel_mutation_limit"
|
|
32
|
-
},
|
|
33
|
-
return
|
|
18
|
+
}, "Tunnel mutation rate limit exceeded");
|
|
19
|
+
return {
|
|
20
|
+
allowed: result.allowed,
|
|
21
|
+
retryAfterMs: result.retryAfterMs
|
|
22
|
+
};
|
|
34
23
|
}
|
|
35
|
-
/** @internal
|
|
24
|
+
/** @internal */
|
|
36
25
|
function resetTunnelMutationLimitsForTests() {
|
|
37
|
-
|
|
26
|
+
buckets.tunnelMutate().resetForTests();
|
|
38
27
|
}
|
|
39
28
|
//#endregion
|
|
40
29
|
export { consumeTunnelMutationLimit, resetTunnelMutationLimitsForTests };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tunnel-rate-limit.js","names":[],"sources":["../../../src/tunnel/tunnel-rate-limit.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\n\nimport {
|
|
1
|
+
{"version":3,"file":"tunnel-rate-limit.js","names":[],"sources":["../../../src/tunnel/tunnel-rate-limit.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\n\nimport { buckets } from '../gateway/rate-limit/index.js';\nimport { createLogger } from '../utils/logger.js';\n\nconst log = createLogger('TunnelRateLimit');\n\nfunction tokenKey(token: string): string {\n return createHash('sha256').update(token, 'utf8').digest('hex').slice(0, 16);\n}\n\nexport type TunnelMutationLimitResult = {\n allowed: boolean;\n retryAfterMs: number;\n};\n\nexport function consumeTunnelMutationLimit(token: string): TunnelMutationLimitResult {\n const result = buckets.tunnelMutate().consume(tokenKey(token));\n if (!result.allowed) {\n log.warn(\n {\n tokenPrefix: token.slice(0, 8),\n retryAfterSec: Math.ceil(result.retryAfterMs / 1000),\n reason: 'tunnel_mutation_limit',\n },\n 'Tunnel mutation rate limit exceeded',\n );\n }\n return { allowed: result.allowed, retryAfterMs: result.retryAfterMs };\n}\n\n/** @internal */\nexport function resetTunnelMutationLimitsForTests(): void {\n buckets.tunnelMutate().resetForTests();\n}\n"],"mappings":";;;;;;aAGkD;AAElD,MAAM,MAAM,aAAa,kBAAkB;AAE3C,SAAS,SAAS,OAAuB;AACvC,QAAO,WAAW,SAAS,CAAC,OAAO,OAAO,OAAO,CAAC,OAAO,MAAM,CAAC,MAAM,GAAG,GAAG;;AAQ9E,SAAgB,2BAA2B,OAA0C;CACnF,MAAM,SAAS,QAAQ,cAAc,CAAC,QAAQ,SAAS,MAAM,CAAC;AAC9D,KAAI,CAAC,OAAO,QACV,KAAI,KACF;EACE,aAAa,MAAM,MAAM,GAAG,EAAE;EAC9B,eAAe,KAAK,KAAK,OAAO,eAAe,IAAK;EACpD,QAAQ;EACT,EACD,sCACD;AAEH,QAAO;EAAE,SAAS,OAAO;EAAS,cAAc,OAAO;EAAc;;;AAIvE,SAAgB,oCAA0C;AACxD,SAAQ,cAAc,CAAC,eAAe"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolveStateDir } from "../config/paths-state.js";
|
|
2
2
|
import { init_paths } from "../config/paths.js";
|
|
3
|
-
import { join } from "node:path";
|
|
4
3
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
5
|
//#region src/tunnel/tunnel-state.ts
|
|
6
6
|
init_paths();
|
|
7
7
|
const TUNNEL_STATE_FILE = "tunnel.json";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { __esmMin } from "../../../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { getLogDir, init_config } from "./config.js";
|
|
3
|
+
import { appendFile } from "fs/promises";
|
|
3
4
|
import path from "path";
|
|
4
5
|
import { existsSync, mkdirSync } from "fs";
|
|
5
|
-
import { appendFile } from "fs/promises";
|
|
6
6
|
//#region src/utils/logger/audit.ts
|
|
7
7
|
/**
|
|
8
8
|
* Audit Log
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { readFile } from "fs/promises";
|
|
1
2
|
import { basename, join } from "path";
|
|
2
3
|
import { createReadStream, existsSync, mkdirSync, readdirSync, statSync, unlinkSync } from "fs";
|
|
3
|
-
import { readFile } from "fs/promises";
|
|
4
4
|
import { gunzip } from "zlib";
|
|
5
5
|
import { promisify } from "util";
|
|
6
6
|
import { createInterface } from "readline";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { __esmMin } from "../../../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { config, getLogDir, init_config } from "./config.js";
|
|
3
|
+
import { writeFile } from "fs/promises";
|
|
3
4
|
import { join } from "path";
|
|
4
5
|
import { readFileSync, readdirSync, statSync, unlinkSync } from "fs";
|
|
5
|
-
import { writeFile } from "fs/promises";
|
|
6
6
|
import { gzip } from "zlib";
|
|
7
7
|
import { promisify } from "util";
|
|
8
8
|
//#region src/utils/logger/rotation.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { join } from "path";
|
|
4
3
|
import { unlink, writeFile } from "fs/promises";
|
|
4
|
+
import { join } from "path";
|
|
5
5
|
import { spawn } from "child_process";
|
|
6
6
|
import { tmpdir } from "os";
|
|
7
7
|
//#region src/voice/tts/audio.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { buildTtsResolveRawConfig } from "./config-slice.js";
|
|
4
3
|
import { getSpeechProvider, listSpeechProviders } from "./speech-registry.js";
|
|
5
4
|
import "./providers/index.js";
|
|
5
|
+
import { buildTtsResolveRawConfig } from "./config-slice.js";
|
|
6
6
|
//#region src/voice/tts/factory.ts
|
|
7
7
|
init_logger();
|
|
8
8
|
const log = createLogger("TTS:Factory");
|
|
@@ -4,11 +4,11 @@ import { alibabaSpeechProvider } from "./providers/alibaba-speech.js";
|
|
|
4
4
|
import { edgeSpeechProvider } from "./providers/edge-speech.js";
|
|
5
5
|
import { MINIMAX_TTS_MODELS, MINIMAX_TTS_VOICES, minimaxSpeechProvider } from "./providers/minimax-speech.js";
|
|
6
6
|
import "./providers/index.js";
|
|
7
|
-
import { getAvailableProviders, isProviderConfigured, isTTSAvailable, listRegisteredSpeechProviderIds, resolveProviderOrder, resolveSpeechProvider, resolveSpeechProviderChain } from "./factory.js";
|
|
8
|
-
import { appendTtsReadinessNote, formatTtsSetupHint, mergeTtsConfigFromAppConfig } from "./merge-config.js";
|
|
9
7
|
import { buildTtsSystemPromptHint, hasTtsDirectives, parseTtsDirectives, stripTtsDirectives } from "./directives.js";
|
|
8
|
+
import { getAvailableProviders, isProviderConfigured, isTTSAvailable, listRegisteredSpeechProviderIds, resolveProviderOrder, resolveSpeechProvider, resolveSpeechProviderChain } from "./factory.js";
|
|
10
9
|
import { preprocessText } from "./preprocess.js";
|
|
11
10
|
import { speak, speakStream, speakWithProvider } from "./speak-core.js";
|
|
11
|
+
import { appendTtsReadinessNote, formatTtsSetupHint, mergeTtsConfigFromAppConfig } from "./merge-config.js";
|
|
12
12
|
import { TTSService, getChannelOutputFormat, getSupportedChannels, isVoiceCompatibleChannel, shouldUseTTS } from "./service.js";
|
|
13
13
|
import { recordTtsFailure, recordTtsSuccess, ttsStatusTracker } from "./status-tracker.js";
|
|
14
14
|
import { isTtsEnabled, maybeApplyTtsToPayload, resolveTtsAutoMode } from "./payload.js";
|