@wrongstack/cli 0.295.1 → 0.296.3
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/data/providers.json +0 -24
- package/dist/acp-A5OSIU2P.js +824 -0
- package/dist/acp-A5OSIU2P.js.map +7 -0
- package/dist/acp-server-agent.d.ts.map +1 -1
- package/dist/arg-parser.d.ts.map +1 -1
- package/dist/audit-2ZSFGNIF.js +102 -0
- package/dist/audit-2ZSFGNIF.js.map +7 -0
- package/dist/auth-CJWQJVRH.js +504 -0
- package/dist/auth-CJWQJVRH.js.map +7 -0
- package/dist/auth-menu/auth-menu-audit.d.ts +0 -4
- package/dist/auth-menu/auth-menu-audit.d.ts.map +1 -1
- package/dist/bench-7ZDWSNEF.js +278 -0
- package/dist/bench-7ZDWSNEF.js.map +7 -0
- package/dist/boot/brain-decision-log.d.ts +7 -5
- package/dist/boot/brain-decision-log.d.ts.map +1 -1
- package/dist/boot/dispatch-webui.d.ts +5 -8
- package/dist/boot/dispatch-webui.d.ts.map +1 -1
- package/dist/boot/system-prompt-builder.d.ts +3 -0
- package/dist/boot/system-prompt-builder.d.ts.map +1 -1
- package/dist/boot/tui-coordinator-callbacks.d.ts +45 -0
- package/dist/boot/tui-coordinator-callbacks.d.ts.map +1 -0
- package/dist/boot/tui-project-switch.d.ts +2 -3
- package/dist/boot/tui-project-switch.d.ts.map +1 -1
- package/dist/boot/tui-runtime-state.d.ts +5 -6
- package/dist/boot/tui-runtime-state.d.ts.map +1 -1
- package/dist/boot/tui-session-resume.d.ts.map +1 -1
- package/dist/boot/tui-settings-adapter.d.ts +2 -3
- package/dist/boot/tui-settings-adapter.d.ts.map +1 -1
- package/dist/boot.d.ts.map +1 -1
- package/dist/brain-menu/panel-service.d.ts.map +1 -1
- package/dist/chimera-review-task.d.ts +6 -0
- package/dist/chimera-review-task.d.ts.map +1 -0
- package/dist/chimera-reviewer-policy.d.ts +34 -0
- package/dist/chimera-reviewer-policy.d.ts.map +1 -0
- package/dist/chronicle-QQEQFSSE.js +256 -0
- package/dist/chronicle-QQEQFSSE.js.map +7 -0
- package/dist/chunk-5N34EWJR.js +418 -0
- package/dist/chunk-5N34EWJR.js.map +7 -0
- package/dist/chunk-66T43Q4Y.js +90 -0
- package/dist/chunk-66T43Q4Y.js.map +7 -0
- package/dist/chunk-7OCVIDC7.js +11 -0
- package/dist/chunk-7OCVIDC7.js.map +7 -0
- package/dist/chunk-ABXK4VVY.js +84 -0
- package/dist/chunk-ABXK4VVY.js.map +7 -0
- package/dist/chunk-AXVZMEWG.js +306 -0
- package/dist/chunk-AXVZMEWG.js.map +7 -0
- package/dist/chunk-AZESNNIC.js +216 -0
- package/dist/chunk-AZESNNIC.js.map +7 -0
- package/dist/chunk-BGFM3PD7.js +41 -0
- package/dist/chunk-BGFM3PD7.js.map +7 -0
- package/dist/chunk-BQCAJ7FI.js +425 -0
- package/dist/chunk-BQCAJ7FI.js.map +7 -0
- package/dist/chunk-DPJZQCVP.js +13 -0
- package/dist/chunk-DPJZQCVP.js.map +7 -0
- package/dist/chunk-F4PEGAJZ.js +176 -0
- package/dist/chunk-F4PEGAJZ.js.map +7 -0
- package/dist/chunk-IHBYBYGA.js +443 -0
- package/dist/chunk-IHBYBYGA.js.map +7 -0
- package/dist/chunk-JBSQ7ONN.js +1023 -0
- package/dist/chunk-JBSQ7ONN.js.map +7 -0
- package/dist/chunk-JBTFWWKV.js +1325 -0
- package/dist/chunk-JBTFWWKV.js.map +7 -0
- package/dist/chunk-JUHRI6OV.js +100 -0
- package/dist/chunk-JUHRI6OV.js.map +7 -0
- package/dist/chunk-OI7GWJDS.js +3303 -0
- package/dist/chunk-OI7GWJDS.js.map +7 -0
- package/dist/chunk-OP47B3IX.js +142 -0
- package/dist/chunk-OP47B3IX.js.map +7 -0
- package/dist/chunk-PJHET45A.js +158 -0
- package/dist/chunk-PJHET45A.js.map +7 -0
- package/dist/chunk-Q5GTM25S.js +17 -0
- package/dist/chunk-Q5GTM25S.js.map +7 -0
- package/dist/chunk-QD544J2B.js +19 -0
- package/dist/chunk-QD544J2B.js.map +7 -0
- package/dist/chunk-QUNHS6O3.js +258 -0
- package/dist/chunk-QUNHS6O3.js.map +7 -0
- package/dist/chunk-TADVX644.js +480 -0
- package/dist/chunk-TADVX644.js.map +7 -0
- package/dist/chunk-TGDHN4LM.js +81 -0
- package/dist/chunk-TGDHN4LM.js.map +7 -0
- package/dist/chunk-TYO2OVAD.js +50 -0
- package/dist/chunk-TYO2OVAD.js.map +7 -0
- package/dist/chunk-VCYZ3WZV.js +14 -0
- package/dist/chunk-VCYZ3WZV.js.map +7 -0
- package/dist/chunk-VJUEZZYB.js +29 -0
- package/dist/chunk-VJUEZZYB.js.map +7 -0
- package/dist/chunk-WHOIR577.js +1 -0
- package/dist/chunk-WHOIR577.js.map +7 -0
- package/dist/chunk-WY7KKOUK.js +460 -0
- package/dist/chunk-WY7KKOUK.js.map +7 -0
- package/dist/chunk-XJXDOF63.js +28 -0
- package/dist/chunk-XJXDOF63.js.map +7 -0
- package/dist/chunk-XWEGWYDU.js +560 -0
- package/dist/chunk-XWEGWYDU.js.map +7 -0
- package/dist/chunk-YWUPHRGB.js +346 -0
- package/dist/chunk-YWUPHRGB.js.map +7 -0
- package/dist/chunk-Z7YGASQP.js +313 -0
- package/dist/chunk-Z7YGASQP.js.map +7 -0
- package/dist/cli-entry-main.d.ts +2 -0
- package/dist/cli-entry-main.d.ts.map +1 -0
- package/dist/cli-entry-point.d.ts +3 -3
- package/dist/cli-entry-point.d.ts.map +1 -1
- package/dist/cli-main-RTY35OPD.js +29268 -0
- package/dist/cli-main-RTY35OPD.js.map +7 -0
- package/dist/cli-main-helpers.d.ts +21 -0
- package/dist/cli-main-helpers.d.ts.map +1 -0
- package/dist/cli-main.d.ts +25 -1
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/context-limit.d.ts +48 -0
- package/dist/context-limit.d.ts.map +1 -1
- package/dist/diag-doctor-OQ3AA63O.js +170 -0
- package/dist/diag-doctor-OQ3AA63O.js.map +7 -0
- package/dist/execute-deps.d.ts +11 -12
- package/dist/execute-deps.d.ts.map +1 -1
- package/dist/execution-O7I5DYE6.js +4682 -0
- package/dist/execution-O7I5DYE6.js.map +7 -0
- package/dist/execution-chimera-ask.d.ts +10 -0
- package/dist/execution-chimera-ask.d.ts.map +1 -0
- package/dist/execution-chimera-cascade.d.ts +15 -0
- package/dist/execution-chimera-cascade.d.ts.map +1 -0
- package/dist/execution-cleanup.d.ts +23 -0
- package/dist/execution-cleanup.d.ts.map +1 -0
- package/dist/execution-kanban-dispatch.d.ts +10 -0
- package/dist/execution-kanban-dispatch.d.ts.map +1 -0
- package/dist/execution-repl-fleet-callbacks.d.ts +11 -0
- package/dist/execution-repl-fleet-callbacks.d.ts.map +1 -0
- package/dist/execution-storage-observability.d.ts +3 -0
- package/dist/execution-storage-observability.d.ts.map +1 -0
- package/dist/execution-tui-next-step-callbacks.d.ts +20 -0
- package/dist/execution-tui-next-step-callbacks.d.ts.map +1 -0
- package/dist/execution.d.ts +2 -139
- package/dist/execution.d.ts.map +1 -1
- package/dist/export-TPORYVRZ.js +64 -0
- package/dist/export-TPORYVRZ.js.map +7 -0
- package/dist/fleet/host-acp-runner-cache.d.ts +9 -0
- package/dist/fleet/host-acp-runner-cache.d.ts.map +1 -0
- package/dist/fleet/host-acp.d.ts +3 -0
- package/dist/fleet/host-acp.d.ts.map +1 -0
- package/dist/fleet/host-concurrency.d.ts +2 -0
- package/dist/fleet/host-concurrency.d.ts.map +1 -0
- package/dist/fleet/host-context.d.ts +5 -0
- package/dist/fleet/host-context.d.ts.map +1 -0
- package/dist/fleet/host-director-builder.d.ts +24 -0
- package/dist/fleet/host-director-builder.d.ts.map +1 -0
- package/dist/fleet/host-director-event-bridges.d.ts +37 -0
- package/dist/fleet/host-director-event-bridges.d.ts.map +1 -0
- package/dist/fleet/host-director-services.d.ts +20 -0
- package/dist/fleet/host-director-services.d.ts.map +1 -0
- package/dist/fleet/host-event-bridge.d.ts +17 -0
- package/dist/fleet/host-event-bridge.d.ts.map +1 -0
- package/dist/fleet/host-helpers.d.ts +22 -0
- package/dist/fleet/host-helpers.d.ts.map +1 -0
- package/dist/fleet/host-learning-tracker.d.ts +11 -0
- package/dist/fleet/host-learning-tracker.d.ts.map +1 -0
- package/dist/fleet/host-learning.d.ts +4 -0
- package/dist/fleet/host-learning.d.ts.map +1 -0
- package/dist/fleet/host-lifecycle-events.d.ts +4 -0
- package/dist/fleet/host-lifecycle-events.d.ts.map +1 -0
- package/dist/fleet/host-paths.d.ts +3 -0
- package/dist/fleet/host-paths.d.ts.map +1 -0
- package/dist/fleet/host-provider.d.ts +22 -0
- package/dist/fleet/host-provider.d.ts.map +1 -0
- package/dist/fleet/host-session-writer.d.ts +3 -0
- package/dist/fleet/host-session-writer.d.ts.map +1 -0
- package/dist/fleet/host-shadow-pass.d.ts +21 -0
- package/dist/fleet/host-shadow-pass.d.ts.map +1 -0
- package/dist/fleet/host-spawn-types.d.ts +25 -0
- package/dist/fleet/host-spawn-types.d.ts.map +1 -0
- package/dist/fleet/host-status.d.ts +48 -0
- package/dist/fleet/host-status.d.ts.map +1 -0
- package/dist/fleet/host-subagent-factory.d.ts +16 -0
- package/dist/fleet/host-subagent-factory.d.ts.map +1 -0
- package/dist/fleet/host-supervisor.d.ts +16 -0
- package/dist/fleet/host-supervisor.d.ts.map +1 -0
- package/dist/fleet/host-task-result-report.d.ts +11 -0
- package/dist/fleet/host-task-result-report.d.ts.map +1 -0
- package/dist/fleet/host-types.d.ts +89 -0
- package/dist/fleet/host-types.d.ts.map +1 -0
- package/dist/fleet/host.d.ts +10 -357
- package/dist/fleet/host.d.ts.map +1 -1
- package/dist/hq-JUYKUNJX.js +547 -0
- package/dist/hq-JUYKUNJX.js.map +7 -0
- package/dist/hq-command-controller.d.ts +2 -2
- package/dist/hq-command-controller.d.ts.map +1 -1
- package/dist/hq-server/auth.d.ts +15 -4
- package/dist/hq-server/auth.d.ts.map +1 -1
- package/dist/hq-server/project-root.d.ts +5 -0
- package/dist/hq-server/project-root.d.ts.map +1 -0
- package/dist/hq-server/routes/auth-handlers.d.ts +25 -0
- package/dist/hq-server/routes/auth-handlers.d.ts.map +1 -0
- package/dist/hq-server/routes/session-handlers.d.ts +8 -0
- package/dist/hq-server/routes/session-handlers.d.ts.map +1 -0
- package/dist/hq-server/routes.d.ts +8 -6
- package/dist/hq-server/routes.d.ts.map +1 -1
- package/dist/hq-server/snapshot.d.ts +44 -0
- package/dist/hq-server/snapshot.d.ts.map +1 -1
- package/dist/hq-server/types.d.ts +22 -4
- package/dist/hq-server/types.d.ts.map +1 -1
- package/dist/hq-server/utils.d.ts +8 -0
- package/dist/hq-server/utils.d.ts.map +1 -1
- package/dist/hq-server/ws.d.ts +1 -1
- package/dist/hq-server/ws.d.ts.map +1 -1
- package/dist/hq-server-6AQ3BXZA.js +39 -0
- package/dist/hq-server-6AQ3BXZA.js.map +7 -0
- package/dist/hq-server.d.ts +3 -3
- package/dist/hq-server.d.ts.map +1 -1
- package/dist/hq-ttl-U2FAYFAT.js +8 -0
- package/dist/hq-ttl-U2FAYFAT.js.map +7 -0
- package/dist/hq-tunnel-RFKGC4HI.js +114 -0
- package/dist/hq-tunnel-RFKGC4HI.js.map +7 -0
- package/dist/hq-tunnel.d.ts +1 -1
- package/dist/hq-tunnel.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2503 -53026
- package/dist/index.js.map +4 -4
- package/dist/init-E2NDDOHI.js +27 -0
- package/dist/init-E2NDDOHI.js.map +7 -0
- package/dist/kanban-dispatch-route.d.ts +14 -0
- package/dist/kanban-dispatch-route.d.ts.map +1 -0
- package/dist/kanban-hq-sync.d.ts +2 -0
- package/dist/kanban-hq-sync.d.ts.map +1 -1
- package/dist/kanban-run-mirror-EKVNGXWW.js +12 -0
- package/dist/kanban-run-mirror-EKVNGXWW.js.map +7 -0
- package/dist/live-settings-input.d.ts +69 -0
- package/dist/live-settings-input.d.ts.map +1 -0
- package/dist/mailbox-serve-2UWHEN3M.js +302 -0
- package/dist/mailbox-serve-2UWHEN3M.js.map +7 -0
- package/dist/mcp-CYLPUEHC.js +413 -0
- package/dist/mcp-CYLPUEHC.js.map +7 -0
- package/dist/modeldiag-HENYJ4N7.js +1290 -0
- package/dist/modeldiag-HENYJ4N7.js.map +7 -0
- package/dist/permissions-FNYLZIL4.js +115 -0
- package/dist/permissions-FNYLZIL4.js.map +7 -0
- package/dist/picker-key-state.d.ts +7 -0
- package/dist/picker-key-state.d.ts.map +1 -0
- package/dist/picker-model-picker.d.ts +6 -0
- package/dist/picker-model-picker.d.ts.map +1 -0
- package/dist/picker-ui.d.ts +17 -0
- package/dist/picker-ui.d.ts.map +1 -0
- package/dist/picker.d.ts +4 -37
- package/dist/picker.d.ts.map +1 -1
- package/dist/plugin-usage-OU6X6LM3.js +40 -0
- package/dist/plugin-usage-OU6X6LM3.js.map +7 -0
- package/dist/plugins-4LJ5IUBI.js +24 -0
- package/dist/plugins-4LJ5IUBI.js.map +7 -0
- package/dist/pre-launch.d.ts +0 -1
- package/dist/pre-launch.d.ts.map +1 -1
- package/dist/project-BLQ3ALVL.js +76 -0
- package/dist/project-BLQ3ALVL.js.map +7 -0
- package/dist/project-manifest-GE25PW4S.js +18 -0
- package/dist/project-manifest-GE25PW4S.js.map +7 -0
- package/dist/project-picker-BOCWHBXP.js +17 -0
- package/dist/project-picker-BOCWHBXP.js.map +7 -0
- package/dist/projects-XE76NFNZ.js +38 -0
- package/dist/projects-XE76NFNZ.js.map +7 -0
- package/dist/provider-helpers.d.ts +22 -6
- package/dist/provider-helpers.d.ts.map +1 -1
- package/dist/providers-models-GDELBHZK.js +589 -0
- package/dist/providers-models-GDELBHZK.js.map +7 -0
- package/dist/quick-VIO2BEHS.js +10 -0
- package/dist/quick-VIO2BEHS.js.map +7 -0
- package/dist/repl-auto-proceed.d.ts +19 -0
- package/dist/repl-auto-proceed.d.ts.map +1 -0
- package/dist/repl-client-registration.d.ts +7 -0
- package/dist/repl-client-registration.d.ts.map +1 -0
- package/dist/repl-input.d.ts +11 -0
- package/dist/repl-input.d.ts.map +1 -0
- package/dist/repl-options.d.ts +54 -0
- package/dist/repl-options.d.ts.map +1 -0
- package/dist/repl-rendering.d.ts +4 -0
- package/dist/repl-rendering.d.ts.map +1 -0
- package/dist/repl-suggestions.d.ts +21 -0
- package/dist/repl-suggestions.d.ts.map +1 -0
- package/dist/repl.d.ts +3 -162
- package/dist/repl.d.ts.map +1 -1
- package/dist/replay-KCTXNMZQ.js +75 -0
- package/dist/replay-KCTXNMZQ.js.map +7 -0
- package/dist/rewind-EJMVFVLS.js +185 -0
- package/dist/rewind-EJMVFVLS.js.map +7 -0
- package/dist/sdd-runtime-JG4EEKL6.js +54 -0
- package/dist/sdd-runtime-JG4EEKL6.js.map +7 -0
- package/dist/services/sdd/project-context.d.ts +1 -1
- package/dist/services/sdd/project-context.d.ts.map +1 -1
- package/dist/services/sdd/task-manager.d.ts.map +1 -1
- package/dist/services/statusline-config.d.ts +1 -1
- package/dist/services/statusline-config.d.ts.map +1 -1
- package/dist/session-event-wiring.d.ts +2 -2
- package/dist/session-event-wiring.d.ts.map +1 -1
- package/dist/sessions-config-NLCMK3BY.js +409 -0
- package/dist/sessions-config-NLCMK3BY.js.map +7 -0
- package/dist/settings-menu.d.ts +3 -18
- package/dist/settings-menu.d.ts.map +1 -1
- package/dist/simpleui-dist-JIFGUJO7.js +93 -0
- package/dist/simpleui-dist-JIFGUJO7.js.map +7 -0
- package/dist/slash-commands/brain.d.ts.map +1 -1
- package/dist/slash-commands/clear.d.ts.map +1 -1
- package/dist/slash-commands/fallback.d.ts.map +1 -1
- package/dist/slash-commands/kanban-agent-helpers.d.ts +18 -0
- package/dist/slash-commands/kanban-agent-helpers.d.ts.map +1 -0
- package/dist/slash-commands/kanban-format.d.ts +16 -0
- package/dist/slash-commands/kanban-format.d.ts.map +1 -0
- package/dist/slash-commands/kanban-help.d.ts +2 -0
- package/dist/slash-commands/kanban-help.d.ts.map +1 -0
- package/dist/slash-commands/kanban.d.ts.map +1 -1
- package/dist/slash-commands/mailbox-demo.d.ts.map +1 -1
- package/dist/slash-commands/mailbox.d.ts +2 -1
- package/dist/slash-commands/mailbox.d.ts.map +1 -1
- package/dist/slash-commands/memory-compact.d.ts +5 -0
- package/dist/slash-commands/memory-compact.d.ts.map +1 -0
- package/dist/slash-commands/memory-flags.d.ts +36 -0
- package/dist/slash-commands/memory-flags.d.ts.map +1 -0
- package/dist/slash-commands/memory-formatters.d.ts +16 -0
- package/dist/slash-commands/memory-formatters.d.ts.map +1 -0
- package/dist/slash-commands/memory.d.ts.map +1 -1
- package/dist/slash-commands/mouse.d.ts +2 -2
- package/dist/slash-commands/review.d.ts.map +1 -1
- package/dist/slash-commands/sdd-command-helpers.d.ts +23 -0
- package/dist/slash-commands/sdd-command-helpers.d.ts.map +1 -0
- package/dist/slash-commands/sdd-format.d.ts +32 -0
- package/dist/slash-commands/sdd-format.d.ts.map +1 -0
- package/dist/slash-commands/sdd.d.ts.map +1 -1
- package/dist/slash-commands/settings.d.ts.map +1 -1
- package/dist/subcommands/handlers/chronicle.d.ts.map +1 -1
- package/dist/subcommands/handlers/mailbox-serve.d.ts.map +1 -1
- package/dist/subcommands/handlers/model-smoke-test.d.ts +51 -0
- package/dist/subcommands/handlers/model-smoke-test.d.ts.map +1 -0
- package/dist/subcommands/handlers/modeldiag-profiles.d.ts +64 -0
- package/dist/subcommands/handlers/modeldiag-profiles.d.ts.map +1 -0
- package/dist/subcommands/handlers/modeldiag.d.ts.map +1 -1
- package/dist/subcommands/handlers/per-subcommand-deep-help-table.d.ts +3 -0
- package/dist/subcommands/handlers/per-subcommand-deep-help-table.d.ts.map +1 -0
- package/dist/subcommands/handlers/per-subcommand-help-data.d.ts +3 -0
- package/dist/subcommands/handlers/per-subcommand-help-data.d.ts.map +1 -0
- package/dist/subcommands/handlers/per-subcommand-help-table.d.ts +36 -0
- package/dist/subcommands/handlers/per-subcommand-help-table.d.ts.map +1 -0
- package/dist/subcommands/handlers/per-subcommand-help-types.d.ts +18 -0
- package/dist/subcommands/handlers/per-subcommand-help-types.d.ts.map +1 -0
- package/dist/subcommands/handlers/per-subcommand-help.d.ts +2 -80
- package/dist/subcommands/handlers/per-subcommand-help.d.ts.map +1 -1
- package/dist/subcommands/handlers/rewind.d.ts.map +1 -1
- package/dist/subcommands/index.d.ts +7 -0
- package/dist/subcommands/index.d.ts.map +1 -1
- package/dist/tools-skills-UNKLOB7M.js +29 -0
- package/dist/tools-skills-UNKLOB7M.js.map +7 -0
- package/dist/update-YC4TYW2Y.js +16 -0
- package/dist/update-YC4TYW2Y.js.map +7 -0
- package/dist/update-check-UMYTOH7Z.js +18 -0
- package/dist/update-check-UMYTOH7Z.js.map +7 -0
- package/dist/version-help-DROHZRW6.js +11 -0
- package/dist/version-help-DROHZRW6.js.map +7 -0
- package/dist/webui-server/connection-handler.d.ts.map +1 -1
- package/dist/webui-server/kanban-host-adapter.d.ts +5 -1
- package/dist/webui-server/kanban-host-adapter.d.ts.map +1 -1
- package/dist/webui-server/listen-helpers.d.ts +18 -0
- package/dist/webui-server/listen-helpers.d.ts.map +1 -0
- package/dist/webui-server/node-pty-loader.d.ts +6 -0
- package/dist/webui-server/node-pty-loader.d.ts.map +1 -0
- package/dist/webui-server-ZF5KVGC5.js +1460 -0
- package/dist/webui-server-ZF5KVGC5.js.map +7 -0
- package/dist/webui-server-options.d.ts +191 -0
- package/dist/webui-server-options.d.ts.map +1 -0
- package/dist/webui-server.d.ts +2 -178
- package/dist/webui-server.d.ts.map +1 -1
- package/dist/wiring/brain-and-orchestration.d.ts.map +1 -1
- package/dist/wiring/codebase-index.d.ts.map +1 -1
- package/dist/wiring/command-host-state.d.ts +4 -4
- package/dist/wiring/dep-watcher-bridge.d.ts +23 -0
- package/dist/wiring/dep-watcher-bridge.d.ts.map +1 -0
- package/dist/wiring/dep-watcher.d.ts.map +1 -1
- package/dist/wiring/hq-telemetry.d.ts +2 -2
- package/dist/wiring/lifecycle-plugins.d.ts +4 -3
- package/dist/wiring/lifecycle-plugins.d.ts.map +1 -1
- package/dist/wiring/mailbox-bridge-bootstrap.d.ts +1 -1
- package/dist/wiring/management-tools.d.ts +15 -0
- package/dist/wiring/management-tools.d.ts.map +1 -0
- package/dist/wiring/pipeline.d.ts +2 -1
- package/dist/wiring/pipeline.d.ts.map +1 -1
- package/dist/wiring/plugins.d.ts +1 -1
- package/dist/wiring/plugins.d.ts.map +1 -1
- package/dist/wiring/provider-runtime-setup.d.ts +14 -1
- package/dist/wiring/provider-runtime-setup.d.ts.map +1 -1
- package/dist/wiring/provider.d.ts.map +1 -1
- package/dist/wiring/runtime-controller-deps.d.ts +1 -1
- package/dist/wiring/runtime-controller-deps.d.ts.map +1 -1
- package/dist/wiring/sage.d.ts.map +1 -1
- package/dist/wiring/session-registry.d.ts +38 -0
- package/dist/wiring/session-registry.d.ts.map +1 -0
- package/dist/wiring/session.d.ts +10 -6
- package/dist/wiring/session.d.ts.map +1 -1
- package/dist/wiring/tools.d.ts.map +1 -1
- package/package.json +22 -22
- package/dist/cli-recovery-prompt.d.ts +0 -19
- package/dist/cli-recovery-prompt.d.ts.map +0 -1
- package/dist/first-run-auth-gate.d.ts +0 -20
- package/dist/first-run-auth-gate.d.ts.map +0 -1
- package/dist/pre-launch/indexing-question.d.ts +0 -28
- package/dist/pre-launch/indexing-question.d.ts.map +0 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/boot/auto-discover-providers.ts"],
|
|
4
|
+
"sourcesContent": ["import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Config, Logger, ModelsDevProvider, ProviderConfig } from '@wrongstack/core/types';\nimport type { DefaultModelsRegistry } from '@wrongstack/core/models';\nimport { COMPATIBLE_PRESETS, discoverOpenAICompatibleModels } from '@wrongstack/providers';\n\ninterface DiscoverCacheEntry {\n fetchedAt: string;\n provider: ModelsDevProvider;\n}\ntype DiscoverCache = Record<string, DiscoverCacheEntry>;\n\n/** Active API key from a ProviderConfig (mirrors the provider factory's resolver). */\nfunction resolveKey(cfg: ProviderConfig): string | undefined {\n if (Array.isArray(cfg.apiKeys) && cfg.apiKeys.length > 0) {\n const active = cfg.activeKey\n ? cfg.apiKeys.find((k) => k.label === cfg.activeKey)\n : undefined;\n return (active ?? cfg.apiKeys[0])?.apiKey;\n }\n return cfg.apiKey && cfg.apiKey.length > 0 ? cfg.apiKey : undefined;\n}\n\n/** Providers eligible for `/v1/models` auto-discovery and their resolved base URL. */\nfunction eligibleProviders(\n config: Config,\n): Array<{ id: string; cfg: ProviderConfig; baseUrl: string; apiKey?: string | undefined }> {\n const out: Array<{\n id: string;\n cfg: ProviderConfig;\n baseUrl: string;\n apiKey?: string | undefined;\n }> = [];\n for (const [id, cfg] of Object.entries(config.providers ?? {})) {\n const preset = COMPATIBLE_PRESETS[id];\n const enabled = cfg.autoDiscoverModels ?? preset?.autoDiscover ?? false;\n if (!enabled) continue;\n const baseUrl = cfg.baseUrl ?? preset?.defaultBaseUrl;\n if (!baseUrl) continue;\n out.push({ id, cfg, baseUrl, apiKey: resolveKey(cfg) });\n }\n return out;\n}\n\nasync function readCache(file: string): Promise<DiscoverCache> {\n try {\n return JSON.parse(await fs.readFile(file, 'utf8')) as DiscoverCache;\n } catch {\n return {};\n }\n}\n\n/**\n * Fetch model lists for every auto-discovery provider in the config and merge\n * them into the catalog. Best-effort end to end: a down server or missing key\n * falls back to the last cached list (any age \u2014 a local proxy being offline at\n * boot shouldn't wipe its models), and any failure is a logged no-op so boot\n * never breaks.\n *\n * Caches the most recent successful fetch per provider+baseUrl so the models\n * survive a restart while the server is briefly unavailable.\n */\nexport async function discoverAndMergeProviders(opts: {\n config: Config;\n registry: DefaultModelsRegistry;\n cacheDir: string;\n logger?: Logger | undefined;\n fetchImpl?: typeof fetch | undefined;\n}): Promise<void> {\n const targets = eligibleProviders(opts.config);\n if (targets.length === 0) return;\n\n const cacheFile = path.join(opts.cacheDir, 'discovered-models-cache.json');\n const cache = await readCache(cacheFile);\n let cacheDirty = false;\n\n await Promise.all(\n targets.map(async ({ id, cfg, baseUrl, apiKey }) => {\n const cacheKey = `${id}\u0000${baseUrl}`;\n const provider = await discoverOpenAICompatibleModels(id, {\n baseUrl,\n apiKey,\n headers: cfg.headers,\n providerName: id,\n fetchImpl: opts.fetchImpl,\n });\n if (provider) {\n cache[cacheKey] = { fetchedAt: new Date().toISOString(), provider };\n cacheDirty = true;\n opts.registry.mergeOverlay({ [id]: provider });\n opts.logger?.info(\n `auto-discovered ${Object.keys(provider.models).length} models for \"${id}\" from ${baseUrl}`,\n );\n return;\n }\n // Fetch failed \u2014 fall back to the last cached list, if any.\n const cached = cache[cacheKey];\n if (cached) {\n opts.registry.mergeOverlay({ [id]: cached.provider });\n opts.logger?.warn(\n `auto-discovery for \"${id}\" failed; using ${\n Object.keys(cached.provider.models).length\n } cached models from ${cached.fetchedAt}`,\n );\n } else {\n opts.logger?.warn(\n `auto-discovery for \"${id}\" failed and no cache available (server at ${baseUrl} unreachable?)`,\n );\n }\n }),\n );\n\n if (cacheDirty) {\n try {\n await fs.writeFile(cacheFile, JSON.stringify(cache), 'utf8');\n } catch {\n // best-effort cache write\n }\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;AAAA,YAAY,QAAQ;AACpB,YAAY,UAAU;AAGtB,SAAS,oBAAoB,sCAAsC;AASnE,SAAS,WAAW,KAAyC;AAC3D,MAAI,MAAM,QAAQ,IAAI,OAAO,KAAK,IAAI,QAAQ,SAAS,GAAG;AACxD,UAAM,SAAS,IAAI,YACf,IAAI,QAAQ,KAAK,CAAC,MAAM,EAAE,UAAU,IAAI,SAAS,IACjD;AACJ,YAAQ,UAAU,IAAI,QAAQ,CAAC,IAAI;AAAA,EACrC;AACA,SAAO,IAAI,UAAU,IAAI,OAAO,SAAS,IAAI,IAAI,SAAS;AAC5D;AAGA,SAAS,kBACP,QAC0F;AAC1F,QAAM,MAKD,CAAC;AACN,aAAW,CAAC,IAAI,GAAG,KAAK,OAAO,QAAQ,OAAO,aAAa,CAAC,CAAC,GAAG;AAC9D,UAAM,SAAS,mBAAmB,EAAE;AACpC,UAAM,UAAU,IAAI,sBAAsB,QAAQ,gBAAgB;AAClE,QAAI,CAAC,QAAS;AACd,UAAM,UAAU,IAAI,WAAW,QAAQ;AACvC,QAAI,CAAC,QAAS;AACd,QAAI,KAAK,EAAE,IAAI,KAAK,SAAS,QAAQ,WAAW,GAAG,EAAE,CAAC;AAAA,EACxD;AACA,SAAO;AACT;AAEA,eAAe,UAAU,MAAsC;AAC7D,MAAI;AACF,WAAO,KAAK,MAAM,MAAS,YAAS,MAAM,MAAM,CAAC;AAAA,EACnD,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAYA,eAAsB,0BAA0B,MAM9B;AAChB,QAAM,UAAU,kBAAkB,KAAK,MAAM;AAC7C,MAAI,QAAQ,WAAW,EAAG;AAE1B,QAAM,YAAiB,UAAK,KAAK,UAAU,8BAA8B;AACzE,QAAM,QAAQ,MAAM,UAAU,SAAS;AACvC,MAAI,aAAa;AAEjB,QAAM,QAAQ;AAAA,IACZ,QAAQ,IAAI,OAAO,EAAE,IAAI,KAAK,SAAS,OAAO,MAAM;AAClD,YAAM,WAAW,GAAG,EAAE,KAAI,OAAO;AACjC,YAAM,WAAW,MAAM,+BAA+B,IAAI;AAAA,QACxD;AAAA,QACA;AAAA,QACA,SAAS,IAAI;AAAA,QACb,cAAc;AAAA,QACd,WAAW,KAAK;AAAA,MAClB,CAAC;AACD,UAAI,UAAU;AACZ,cAAM,QAAQ,IAAI,EAAE,YAAW,oBAAI,KAAK,GAAE,YAAY,GAAG,SAAS;AAClE,qBAAa;AACb,aAAK,SAAS,aAAa,EAAE,CAAC,EAAE,GAAG,SAAS,CAAC;AAC7C,aAAK,QAAQ;AAAA,UACX,mBAAmB,OAAO,KAAK,SAAS,MAAM,EAAE,MAAM,gBAAgB,EAAE,UAAU,OAAO;AAAA,QAC3F;AACA;AAAA,MACF;AAEA,YAAM,SAAS,MAAM,QAAQ;AAC7B,UAAI,QAAQ;AACV,aAAK,SAAS,aAAa,EAAE,CAAC,EAAE,GAAG,OAAO,SAAS,CAAC;AACpD,aAAK,QAAQ;AAAA,UACX,uBAAuB,EAAE,mBACvB,OAAO,KAAK,OAAO,SAAS,MAAM,EAAE,MACtC,uBAAuB,OAAO,SAAS;AAAA,QACzC;AAAA,MACF,OAAO;AACL,aAAK,QAAQ;AAAA,UACX,uBAAuB,EAAE,8CAA8C,OAAO;AAAA,QAChF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,YAAY;AACd,QAAI;AACF,YAAS,aAAU,WAAW,KAAK,UAAU,KAAK,GAAG,MAAM;AAAA,IAC7D,QAAQ;AAAA,IAER;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
|
|
2
|
+
// src/utils.ts
|
|
3
|
+
function fmtTok(n) {
|
|
4
|
+
if (n < 1e3) return String(n);
|
|
5
|
+
if (n < 1e6) return `${(n / 1e3).toFixed(n < 1e4 ? 1 : 0)}k`;
|
|
6
|
+
return `${(n / 1e6).toFixed(1)}M`;
|
|
7
|
+
}
|
|
8
|
+
function patchConfig(base, patch) {
|
|
9
|
+
return Object.freeze({ ...base, ...patch });
|
|
10
|
+
}
|
|
11
|
+
function fmtDuration(ms) {
|
|
12
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
13
|
+
const s = ms / 1e3;
|
|
14
|
+
if (s < 60) return `${s.toFixed(s < 10 ? 1 : 0)}s`;
|
|
15
|
+
const m = Math.floor(s / 60);
|
|
16
|
+
const remSec = Math.round(s - m * 60);
|
|
17
|
+
if (m < 60) return remSec === 0 ? `${m}m` : `${m}m${remSec}s`;
|
|
18
|
+
const h = Math.floor(m / 60);
|
|
19
|
+
const remMin = m - h * 60;
|
|
20
|
+
return `${h}h${remMin}m`;
|
|
21
|
+
}
|
|
22
|
+
function fmtTaskResultLine(r, color) {
|
|
23
|
+
const stats = `${r.iterations}it ${r.toolCalls}tc ${fmtDuration(r.durationMs)}`;
|
|
24
|
+
const errMsg = typeof r.error === "string" ? r.error : r.error?.message;
|
|
25
|
+
const errKind = typeof r.error === "object" ? r.error?.kind : void 0;
|
|
26
|
+
const errTail = errMsg ? ` \u2014 ${errMsg.replace(/\s+/g, " ").slice(0, 80)}${errMsg.length > 80 ? "\u2026" : ""}` : "";
|
|
27
|
+
const errKindChip = errKind ? color.dim(` [${errKind}]`) : "";
|
|
28
|
+
const errSnip = errMsg || errKind ? `${errKindChip}${color.dim(errTail)}` : "";
|
|
29
|
+
switch (r.status) {
|
|
30
|
+
case "success":
|
|
31
|
+
return { mark: color.green("\u2713"), stats, tail: "" };
|
|
32
|
+
case "timeout":
|
|
33
|
+
return {
|
|
34
|
+
mark: color.yellow("\u23F1"),
|
|
35
|
+
stats: `${color.yellow("timeout")} ${stats}`,
|
|
36
|
+
tail: errSnip
|
|
37
|
+
};
|
|
38
|
+
case "stopped":
|
|
39
|
+
return { mark: color.dim("\u2298"), stats: `${color.dim("stopped")} ${stats}`, tail: errSnip };
|
|
40
|
+
case "failed":
|
|
41
|
+
return { mark: color.red("\u2717"), stats: `${color.red("failed")} ${stats}`, tail: errSnip };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export {
|
|
46
|
+
fmtTok,
|
|
47
|
+
patchConfig,
|
|
48
|
+
fmtTaskResultLine
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=chunk-TYO2OVAD.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/utils.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Format a token count for human-readable display.\n * 999 \u2192 \"999\"\n * 1_200 \u2192 \"1.2k\"\n * 12_000 \u2192 \"12k\"\n * 1_500_000 \u2192 \"1.5M\"\n */\nexport function fmtTok(n: number): string {\n if (n < 1000) return String(n);\n if (n < 1_000_000) return `${(n / 1000).toFixed(n < 10_000 ? 1 : 0)}k`;\n return `${(n / 1_000_000).toFixed(1)}M`;\n}\n\n/**\n * Return a new frozen config object with the given patch applied.\n * Config objects are frozen by the config loader \u2014 direct mutation\n * silently fails at runtime. This helper spreads + re-freezes safely.\n */\nexport function patchConfig<T extends object>(base: T, patch: Partial<T>): T {\n return Object.freeze({ ...base, ...patch }) as T;\n}\n\n/**\n * Human-readable duration: 999 \u2192 \"999ms\", 12_500 \u2192 \"12.5s\",\n * 160_016 \u2192 \"2m40s\", 7_200_000 \u2192 \"2h0m\". Used by `/agents` and\n * `/fleet status` so users don't have to read \"160016ms\" and do the\n * conversion in their head.\n */\nexport function fmtDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n const s = ms / 1000;\n if (s < 60) return `${s.toFixed(s < 10 ? 1 : 0)}s`;\n const m = Math.floor(s / 60);\n const remSec = Math.round(s - m * 60);\n if (m < 60) return remSec === 0 ? `${m}m` : `${m}m${remSec}s`;\n const h = Math.floor(m / 60);\n const remMin = m - h * 60;\n return `${h}h${remMin}m`;\n}\n\n/**\n * Render a completed TaskResult into a single line for `/agents` and\n * `/fleet status`. Distinguishes all four terminal statuses with\n * separate icons + colors so users can tell a timeout from a real\n * failure at a glance, and surfaces both the failure kind (e.g.\n * `provider_rate_limit`, `tool_failed`) and a truncated error tail\n * (previously dropped on the floor).\n *\n * Accepts either the structured `SubagentError` envelope (current) or\n * a legacy string error \u2014 the field shape is widened to keep older\n * callers compiling while migrations roll through.\n *\n * The caller passes the color helper (it lives in @wrongstack/core)\n * to avoid a circular import from this utility module.\n */\nexport function fmtTaskResultLine(\n r: {\n status: 'success' | 'failed' | 'timeout' | 'stopped';\n error?:\n | string\n | {\n kind?: string | undefined;\n message?: string | undefined;\n retryable?: boolean | undefined;\n backoffMs?: number | undefined;\n }\n | undefined;\n iterations: number;\n toolCalls: number;\n durationMs: number;\n },\n color: {\n green(s: string): string;\n red(s: string): string;\n yellow(s: string): string;\n dim(s: string): string;\n },\n): { mark: string; stats: string; tail: string } {\n const stats = `${r.iterations}it ${r.toolCalls}tc ${fmtDuration(r.durationMs)}`;\n // Error tails are unbounded provider strings \u2014 collapse whitespace and\n // truncate so a 2KB stack trace can't blow up the chat line. Lift the\n // structured `kind` chip in front of the tail so the user reads\n // `\u2717 failed [provider_rate_limit] \u2014 server overloaded` instead of\n // raw verbose body.\n const errMsg = typeof r.error === 'string' ? r.error : r.error?.message;\n const errKind = typeof r.error === 'object' ? r.error?.kind : undefined;\n const errTail = errMsg\n ? ` \u2014 ${errMsg.replace(/\\s+/g, ' ').slice(0, 80)}${errMsg.length > 80 ? '\u2026' : ''}`\n : '';\n const errKindChip = errKind ? color.dim(` [${errKind}]`) : '';\n const errSnip = errMsg || errKind ? `${errKindChip}${color.dim(errTail)}` : '';\n switch (r.status) {\n case 'success':\n return { mark: color.green('\u2713'), stats, tail: '' };\n case 'timeout':\n return {\n mark: color.yellow('\u23F1'),\n stats: `${color.yellow('timeout')} ${stats}`,\n tail: errSnip,\n };\n case 'stopped':\n return { mark: color.dim('\u2298'), stats: `${color.dim('stopped')} ${stats}`, tail: errSnip };\n case 'failed':\n return { mark: color.red('\u2717'), stats: `${color.red('failed')} ${stats}`, tail: errSnip };\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;AAOO,SAAS,OAAO,GAAmB;AACxC,MAAI,IAAI,IAAM,QAAO,OAAO,CAAC;AAC7B,MAAI,IAAI,IAAW,QAAO,IAAI,IAAI,KAAM,QAAQ,IAAI,MAAS,IAAI,CAAC,CAAC;AACnE,SAAO,IAAI,IAAI,KAAW,QAAQ,CAAC,CAAC;AACtC;AAOO,SAAS,YAA8B,MAAS,OAAsB;AAC3E,SAAO,OAAO,OAAO,EAAE,GAAG,MAAM,GAAG,MAAM,CAAC;AAC5C;AAQO,SAAS,YAAY,IAAoB;AAC9C,MAAI,KAAK,IAAM,QAAO,GAAG,EAAE;AAC3B,QAAM,IAAI,KAAK;AACf,MAAI,IAAI,GAAI,QAAO,GAAG,EAAE,QAAQ,IAAI,KAAK,IAAI,CAAC,CAAC;AAC/C,QAAM,IAAI,KAAK,MAAM,IAAI,EAAE;AAC3B,QAAM,SAAS,KAAK,MAAM,IAAI,IAAI,EAAE;AACpC,MAAI,IAAI,GAAI,QAAO,WAAW,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM;AAC1D,QAAM,IAAI,KAAK,MAAM,IAAI,EAAE;AAC3B,QAAM,SAAS,IAAI,IAAI;AACvB,SAAO,GAAG,CAAC,IAAI,MAAM;AACvB;AAiBO,SAAS,kBACd,GAeA,OAM+C;AAC/C,QAAM,QAAQ,GAAG,EAAE,UAAU,MAAM,EAAE,SAAS,MAAM,YAAY,EAAE,UAAU,CAAC;AAM7E,QAAM,SAAS,OAAO,EAAE,UAAU,WAAW,EAAE,QAAQ,EAAE,OAAO;AAChE,QAAM,UAAU,OAAO,EAAE,UAAU,WAAW,EAAE,OAAO,OAAO;AAC9D,QAAM,UAAU,SACZ,WAAM,OAAO,QAAQ,QAAQ,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,OAAO,SAAS,KAAK,WAAM,EAAE,KAC9E;AACJ,QAAM,cAAc,UAAU,MAAM,IAAI,KAAK,OAAO,GAAG,IAAI;AAC3D,QAAM,UAAU,UAAU,UAAU,GAAG,WAAW,GAAG,MAAM,IAAI,OAAO,CAAC,KAAK;AAC5E,UAAQ,EAAE,QAAQ;AAAA,IAChB,KAAK;AACH,aAAO,EAAE,MAAM,MAAM,MAAM,QAAG,GAAG,OAAO,MAAM,GAAG;AAAA,IACnD,KAAK;AACH,aAAO;AAAA,QACL,MAAM,MAAM,OAAO,QAAG;AAAA,QACtB,OAAO,GAAG,MAAM,OAAO,SAAS,CAAC,IAAI,KAAK;AAAA,QAC1C,MAAM;AAAA,MACR;AAAA,IACF,KAAK;AACH,aAAO,EAAE,MAAM,MAAM,IAAI,QAAG,GAAG,OAAO,GAAG,MAAM,IAAI,SAAS,CAAC,IAAI,KAAK,IAAI,MAAM,QAAQ;AAAA,IAC1F,KAAK;AACH,aAAO,EAAE,MAAM,MAAM,IAAI,QAAG,GAAG,OAAO,GAAG,MAAM,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,MAAM,QAAQ;AAAA,EAC3F;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
// src/webui-server/kanban-run-mirror.ts
|
|
3
|
+
import {
|
|
4
|
+
buildTaskGraphFromGoalPhase,
|
|
5
|
+
buildTaskGraphFromSddSnapshot,
|
|
6
|
+
createKanbanRunMirror
|
|
7
|
+
} from "@wrongstack/webui-server";
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
buildTaskGraphFromGoalPhase,
|
|
11
|
+
buildTaskGraphFromSddSnapshot,
|
|
12
|
+
createKanbanRunMirror
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=chunk-VCYZ3WZV.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/webui-server/kanban-run-mirror.ts"],
|
|
4
|
+
"sourcesContent": ["export {\n buildTaskGraphFromGoalPhase,\n buildTaskGraphFromSddSnapshot,\n createKanbanRunMirror,\n type KanbanRunMirror,\n type KanbanRunMirrorDeps,\n} from '@wrongstack/webui-server';\n"],
|
|
5
|
+
"mappings": ";;;AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
|
|
2
|
+
// src/utils/win32-cmd.ts
|
|
3
|
+
var WIN32_CMD_META = /[&|<>"\r\n\0]/;
|
|
4
|
+
function buildWin32CmdShimInvocation(command, args = []) {
|
|
5
|
+
assertSafeWin32CmdArgs([command, ...args]);
|
|
6
|
+
const line = ["call", quoteWin32CmdArg(command), ...args.map(quoteWin32CmdArg)].join(" ");
|
|
7
|
+
return {
|
|
8
|
+
command: process.env["COMSPEC"] ?? "cmd.exe",
|
|
9
|
+
args: ["/d", "/c", line],
|
|
10
|
+
windowsVerbatimArguments: true
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function assertSafeWin32CmdArgs(args) {
|
|
14
|
+
for (const arg of args) {
|
|
15
|
+
if (typeof arg === "string" && WIN32_CMD_META.test(arg)) {
|
|
16
|
+
throw new Error(
|
|
17
|
+
'win32 cmd shim spawn: argument contains a shell metacharacter (one of & | < > ", or a newline) that could enable command injection through the .cmd/.bat wrapper - refusing to run. Offending argument: ' + JSON.stringify(arg)
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function quoteWin32CmdArg(arg) {
|
|
23
|
+
return `"${arg}"`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export {
|
|
27
|
+
buildWin32CmdShimInvocation
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=chunk-VJUEZZYB.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/utils/win32-cmd.ts"],
|
|
4
|
+
"sourcesContent": ["const WIN32_CMD_META = /[&|<>\"\\r\\n\\0]/;\n\nexport interface Win32CmdShimInvocation {\n command: string;\n args: string[];\n windowsVerbatimArguments: true;\n}\n\nexport function buildWin32CmdShimInvocation(\n command: string,\n args: readonly string[] = [],\n): Win32CmdShimInvocation {\n assertSafeWin32CmdArgs([command, ...args]);\n const line = ['call', quoteWin32CmdArg(command), ...args.map(quoteWin32CmdArg)].join(' ');\n return {\n command: process.env['COMSPEC'] ?? 'cmd.exe',\n args: ['/d', '/c', line],\n windowsVerbatimArguments: true,\n };\n}\n\nfunction assertSafeWin32CmdArgs(args: readonly unknown[]): void {\n for (const arg of args) {\n if (typeof arg === 'string' && WIN32_CMD_META.test(arg)) {\n throw new Error(\n 'win32 cmd shim spawn: argument contains a shell metacharacter ' +\n '(one of & | < > \", or a newline) that could enable command injection ' +\n 'through the .cmd/.bat wrapper - refusing to run. Offending argument: ' +\n JSON.stringify(arg),\n );\n }\n }\n}\n\nfunction quoteWin32CmdArg(arg: string): string {\n return `\"${arg}\"`;\n}\n"],
|
|
5
|
+
"mappings": ";;;AAAA,IAAM,iBAAiB;AAQhB,SAAS,4BACd,SACA,OAA0B,CAAC,GACH;AACxB,yBAAuB,CAAC,SAAS,GAAG,IAAI,CAAC;AACzC,QAAM,OAAO,CAAC,QAAQ,iBAAiB,OAAO,GAAG,GAAG,KAAK,IAAI,gBAAgB,CAAC,EAAE,KAAK,GAAG;AACxF,SAAO;AAAA,IACL,SAAS,QAAQ,IAAI,SAAS,KAAK;AAAA,IACnC,MAAM,CAAC,MAAM,MAAM,IAAI;AAAA,IACvB,0BAA0B;AAAA,EAC5B;AACF;AAEA,SAAS,uBAAuB,MAAgC;AAC9D,aAAW,OAAO,MAAM;AACtB,QAAI,OAAO,QAAQ,YAAY,eAAe,KAAK,GAAG,GAAG;AACvD,YAAM,IAAI;AAAA,QACR,6MAGE,KAAK,UAAU,GAAG;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,KAAqB;AAC7C,SAAO,IAAI,GAAG;AAChB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=chunk-WHOIR577.js.map
|
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
|
|
2
|
+
// src/hq-publisher.ts
|
|
3
|
+
import { createHqPublisherFromEnv, resolveHqConfig } from "@wrongstack/core/hq";
|
|
4
|
+
import { WebSocket } from "ws";
|
|
5
|
+
|
|
6
|
+
// src/kanban-hq-sync.ts
|
|
7
|
+
import { deriveHqProjectId } from "@wrongstack/core/hq";
|
|
8
|
+
import {
|
|
9
|
+
bridgeKanbanSupervisor,
|
|
10
|
+
deleteBoard,
|
|
11
|
+
listBoardIds,
|
|
12
|
+
readBoard,
|
|
13
|
+
readKanbanMetadata,
|
|
14
|
+
writeBoard,
|
|
15
|
+
writeKanbanMetadata
|
|
16
|
+
} from "@wrongstack/kanban";
|
|
17
|
+
var SYNC_STATE_KEY = "hq-sync-state-v1";
|
|
18
|
+
var MAX_KANBAN_SNAPSHOT_PAYLOAD_BYTES = 512 * 1024;
|
|
19
|
+
var KANBAN_TOMBSTONE_RETENTION_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
20
|
+
var MAX_BOARDS_PER_PUBLISH = 50;
|
|
21
|
+
function warnSyncFailure(error) {
|
|
22
|
+
process.emitWarning(
|
|
23
|
+
`WrongStack kanban HQ sync failed (best-effort, will retry on next change): ${error instanceof Error ? error.message : String(error)}`,
|
|
24
|
+
{ code: "WRONGSTACK_HQ_KANBAN_SYNC_FAILED" }
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
function createKanbanHqSync(projectRoot, projectId = deriveHqProjectId(projectRoot)) {
|
|
28
|
+
let publisher;
|
|
29
|
+
let unsubscribeDaemon;
|
|
30
|
+
let daemonConnectionCount = 0;
|
|
31
|
+
let timer;
|
|
32
|
+
const pendingBoardIds = /* @__PURE__ */ new Set();
|
|
33
|
+
let fullRescanPending = false;
|
|
34
|
+
let applyingRemote = false;
|
|
35
|
+
let stopped = false;
|
|
36
|
+
let operationChain = Promise.resolve();
|
|
37
|
+
let pendingRemote = null;
|
|
38
|
+
let remoteApplyQueued = false;
|
|
39
|
+
const runExclusive = (operation) => {
|
|
40
|
+
let resolveResult;
|
|
41
|
+
let rejectResult;
|
|
42
|
+
const result = new Promise((resolve, reject) => {
|
|
43
|
+
resolveResult = resolve;
|
|
44
|
+
rejectResult = reject;
|
|
45
|
+
});
|
|
46
|
+
operationChain = operationChain.then(async () => {
|
|
47
|
+
try {
|
|
48
|
+
resolveResult(await operation());
|
|
49
|
+
} catch (error) {
|
|
50
|
+
rejectResult(error);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
return result;
|
|
54
|
+
};
|
|
55
|
+
const scheduleNext = () => {
|
|
56
|
+
if (stopped || timer !== void 0 || applyingRemote) return;
|
|
57
|
+
timer = setTimeout(() => {
|
|
58
|
+
timer = void 0;
|
|
59
|
+
const rescan = fullRescanPending;
|
|
60
|
+
const dirtyBoardIds = [...pendingBoardIds];
|
|
61
|
+
fullRescanPending = false;
|
|
62
|
+
pendingBoardIds.clear();
|
|
63
|
+
runExclusive(() => publishLocal(false, rescan ? void 0 : dirtyBoardIds)).catch(
|
|
64
|
+
warnSyncFailure
|
|
65
|
+
);
|
|
66
|
+
}, 100);
|
|
67
|
+
timer.unref?.();
|
|
68
|
+
};
|
|
69
|
+
const schedulePublish = (boardId) => {
|
|
70
|
+
if (stopped || applyingRemote || publisher === void 0) return;
|
|
71
|
+
if (boardId === null) fullRescanPending = true;
|
|
72
|
+
else pendingBoardIds.add(boardId);
|
|
73
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
74
|
+
timer = void 0;
|
|
75
|
+
scheduleNext();
|
|
76
|
+
};
|
|
77
|
+
const publishLocal = async (fullSnapshot, dirtyBoardIds) => {
|
|
78
|
+
const target = publisher;
|
|
79
|
+
if (target === void 0 || stopped) return;
|
|
80
|
+
const state = await readState(projectRoot);
|
|
81
|
+
const prunedTombstones = pruneExpiredTombstones(state, Date.now());
|
|
82
|
+
let stateChanged = fullSnapshot || prunedTombstones;
|
|
83
|
+
const boards = [];
|
|
84
|
+
const tombstones = [];
|
|
85
|
+
const fullScan = fullSnapshot || dirtyBoardIds === void 0;
|
|
86
|
+
const allBoardIds = fullScan ? await listBoardIds(projectRoot) : dirtyBoardIds;
|
|
87
|
+
let boardIds = allBoardIds;
|
|
88
|
+
if (!fullScan && boardIds.length > MAX_BOARDS_PER_PUBLISH) {
|
|
89
|
+
for (const id of boardIds.slice(MAX_BOARDS_PER_PUBLISH)) {
|
|
90
|
+
pendingBoardIds.add(id);
|
|
91
|
+
}
|
|
92
|
+
scheduleNext();
|
|
93
|
+
boardIds = boardIds.slice(0, MAX_BOARDS_PER_PUBLISH);
|
|
94
|
+
}
|
|
95
|
+
const present = /* @__PURE__ */ new Set();
|
|
96
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
97
|
+
for (const boardId of boardIds) {
|
|
98
|
+
const board = await readBoard(projectRoot, boardId);
|
|
99
|
+
if (board === null) {
|
|
100
|
+
const known2 = state.boards[boardId];
|
|
101
|
+
if (known2 !== void 0 && state.tombstones[boardId] === void 0) {
|
|
102
|
+
const tombstone = {
|
|
103
|
+
boardId,
|
|
104
|
+
revision: known2.revision + 1,
|
|
105
|
+
deletedAt: now
|
|
106
|
+
};
|
|
107
|
+
state.tombstones[boardId] = tombstone;
|
|
108
|
+
tombstones.push(tombstone);
|
|
109
|
+
stateChanged = true;
|
|
110
|
+
}
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
present.add(boardId);
|
|
114
|
+
const record = boardRecord(board);
|
|
115
|
+
const known = state.boards[boardId];
|
|
116
|
+
const hadTombstone = state.tombstones[boardId] !== void 0;
|
|
117
|
+
if (fullSnapshot || hadTombstone || known === void 0 || compareVersions(known.revision, known.updatedAt, record.revision, record.updatedAt) !== 0) {
|
|
118
|
+
boards.push(record);
|
|
119
|
+
}
|
|
120
|
+
if (known === void 0 || known.revision !== record.revision || known.updatedAt !== record.updatedAt || hadTombstone) {
|
|
121
|
+
stateChanged = true;
|
|
122
|
+
}
|
|
123
|
+
state.boards[boardId] = { revision: record.revision, updatedAt: record.updatedAt };
|
|
124
|
+
delete state.tombstones[boardId];
|
|
125
|
+
}
|
|
126
|
+
if (fullScan) {
|
|
127
|
+
for (const [boardId, known] of Object.entries(state.boards)) {
|
|
128
|
+
if (present.has(boardId) || state.tombstones[boardId] !== void 0 || isExpiredVersion(known.updatedAt, Date.now())) {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
const tombstone = {
|
|
132
|
+
boardId,
|
|
133
|
+
revision: known.revision + 1,
|
|
134
|
+
deletedAt: now
|
|
135
|
+
};
|
|
136
|
+
state.tombstones[boardId] = tombstone;
|
|
137
|
+
tombstones.push(tombstone);
|
|
138
|
+
stateChanged = true;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (stateChanged) await writeState(projectRoot, state);
|
|
142
|
+
if (!fullSnapshot && boards.length === 0 && tombstones.length === 0) return;
|
|
143
|
+
for (const payload of chunkSnapshotPayload(
|
|
144
|
+
projectId,
|
|
145
|
+
now,
|
|
146
|
+
boards,
|
|
147
|
+
fullSnapshot ? Object.values(state.tombstones) : tombstones
|
|
148
|
+
)) {
|
|
149
|
+
target.publishEvent({
|
|
150
|
+
type: "kanban.snapshot",
|
|
151
|
+
payload,
|
|
152
|
+
maxSummaryLength: 1e5
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
const attachPublisher = (next) => {
|
|
157
|
+
publisher = next;
|
|
158
|
+
return runExclusive(async () => {
|
|
159
|
+
if (unsubscribeDaemon === void 0 && (process.env["NODE_ENV"] !== "test" || process.env["WRONGSTACK_KANBAN_FORCE_IPC"] === "1")) {
|
|
160
|
+
unsubscribeDaemon = bridgeKanbanSupervisor(
|
|
161
|
+
projectRoot,
|
|
162
|
+
(event) => {
|
|
163
|
+
const data = event.data;
|
|
164
|
+
schedulePublish(data?.boardId ?? null);
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
autoReconnect: true,
|
|
168
|
+
reconnectDelayMs: 1e3,
|
|
169
|
+
// Events emitted while the daemon was down cannot be replayed.
|
|
170
|
+
// Reconcile the authoritative snapshot after every connection.
|
|
171
|
+
onConnected: () => {
|
|
172
|
+
daemonConnectionCount++;
|
|
173
|
+
if (daemonConnectionCount > 1) schedulePublish(null);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
await publishLocal(true);
|
|
179
|
+
});
|
|
180
|
+
};
|
|
181
|
+
const applyRemote = async (snapshot) => {
|
|
182
|
+
if (snapshot.projectId !== projectId || stopped) return;
|
|
183
|
+
applyingRemote = true;
|
|
184
|
+
try {
|
|
185
|
+
const state = await readState(projectRoot);
|
|
186
|
+
for (const remote of snapshot.boards) {
|
|
187
|
+
const local = await readBoard(projectRoot, remote.boardId);
|
|
188
|
+
if (local !== null && compareVersions(
|
|
189
|
+
local.revision ?? 0,
|
|
190
|
+
local.updatedAt,
|
|
191
|
+
remote.revision,
|
|
192
|
+
remote.updatedAt
|
|
193
|
+
) >= 0) {
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
await writeBoard(projectRoot, remote.board);
|
|
197
|
+
state.boards[remote.boardId] = {
|
|
198
|
+
revision: remote.revision,
|
|
199
|
+
updatedAt: remote.updatedAt
|
|
200
|
+
};
|
|
201
|
+
delete state.tombstones[remote.boardId];
|
|
202
|
+
}
|
|
203
|
+
for (const tombstone of snapshot.tombstones) {
|
|
204
|
+
const local = await readBoard(projectRoot, tombstone.boardId);
|
|
205
|
+
if (local !== null && compareVersions(
|
|
206
|
+
local.revision ?? 0,
|
|
207
|
+
local.updatedAt,
|
|
208
|
+
tombstone.revision,
|
|
209
|
+
tombstone.deletedAt
|
|
210
|
+
) >= 0) {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (local !== null) await deleteBoard(projectRoot, tombstone.boardId);
|
|
214
|
+
state.boards[tombstone.boardId] = {
|
|
215
|
+
revision: Math.max(0, tombstone.revision - 1),
|
|
216
|
+
updatedAt: tombstone.deletedAt
|
|
217
|
+
};
|
|
218
|
+
state.tombstones[tombstone.boardId] = tombstone;
|
|
219
|
+
}
|
|
220
|
+
await writeState(projectRoot, state);
|
|
221
|
+
} finally {
|
|
222
|
+
applyingRemote = false;
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
const handleRemote = (snapshot) => {
|
|
226
|
+
if (snapshot.projectId !== projectId || stopped) return Promise.resolve();
|
|
227
|
+
pendingRemote = pendingRemote === null ? snapshot : coalesceRemoteSnapshots(pendingRemote, snapshot);
|
|
228
|
+
if (remoteApplyQueued) return Promise.resolve();
|
|
229
|
+
remoteApplyQueued = true;
|
|
230
|
+
return runExclusive(async () => {
|
|
231
|
+
remoteApplyQueued = false;
|
|
232
|
+
const batch = pendingRemote;
|
|
233
|
+
pendingRemote = null;
|
|
234
|
+
if (batch !== null) await applyRemote(batch);
|
|
235
|
+
}).catch(warnSyncFailure);
|
|
236
|
+
};
|
|
237
|
+
return {
|
|
238
|
+
attachPublisher,
|
|
239
|
+
handleRemote,
|
|
240
|
+
refresh: (boardId) => schedulePublish(boardId ?? null),
|
|
241
|
+
stop: () => {
|
|
242
|
+
stopped = true;
|
|
243
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
244
|
+
pendingBoardIds.clear();
|
|
245
|
+
fullRescanPending = false;
|
|
246
|
+
pendingRemote = null;
|
|
247
|
+
unsubscribeDaemon?.();
|
|
248
|
+
unsubscribeDaemon = void 0;
|
|
249
|
+
publisher = void 0;
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
function boardRecord(board) {
|
|
254
|
+
return {
|
|
255
|
+
boardId: board.id,
|
|
256
|
+
revision: board.revision ?? 0,
|
|
257
|
+
updatedAt: board.updatedAt,
|
|
258
|
+
board: structuredClone(board)
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
function chunkSnapshotPayload(projectId, generatedAt, boards, tombstones) {
|
|
262
|
+
const chunks = [];
|
|
263
|
+
const emptyPayload = () => ({
|
|
264
|
+
projectId,
|
|
265
|
+
generatedAt,
|
|
266
|
+
boards: [],
|
|
267
|
+
tombstones: []
|
|
268
|
+
});
|
|
269
|
+
const emptyPayloadBytes = Buffer.byteLength(JSON.stringify(emptyPayload()), "utf8");
|
|
270
|
+
let currentBoards = [];
|
|
271
|
+
let currentTombstones = [];
|
|
272
|
+
let currentBytes = emptyPayloadBytes;
|
|
273
|
+
const pushCurrent = () => {
|
|
274
|
+
if (currentBoards.length === 0 && currentTombstones.length === 0) return;
|
|
275
|
+
chunks.push({
|
|
276
|
+
projectId,
|
|
277
|
+
generatedAt,
|
|
278
|
+
boards: currentBoards,
|
|
279
|
+
tombstones: currentTombstones
|
|
280
|
+
});
|
|
281
|
+
currentBoards = [];
|
|
282
|
+
currentTombstones = [];
|
|
283
|
+
currentBytes = emptyPayloadBytes;
|
|
284
|
+
};
|
|
285
|
+
const append = (kind, item) => {
|
|
286
|
+
const itemBytes = Buffer.byteLength(JSON.stringify(item), "utf8");
|
|
287
|
+
const itemCount = kind === "boards" ? currentBoards.length : currentTombstones.length;
|
|
288
|
+
const additionalBytes = itemBytes + (itemCount > 0 ? 1 : 0);
|
|
289
|
+
if (emptyPayloadBytes + itemBytes > MAX_KANBAN_SNAPSHOT_PAYLOAD_BYTES) {
|
|
290
|
+
process.emitWarning(
|
|
291
|
+
`Kanban ${kind === "boards" ? "board" : "tombstone"} ${item.boardId} exceeds the ${MAX_KANBAN_SNAPSHOT_PAYLOAD_BYTES}-byte snapshot chunk target`,
|
|
292
|
+
{ code: "WRONGSTACK_HQ_KANBAN_OVERSIZED_RECORD" }
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
if ((currentBoards.length > 0 || currentTombstones.length > 0) && currentBytes + additionalBytes > MAX_KANBAN_SNAPSHOT_PAYLOAD_BYTES) {
|
|
296
|
+
pushCurrent();
|
|
297
|
+
}
|
|
298
|
+
if (kind === "boards") {
|
|
299
|
+
currentBoards.push(item);
|
|
300
|
+
} else {
|
|
301
|
+
currentTombstones.push(item);
|
|
302
|
+
}
|
|
303
|
+
currentBytes += itemBytes + (kind === "boards" ? currentBoards.length > 1 ? 1 : 0 : currentTombstones.length > 1 ? 1 : 0);
|
|
304
|
+
};
|
|
305
|
+
for (const board of boards) append("boards", board);
|
|
306
|
+
for (const tombstone of tombstones) append("tombstones", tombstone);
|
|
307
|
+
pushCurrent();
|
|
308
|
+
return chunks.length > 0 ? chunks : [emptyPayload()];
|
|
309
|
+
}
|
|
310
|
+
function coalesceRemoteSnapshots(older, newer) {
|
|
311
|
+
const byBoardId = /* @__PURE__ */ new Map();
|
|
312
|
+
const put = (candidate, boardId) => {
|
|
313
|
+
const existing = byBoardId.get(boardId);
|
|
314
|
+
if (existing === void 0 || compareVersions(existing.revision, existing.time, candidate.revision, candidate.time) <= 0) {
|
|
315
|
+
byBoardId.set(boardId, candidate);
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
for (const snapshot of [older, newer]) {
|
|
319
|
+
for (const record of snapshot.boards) {
|
|
320
|
+
put(
|
|
321
|
+
{ kind: "board", revision: record.revision, time: record.updatedAt, record },
|
|
322
|
+
record.boardId
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
for (const record of snapshot.tombstones) {
|
|
326
|
+
put(
|
|
327
|
+
{ kind: "tombstone", revision: record.revision, time: record.deletedAt, record },
|
|
328
|
+
record.boardId
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
const merged = {
|
|
333
|
+
projectId: newer.projectId,
|
|
334
|
+
generatedAt: newer.generatedAt,
|
|
335
|
+
boards: [],
|
|
336
|
+
tombstones: []
|
|
337
|
+
};
|
|
338
|
+
for (const entry of byBoardId.values()) {
|
|
339
|
+
if (entry.kind === "board") merged.boards.push(entry.record);
|
|
340
|
+
else merged.tombstones.push(entry.record);
|
|
341
|
+
}
|
|
342
|
+
return merged;
|
|
343
|
+
}
|
|
344
|
+
function compareVersions(aRevision, aTime, bRevision, bTime) {
|
|
345
|
+
if (aRevision !== bRevision) return aRevision - bRevision;
|
|
346
|
+
return aTime.localeCompare(bTime);
|
|
347
|
+
}
|
|
348
|
+
function isExpiredVersion(timestamp, now) {
|
|
349
|
+
const parsed = Date.parse(timestamp);
|
|
350
|
+
return !Number.isNaN(parsed) && parsed <= now - KANBAN_TOMBSTONE_RETENTION_MS;
|
|
351
|
+
}
|
|
352
|
+
function pruneExpiredTombstones(state, now) {
|
|
353
|
+
let changed = false;
|
|
354
|
+
for (const [boardId, tombstone] of Object.entries(state.tombstones)) {
|
|
355
|
+
if (!isExpiredVersion(tombstone.deletedAt, now)) continue;
|
|
356
|
+
delete state.tombstones[boardId];
|
|
357
|
+
delete state.boards[boardId];
|
|
358
|
+
changed = true;
|
|
359
|
+
}
|
|
360
|
+
return changed;
|
|
361
|
+
}
|
|
362
|
+
async function readState(projectRoot) {
|
|
363
|
+
try {
|
|
364
|
+
const raw = await readKanbanMetadata(projectRoot, SYNC_STATE_KEY);
|
|
365
|
+
if (raw === null) return { boards: {}, tombstones: {} };
|
|
366
|
+
const parsed = JSON.parse(raw);
|
|
367
|
+
return { boards: parsed.boards ?? {}, tombstones: parsed.tombstones ?? {} };
|
|
368
|
+
} catch {
|
|
369
|
+
return { boards: {}, tombstones: {} };
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
async function writeState(projectRoot, state) {
|
|
373
|
+
await writeKanbanMetadata(projectRoot, SYNC_STATE_KEY, JSON.stringify(state));
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// src/hq-publisher.ts
|
|
377
|
+
function nodeWsSocketFactory(url) {
|
|
378
|
+
return new WebSocket(url);
|
|
379
|
+
}
|
|
380
|
+
function createCliHqPublisher(options) {
|
|
381
|
+
return createHqPublisherFromEnv({
|
|
382
|
+
...options,
|
|
383
|
+
socketFactory: options.socketFactory ?? nodeWsSocketFactory
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
function hqExplicitlyDisabled(options) {
|
|
387
|
+
const envEnabled = process.env["WRONGSTACK_HQ_ENABLED"]?.trim();
|
|
388
|
+
if (envEnabled !== void 0 && envEnabled.length > 0) return envEnabled === "0";
|
|
389
|
+
if (options.config?.enabled !== void 0) return options.config.enabled === false;
|
|
390
|
+
return options.appConfig?.hq?.enabled === false;
|
|
391
|
+
}
|
|
392
|
+
function resolvedHqConnectionKey(options) {
|
|
393
|
+
if (options.config !== void 0) {
|
|
394
|
+
return options.config.enabled === false ? void 0 : `${options.config.url}
|
|
395
|
+
${options.config.token ?? ""}`;
|
|
396
|
+
}
|
|
397
|
+
const config = resolveHqConfig({ config: options.appConfig?.hq });
|
|
398
|
+
return config === void 0 ? void 0 : `${config.url}
|
|
399
|
+
${config.token ?? ""}`;
|
|
400
|
+
}
|
|
401
|
+
function startCliHqConnection(options) {
|
|
402
|
+
const shouldOwnKanbanSync = options.onKanbanSnapshot === void 0;
|
|
403
|
+
let kanbanSync;
|
|
404
|
+
const publisherOptions = shouldOwnKanbanSync ? {
|
|
405
|
+
...options,
|
|
406
|
+
onKanbanSnapshot: (snapshot) => kanbanSync?.handleRemote(snapshot)
|
|
407
|
+
} : options;
|
|
408
|
+
let publisher;
|
|
409
|
+
let publisherKey;
|
|
410
|
+
let timer;
|
|
411
|
+
const tryConnect = () => {
|
|
412
|
+
const nextKey = resolvedHqConnectionKey(options);
|
|
413
|
+
if (nextKey === void 0) return;
|
|
414
|
+
if (publisher !== void 0 && publisherKey === nextKey) return;
|
|
415
|
+
publisher?.close();
|
|
416
|
+
publisher = void 0;
|
|
417
|
+
publisherKey = void 0;
|
|
418
|
+
const next = createCliHqPublisher(publisherOptions);
|
|
419
|
+
if (next === void 0) return;
|
|
420
|
+
publisher = next;
|
|
421
|
+
publisherKey = nextKey;
|
|
422
|
+
if (shouldOwnKanbanSync) {
|
|
423
|
+
kanbanSync?.stop();
|
|
424
|
+
kanbanSync = createKanbanHqSync(options.projectRoot, next.project.projectId);
|
|
425
|
+
}
|
|
426
|
+
next.connect();
|
|
427
|
+
if (kanbanSync !== void 0) {
|
|
428
|
+
kanbanSync.attachPublisher(next).catch((error) => {
|
|
429
|
+
process.emitWarning(
|
|
430
|
+
`WrongStack kanban HQ sync attach failed (best-effort, retried on reconnect): ${error instanceof Error ? error.message : String(error)}`,
|
|
431
|
+
{ code: "WRONGSTACK_HQ_KANBAN_SYNC_FAILED" }
|
|
432
|
+
);
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
options.onConnect?.(next);
|
|
436
|
+
};
|
|
437
|
+
tryConnect();
|
|
438
|
+
if (!hqExplicitlyDisabled(options)) {
|
|
439
|
+
timer = setInterval(tryConnect, options.retryIntervalMs ?? 2500);
|
|
440
|
+
timer.unref?.();
|
|
441
|
+
}
|
|
442
|
+
return {
|
|
443
|
+
getPublisher: () => publisher,
|
|
444
|
+
stop: () => {
|
|
445
|
+
if (timer !== void 0) {
|
|
446
|
+
clearInterval(timer);
|
|
447
|
+
timer = void 0;
|
|
448
|
+
}
|
|
449
|
+
kanbanSync?.stop();
|
|
450
|
+
publisher?.close();
|
|
451
|
+
publisher = void 0;
|
|
452
|
+
publisherKey = void 0;
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
export {
|
|
458
|
+
startCliHqConnection
|
|
459
|
+
};
|
|
460
|
+
//# sourceMappingURL=chunk-WY7KKOUK.js.map
|