@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,560 @@
|
|
|
1
|
+
|
|
2
|
+
// src/plugin-management.ts
|
|
3
|
+
import * as fs from "node:fs/promises";
|
|
4
|
+
import { atomicWrite } from "@wrongstack/core/utils";
|
|
5
|
+
import { OFFICIAL_PLUGIN_AUDIT_ENTRIES } from "@wrongstack/plugins/audit";
|
|
6
|
+
var HOST_PLUGIN_AUDIT_ENTRIES = [
|
|
7
|
+
{
|
|
8
|
+
name: "wstack-prompts",
|
|
9
|
+
risk: "medium",
|
|
10
|
+
summary: "Prompt library and prompt authoring commands.",
|
|
11
|
+
defaultState: "active",
|
|
12
|
+
canDisable: true
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: "wstack-sync",
|
|
16
|
+
risk: "medium",
|
|
17
|
+
summary: "Cloud sync commands for prompts, skills, settings, memory, and history.",
|
|
18
|
+
defaultState: "active",
|
|
19
|
+
canDisable: true
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: "wstack-git",
|
|
23
|
+
risk: "high",
|
|
24
|
+
summary: "Git commands for commit, status checks, and push.",
|
|
25
|
+
defaultState: "active",
|
|
26
|
+
canDisable: true
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: "wstack-observability",
|
|
30
|
+
risk: "low",
|
|
31
|
+
summary: "Runtime metrics and health slash commands.",
|
|
32
|
+
defaultState: "active",
|
|
33
|
+
canDisable: true
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: "wstack-chimera",
|
|
37
|
+
risk: "medium",
|
|
38
|
+
summary: "Spawns a post-session code review subagent when explicitly enabled.",
|
|
39
|
+
defaultState: "inactive",
|
|
40
|
+
canDisable: true
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "wstack-skills",
|
|
44
|
+
risk: "medium",
|
|
45
|
+
summary: "Skill library, authoring, install, update, and uninstall commands.",
|
|
46
|
+
defaultState: "active",
|
|
47
|
+
canDisable: true
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: "wstack-plan",
|
|
51
|
+
risk: "medium",
|
|
52
|
+
summary: "Strategic plan board slash command.",
|
|
53
|
+
defaultState: "active",
|
|
54
|
+
canDisable: true
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: "@wrongstack/plug-lsp",
|
|
58
|
+
risk: "medium",
|
|
59
|
+
summary: "Language Server Protocol tools and slash commands.",
|
|
60
|
+
defaultState: "inactive",
|
|
61
|
+
canDisable: true
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: "telegram",
|
|
65
|
+
risk: "medium",
|
|
66
|
+
summary: "Telegram bridge for messages, approvals, and notifications.",
|
|
67
|
+
defaultState: "inactive",
|
|
68
|
+
canDisable: true
|
|
69
|
+
}
|
|
70
|
+
];
|
|
71
|
+
var PLUGIN_AUDIT_ENTRIES = Object.freeze([
|
|
72
|
+
...HOST_PLUGIN_AUDIT_ENTRIES,
|
|
73
|
+
...OFFICIAL_PLUGIN_AUDIT_ENTRIES
|
|
74
|
+
]);
|
|
75
|
+
var OFFICIAL_PLUGINS = [
|
|
76
|
+
{
|
|
77
|
+
alias: "telegram",
|
|
78
|
+
specifier: "@wrongstack/telegram",
|
|
79
|
+
description: "Telegram bridge for prompts, notifications, and slash commands."
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
alias: "lsp",
|
|
83
|
+
specifier: "@wrongstack/plug-lsp",
|
|
84
|
+
description: "Language Server Protocol tools for code intelligence."
|
|
85
|
+
}
|
|
86
|
+
];
|
|
87
|
+
var OFFICIAL_ALIASES = new Map(
|
|
88
|
+
OFFICIAL_PLUGINS.flatMap((p) => [
|
|
89
|
+
[p.alias, p.specifier],
|
|
90
|
+
[p.specifier, p.specifier]
|
|
91
|
+
])
|
|
92
|
+
);
|
|
93
|
+
async function runPluginManagementCommand(args, deps) {
|
|
94
|
+
const sub = args[0];
|
|
95
|
+
if (!sub || sub === "list" || sub === "status") {
|
|
96
|
+
return {
|
|
97
|
+
code: 0,
|
|
98
|
+
level: "output",
|
|
99
|
+
message: renderConfiguredPlugins(deps.config)
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
if (sub === "official" || sub === "officials") {
|
|
103
|
+
return {
|
|
104
|
+
code: 0,
|
|
105
|
+
level: "output",
|
|
106
|
+
message: renderOfficialPlugins(deps.config)
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
if (sub === "report" || sub === "audit" || sub === "menu") {
|
|
110
|
+
return {
|
|
111
|
+
code: 0,
|
|
112
|
+
level: "output",
|
|
113
|
+
message: renderPluginAuditReport(deps.config)
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
if (sub === "add" || sub === "install") {
|
|
117
|
+
const spec = args[1];
|
|
118
|
+
if (!spec) {
|
|
119
|
+
return errorResult("Usage: wstack plugin add <specifier|official-alias> [--disabled]");
|
|
120
|
+
}
|
|
121
|
+
return upsertPlugin(
|
|
122
|
+
resolvePluginSpecifier(spec),
|
|
123
|
+
{ enabled: !args.includes("--disabled") },
|
|
124
|
+
deps,
|
|
125
|
+
"Added"
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
if (sub === "remove" || sub === "rm" || sub === "uninstall") {
|
|
129
|
+
const spec = args[1];
|
|
130
|
+
if (!spec) {
|
|
131
|
+
return errorResult("Usage: wstack plugin remove <specifier|official-alias>");
|
|
132
|
+
}
|
|
133
|
+
return removePlugin(resolvePluginSpecifier(spec), deps);
|
|
134
|
+
}
|
|
135
|
+
if (sub === "enable" || sub === "disable") {
|
|
136
|
+
const spec = args[1];
|
|
137
|
+
if (!spec) {
|
|
138
|
+
return errorResult(`Usage: wstack plugin ${sub} <specifier|official-alias>`);
|
|
139
|
+
}
|
|
140
|
+
return upsertPlugin(
|
|
141
|
+
resolvePluginSpecifier(spec),
|
|
142
|
+
{ enabled: sub === "enable" },
|
|
143
|
+
deps,
|
|
144
|
+
sub === "enable" ? "Enabled" : "Disabled"
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
if (sub === "toggle") {
|
|
148
|
+
const spec = args[1];
|
|
149
|
+
if (!spec) {
|
|
150
|
+
return errorResult("Usage: wstack plugin toggle <plugin-name|official-alias>");
|
|
151
|
+
}
|
|
152
|
+
return togglePlugin(resolvePluginToggleSpecifier(spec), deps);
|
|
153
|
+
}
|
|
154
|
+
if (sub === "manager") {
|
|
155
|
+
return runPluginManagerPolicyCommand(args.slice(1), deps);
|
|
156
|
+
}
|
|
157
|
+
if (sub === "llm") {
|
|
158
|
+
return runPluginLlmCommand(args.slice(1), deps);
|
|
159
|
+
}
|
|
160
|
+
return errorResult(
|
|
161
|
+
`Unknown plugin subcommand: ${sub}
|
|
162
|
+
Usage: wstack plugin [list|status|report|menu|official|add|install|remove|enable|disable|toggle|manager|llm]`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
var PLUGIN_MANAGER_POLICY_USAGE = [
|
|
166
|
+
"Usage:",
|
|
167
|
+
" wstack plugin manager List plugins locked against LLM state changes.",
|
|
168
|
+
" wstack plugin manager lock <plugin|*> Prevent plugin_manager from enabling/disabling it.",
|
|
169
|
+
" wstack plugin manager unlock <plugin|*> Restore plugin_manager enable/disable access.",
|
|
170
|
+
"",
|
|
171
|
+
"This policy affects only the LLM-facing plugin_manager tool. Human /plugin and",
|
|
172
|
+
"wstack plugin enable/disable commands remain available."
|
|
173
|
+
].join("\n");
|
|
174
|
+
async function runPluginManagerPolicyCommand(args, deps) {
|
|
175
|
+
const action = args[0] ?? "list";
|
|
176
|
+
if (action === "list") {
|
|
177
|
+
const locked = deps.config.pluginManager?.locked ?? [];
|
|
178
|
+
return {
|
|
179
|
+
code: 0,
|
|
180
|
+
level: "output",
|
|
181
|
+
message: locked.length === 0 ? "LLM plugin-manager policy: no plugins are locked." : `LLM plugin-manager policy \u2014 locked (${locked.length}):
|
|
182
|
+
${locked.map((name2) => ` ${name2}`).join("\n")}`
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
if (action !== "lock" && action !== "unlock") {
|
|
186
|
+
return errorResult(PLUGIN_MANAGER_POLICY_USAGE);
|
|
187
|
+
}
|
|
188
|
+
const rawName = args[1];
|
|
189
|
+
if (!rawName) return errorResult(PLUGIN_MANAGER_POLICY_USAGE);
|
|
190
|
+
const name = rawName === "*" ? "*" : resolvePluginToggleSpecifier(rawName);
|
|
191
|
+
const existing = await readConfig(deps.configPath);
|
|
192
|
+
const filePolicy = isRecord(existing.pluginManager) ? existing.pluginManager : void 0;
|
|
193
|
+
const current = Array.isArray(filePolicy?.["locked"]) ? filePolicy["locked"].filter((entry) => typeof entry === "string") : [...deps.config.pluginManager?.locked ?? []];
|
|
194
|
+
const canonical = canonicalPolicyName(name);
|
|
195
|
+
const next = action === "lock" ? current.some((entry) => canonicalPolicyName(entry) === canonical) ? current : [...current, name] : current.filter((entry) => canonicalPolicyName(entry) !== canonical);
|
|
196
|
+
const pluginManager = { locked: next };
|
|
197
|
+
existing.pluginManager = { ...filePolicy ?? {}, ...pluginManager };
|
|
198
|
+
await atomicWrite(deps.configPath, JSON.stringify(existing, null, 2), { mode: 384 });
|
|
199
|
+
return {
|
|
200
|
+
code: 0,
|
|
201
|
+
level: "info",
|
|
202
|
+
message: action === "lock" ? `Locked "${name}" against LLM enable/disable changes. Human plugin commands still work.` : `Unlocked "${name}" for LLM enable/disable changes.`,
|
|
203
|
+
patch: { pluginManager }
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
function canonicalPolicyName(name) {
|
|
207
|
+
if (name === "*") return name;
|
|
208
|
+
return resolvePluginToggleSpecifier(name).trim().toLowerCase();
|
|
209
|
+
}
|
|
210
|
+
var PLUGIN_LLM_USAGE = [
|
|
211
|
+
"Usage:",
|
|
212
|
+
" wstack plugin llm List every per-plugin LLM override.",
|
|
213
|
+
" wstack plugin llm <plugin> Show one plugin's LLM override.",
|
|
214
|
+
" wstack plugin llm <plugin> <provider> [model] Route this plugin through a provider (and model).",
|
|
215
|
+
" wstack plugin llm <plugin> - <model> Keep the session provider, override only the model.",
|
|
216
|
+
" wstack plugin llm <plugin> --clear Remove the override (back to the session default).",
|
|
217
|
+
"",
|
|
218
|
+
"The override is stored as config.extensions.<plugin>.llm and is used by",
|
|
219
|
+
"every api.llm call the plugin makes. Without an override, plugins follow",
|
|
220
|
+
"the active session provider/model (the chat leader)."
|
|
221
|
+
].join("\n");
|
|
222
|
+
function renderPluginLlmOverviews(config, sessionDefault) {
|
|
223
|
+
const rows = [];
|
|
224
|
+
for (const [pluginName2, ext] of Object.entries(config.extensions ?? {})) {
|
|
225
|
+
const llm = ext?.["llm"];
|
|
226
|
+
if (llm && typeof llm === "object") {
|
|
227
|
+
const o = llm;
|
|
228
|
+
rows.push({
|
|
229
|
+
name: pluginName2,
|
|
230
|
+
provider: o.provider ?? "(session)",
|
|
231
|
+
model: o.model ?? "(session)"
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const lines = [`Per-plugin LLM routing (session default: ${sessionDefault}):`];
|
|
236
|
+
if (rows.length === 0) {
|
|
237
|
+
lines.push(
|
|
238
|
+
" No plugin overrides \u2014 every plugin follows the session default.",
|
|
239
|
+
" Set one with: wstack plugin llm <plugin> <provider> [model]"
|
|
240
|
+
);
|
|
241
|
+
} else {
|
|
242
|
+
rows.sort((a, b) => a.name.localeCompare(b.name));
|
|
243
|
+
for (const r of rows) {
|
|
244
|
+
lines.push(` ${r.name.padEnd(24)} provider=${r.provider.padEnd(16)} model=${r.model}`);
|
|
245
|
+
}
|
|
246
|
+
lines.push("", "Clear one with: wstack plugin llm <plugin> --clear");
|
|
247
|
+
}
|
|
248
|
+
return lines.join("\n");
|
|
249
|
+
}
|
|
250
|
+
async function runPluginLlmCommand(args, deps) {
|
|
251
|
+
const sessionDefault = `${deps.config.provider ?? "?"} / ${deps.config.model ?? "?"}`;
|
|
252
|
+
if (args.length === 0 || args[0] === "list") {
|
|
253
|
+
return {
|
|
254
|
+
code: 0,
|
|
255
|
+
level: "output",
|
|
256
|
+
message: renderPluginLlmOverviews(deps.config, sessionDefault)
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
const name = args[0];
|
|
260
|
+
if (!name || name.startsWith("-")) return errorResult(PLUGIN_LLM_USAGE);
|
|
261
|
+
const currentOverride = deps.config.extensions?.[name]?.["llm"];
|
|
262
|
+
if (args.length === 1) {
|
|
263
|
+
const lines = [`LLM routing for plugin "${name}":`];
|
|
264
|
+
if (currentOverride && typeof currentOverride === "object") {
|
|
265
|
+
const o = currentOverride;
|
|
266
|
+
lines.push(
|
|
267
|
+
` override: provider=${o.provider ?? "(session)"} model=${o.model ?? "(session)"}`,
|
|
268
|
+
` session default: ${sessionDefault}`
|
|
269
|
+
);
|
|
270
|
+
} else {
|
|
271
|
+
lines.push(
|
|
272
|
+
` no override \u2014 follows the session default (${sessionDefault}).`,
|
|
273
|
+
` Set one with: wstack plugin llm ${name} <provider> [model]`
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
return { code: 0, level: "output", message: lines.join("\n") };
|
|
277
|
+
}
|
|
278
|
+
const existing = await readConfig(deps.configPath);
|
|
279
|
+
const fileExtensions = isRecord(existing.extensions) ? existing.extensions : {};
|
|
280
|
+
const pluginExt = isRecord(fileExtensions[name]) ? { ...fileExtensions[name] } : {};
|
|
281
|
+
if (args[1] === "--clear" || args[1] === "clear") {
|
|
282
|
+
if (!("llm" in pluginExt) && !currentOverride) {
|
|
283
|
+
return { code: 0, level: "info", message: `Plugin "${name}" has no LLM override.` };
|
|
284
|
+
}
|
|
285
|
+
delete pluginExt["llm"];
|
|
286
|
+
if (Object.keys(pluginExt).length === 0) delete fileExtensions[name];
|
|
287
|
+
else fileExtensions[name] = pluginExt;
|
|
288
|
+
existing.extensions = fileExtensions;
|
|
289
|
+
await atomicWrite(deps.configPath, JSON.stringify(existing, null, 2), { mode: 384 });
|
|
290
|
+
const merged2 = mergeExtensionsForPatch(deps.config, fileExtensions);
|
|
291
|
+
const mergedEntry = merged2[name];
|
|
292
|
+
if (mergedEntry) {
|
|
293
|
+
delete mergedEntry["llm"];
|
|
294
|
+
if (Object.keys(mergedEntry).length === 0) delete merged2[name];
|
|
295
|
+
}
|
|
296
|
+
return {
|
|
297
|
+
code: 0,
|
|
298
|
+
level: "info",
|
|
299
|
+
message: `Cleared LLM override for "${name}" \u2014 it now follows the session default (${sessionDefault}). Takes effect immediately for api.llm calls.`,
|
|
300
|
+
patch: { extensions: merged2 }
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
const providerArg = args[1];
|
|
304
|
+
const modelArg = args[2];
|
|
305
|
+
if (!providerArg || providerArg.startsWith("--")) return errorResult(PLUGIN_LLM_USAGE);
|
|
306
|
+
const provider = providerArg === "-" ? void 0 : providerArg;
|
|
307
|
+
const model = modelArg && modelArg !== "-" ? modelArg : void 0;
|
|
308
|
+
if (!provider && !model) return errorResult(PLUGIN_LLM_USAGE);
|
|
309
|
+
const llm = {};
|
|
310
|
+
if (provider) llm["provider"] = provider;
|
|
311
|
+
if (model) llm["model"] = model;
|
|
312
|
+
pluginExt["llm"] = llm;
|
|
313
|
+
fileExtensions[name] = pluginExt;
|
|
314
|
+
existing.extensions = fileExtensions;
|
|
315
|
+
await atomicWrite(deps.configPath, JSON.stringify(existing, null, 2), { mode: 384 });
|
|
316
|
+
const configured = Object.keys(deps.config.providers ?? {});
|
|
317
|
+
const note = provider && configured.length > 0 && !configured.includes(provider) ? `
|
|
318
|
+
Note: "${provider}" is not in config.providers (configured: ${configured.join(", ")}). Catalog providers (anthropic, openai, \u2026) still resolve if credentials are available.` : "";
|
|
319
|
+
const merged = mergeExtensionsForPatch(deps.config, fileExtensions);
|
|
320
|
+
return {
|
|
321
|
+
code: 0,
|
|
322
|
+
level: "info",
|
|
323
|
+
message: `Plugin "${name}" now routes api.llm calls via provider=${provider ?? "(session)"} model=${model ?? "(session)"}. Session default stays ${sessionDefault}. Takes effect immediately for api.llm calls.${note}`,
|
|
324
|
+
patch: { extensions: merged }
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
function mergeExtensionsForPatch(config, fileExtensions) {
|
|
328
|
+
const merged = {};
|
|
329
|
+
for (const [k, v] of Object.entries(config.extensions ?? {})) {
|
|
330
|
+
merged[k] = { ...v };
|
|
331
|
+
}
|
|
332
|
+
for (const [k, v] of Object.entries(fileExtensions)) {
|
|
333
|
+
if (isRecord(v)) merged[k] = { ...merged[k] ?? {}, ...v };
|
|
334
|
+
}
|
|
335
|
+
for (const k of Object.keys(merged)) {
|
|
336
|
+
if (!(k in fileExtensions) && !(k in (config.extensions ?? {}))) delete merged[k];
|
|
337
|
+
}
|
|
338
|
+
return merged;
|
|
339
|
+
}
|
|
340
|
+
function resolvePluginSpecifier(input) {
|
|
341
|
+
return OFFICIAL_ALIASES.get(input.toLowerCase()) ?? input;
|
|
342
|
+
}
|
|
343
|
+
function resolvePluginToggleSpecifier(input) {
|
|
344
|
+
if (input.toLowerCase() === "@wrongstack/telegram") return "telegram";
|
|
345
|
+
if (auditEntryFor(input)) return input;
|
|
346
|
+
return resolvePluginSpecifier(input);
|
|
347
|
+
}
|
|
348
|
+
function renderOfficialPlugins(config) {
|
|
349
|
+
return [
|
|
350
|
+
"Official plugins:",
|
|
351
|
+
...OFFICIAL_PLUGINS.map((p) => {
|
|
352
|
+
const state = config ? officialPluginState(config, p.specifier) : "";
|
|
353
|
+
const status = state ? `${state.padEnd(14)} ` : "";
|
|
354
|
+
return ` ${p.alias.padEnd(12)} ${status}${p.specifier.padEnd(24)} ${p.description}`;
|
|
355
|
+
}),
|
|
356
|
+
"",
|
|
357
|
+
"Use `wstack plugin add <alias>` or `/plugin install <alias>`."
|
|
358
|
+
].join("\n");
|
|
359
|
+
}
|
|
360
|
+
function renderConfiguredPlugins(config) {
|
|
361
|
+
const plugins = config.plugins ?? [];
|
|
362
|
+
if (plugins.length === 0) {
|
|
363
|
+
return [
|
|
364
|
+
"No plugins configured.",
|
|
365
|
+
"Use `wstack plugin add <specifier>` or `/plugin install <official-alias>`."
|
|
366
|
+
].join("\n");
|
|
367
|
+
}
|
|
368
|
+
return plugins.map((p) => {
|
|
369
|
+
const name = pluginName(p);
|
|
370
|
+
const enabled = typeof p === "object" && p.enabled === false ? "disabled" : "enabled";
|
|
371
|
+
const official = OFFICIAL_PLUGINS.find((entry) => entry.specifier === name);
|
|
372
|
+
const suffix = official ? ` (${official.alias})` : "";
|
|
373
|
+
return ` ${`${name}${suffix}`.padEnd(44)} ${enabled}`;
|
|
374
|
+
}).join("\n");
|
|
375
|
+
}
|
|
376
|
+
function renderPluginAuditReport(config) {
|
|
377
|
+
const configured = config.plugins ?? [];
|
|
378
|
+
const lines = [
|
|
379
|
+
"Plugin audit report:",
|
|
380
|
+
" State shows the effective boot state. Default-active plugins run unless disabled in config.",
|
|
381
|
+
" Built-in audit rows are toggleable unless a future row explicitly marks itself locked.",
|
|
382
|
+
"",
|
|
383
|
+
" Built-in audit entries:"
|
|
384
|
+
];
|
|
385
|
+
for (const entry of PLUGIN_AUDIT_ENTRIES) {
|
|
386
|
+
const { state, source } = effectiveAuditState(config, entry);
|
|
387
|
+
const policy = entry.canDisable ? "toggleable" : lockedReason(entry);
|
|
388
|
+
lines.push(
|
|
389
|
+
` ${entry.name.padEnd(24)} ${state.padEnd(8)} ${source.padEnd(8)} risk=${entry.risk.padEnd(6)} ${policy.padEnd(24)} ${entry.summary}`
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
const extra = configured.filter(
|
|
393
|
+
(plugin) => !PLUGIN_AUDIT_ENTRIES.some((entry) => pluginMatchesToggleSpec(plugin, entry.name))
|
|
394
|
+
);
|
|
395
|
+
if (extra.length > 0) {
|
|
396
|
+
lines.push("", " Configured plugins outside the audit list:");
|
|
397
|
+
for (const plugin of extra) {
|
|
398
|
+
const name = pluginName(plugin);
|
|
399
|
+
const state = typeof plugin === "object" && plugin.enabled === false ? "disabled" : "enabled";
|
|
400
|
+
lines.push(
|
|
401
|
+
` ${name.padEnd(24)} ${state.padEnd(8)} config risk=custom user-configured plugin`
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
lines.push(
|
|
406
|
+
"",
|
|
407
|
+
"Use `/plugin menu` in the TUI, or `wstack plugin toggle <name>` for toggleable rows."
|
|
408
|
+
);
|
|
409
|
+
return lines.join("\n");
|
|
410
|
+
}
|
|
411
|
+
async function readConfig(file) {
|
|
412
|
+
try {
|
|
413
|
+
return JSON.parse(await fs.readFile(file, "utf8"));
|
|
414
|
+
} catch {
|
|
415
|
+
return {};
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
function pluginName(p) {
|
|
419
|
+
return typeof p === "string" ? p : p.name;
|
|
420
|
+
}
|
|
421
|
+
function pluginEntry(spec, enabled) {
|
|
422
|
+
return enabled ? spec : { name: spec, enabled: false };
|
|
423
|
+
}
|
|
424
|
+
function pluginMatchesToggleSpec(p, spec) {
|
|
425
|
+
const name = pluginName(p);
|
|
426
|
+
if (spec === "telegram") return name === "telegram" || name === "@wrongstack/telegram";
|
|
427
|
+
return name === spec;
|
|
428
|
+
}
|
|
429
|
+
function effectiveAuditState(config, entry) {
|
|
430
|
+
const configured = (config.plugins ?? []).find(
|
|
431
|
+
(plugin) => pluginMatchesToggleSpec(plugin, entry.name)
|
|
432
|
+
);
|
|
433
|
+
if (configured) {
|
|
434
|
+
return {
|
|
435
|
+
state: typeof configured === "object" && configured.enabled === false ? "disabled" : "enabled",
|
|
436
|
+
source: "config"
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
return {
|
|
440
|
+
state: entry.defaultState === "active" ? "enabled" : "disabled",
|
|
441
|
+
source: "default"
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
function lockedReason(entry) {
|
|
445
|
+
if (entry.canDisable) return "toggleable";
|
|
446
|
+
if (entry.name === "secret-scanner") {
|
|
447
|
+
return "locked: safety guard";
|
|
448
|
+
}
|
|
449
|
+
return "locked: core surface";
|
|
450
|
+
}
|
|
451
|
+
function auditEntryFor(spec) {
|
|
452
|
+
return PLUGIN_AUDIT_ENTRIES.find((entry) => entry.name === spec);
|
|
453
|
+
}
|
|
454
|
+
function officialPluginState(config, spec) {
|
|
455
|
+
const match = (config.plugins ?? []).find((p) => pluginName(p) === spec);
|
|
456
|
+
if (!match) return "not configured";
|
|
457
|
+
return typeof match === "object" && match.enabled === false ? "disabled" : "enabled";
|
|
458
|
+
}
|
|
459
|
+
async function togglePlugin(spec, deps) {
|
|
460
|
+
const auditEntry = auditEntryFor(spec);
|
|
461
|
+
if (auditEntry?.canDisable === false) {
|
|
462
|
+
return errorResult(`Plugin "${spec}" is locked and cannot be toggled from the plugin menu.`);
|
|
463
|
+
}
|
|
464
|
+
const existing = await readConfig(deps.configPath);
|
|
465
|
+
const plugins = Array.isArray(existing.plugins) ? existing.plugins : [];
|
|
466
|
+
const idx = plugins.findIndex((p) => pluginMatchesToggleSpec(p, spec));
|
|
467
|
+
const configured = idx >= 0 ? plugins[idx] : void 0;
|
|
468
|
+
const enabled = configured ? !(typeof configured === "object" && configured.enabled === false) : auditEntry?.defaultState === "active";
|
|
469
|
+
if (!configured && !auditEntry) {
|
|
470
|
+
return errorResult(
|
|
471
|
+
`Plugin "${spec}" is not configured. Use "wstack plugin add ${spec}" first.`
|
|
472
|
+
);
|
|
473
|
+
}
|
|
474
|
+
let nextPlugins;
|
|
475
|
+
let nextEnabled;
|
|
476
|
+
if (enabled) {
|
|
477
|
+
nextEnabled = false;
|
|
478
|
+
nextPlugins = plugins.filter((p) => !pluginMatchesToggleSpec(p, spec));
|
|
479
|
+
if (auditEntry?.defaultState !== "inactive") {
|
|
480
|
+
nextPlugins.push({ name: spec, enabled: false });
|
|
481
|
+
}
|
|
482
|
+
} else {
|
|
483
|
+
nextEnabled = true;
|
|
484
|
+
if (auditEntry?.defaultState === "active") {
|
|
485
|
+
nextPlugins = plugins.filter((p) => !pluginMatchesToggleSpec(p, spec));
|
|
486
|
+
} else {
|
|
487
|
+
nextPlugins = plugins.filter((p) => !pluginMatchesToggleSpec(p, spec));
|
|
488
|
+
nextPlugins.push(spec);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
const features = {
|
|
492
|
+
...isRecord(deps.config.features) ? deps.config.features : {},
|
|
493
|
+
...isRecord(existing.features) ? existing.features : {},
|
|
494
|
+
plugins: true
|
|
495
|
+
};
|
|
496
|
+
existing.plugins = nextPlugins;
|
|
497
|
+
existing.features = features;
|
|
498
|
+
await atomicWrite(deps.configPath, JSON.stringify(existing, null, 2), { mode: 384 });
|
|
499
|
+
const restartRequired = spec === "branch-guard" && !nextEnabled ? void 0 : true;
|
|
500
|
+
return {
|
|
501
|
+
code: 0,
|
|
502
|
+
level: "info",
|
|
503
|
+
message: `${nextEnabled ? "Enabled" : "Disabled"} "${spec}". Config written to ${deps.configPath}.` + (spec === "branch-guard" && !nextEnabled ? " The running branch-guard hook will disable itself on config update." : ""),
|
|
504
|
+
patch: { plugins: nextPlugins, features },
|
|
505
|
+
restartRequired
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
async function upsertPlugin(spec, opts, deps, verb) {
|
|
509
|
+
const existing = await readConfig(deps.configPath);
|
|
510
|
+
const plugins = Array.isArray(existing.plugins) ? existing.plugins : [];
|
|
511
|
+
const idx = plugins.findIndex((p) => pluginName(p) === spec);
|
|
512
|
+
const nextEntry = pluginEntry(spec, opts.enabled);
|
|
513
|
+
if (idx >= 0) plugins[idx] = nextEntry;
|
|
514
|
+
else plugins.push(nextEntry);
|
|
515
|
+
const features = {
|
|
516
|
+
...isRecord(deps.config.features) ? deps.config.features : {},
|
|
517
|
+
...isRecord(existing.features) ? existing.features : {},
|
|
518
|
+
plugins: true
|
|
519
|
+
};
|
|
520
|
+
existing.plugins = plugins;
|
|
521
|
+
existing.features = features;
|
|
522
|
+
await atomicWrite(deps.configPath, JSON.stringify(existing, null, 2), { mode: 384 });
|
|
523
|
+
const restartRequired = spec === "branch-guard" && !opts.enabled ? void 0 : true;
|
|
524
|
+
return {
|
|
525
|
+
code: 0,
|
|
526
|
+
level: "info",
|
|
527
|
+
message: `${verb} "${spec}" (${opts.enabled ? "enabled" : "disabled"}). Config written to ${deps.configPath}.` + (spec === "branch-guard" && !opts.enabled ? " The running branch-guard hook will disable itself on config update." : ""),
|
|
528
|
+
patch: { plugins, features },
|
|
529
|
+
restartRequired
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
async function removePlugin(spec, deps) {
|
|
533
|
+
const existing = await readConfig(deps.configPath);
|
|
534
|
+
const plugins = Array.isArray(existing.plugins) ? existing.plugins : [];
|
|
535
|
+
const next = plugins.filter((p) => pluginName(p) !== spec);
|
|
536
|
+
if (next.length === plugins.length) {
|
|
537
|
+
return errorResult(`Plugin "${spec}" not in config.`);
|
|
538
|
+
}
|
|
539
|
+
existing.plugins = next;
|
|
540
|
+
await atomicWrite(deps.configPath, JSON.stringify(existing, null, 2), { mode: 384 });
|
|
541
|
+
return {
|
|
542
|
+
code: 0,
|
|
543
|
+
level: "info",
|
|
544
|
+
message: `Removed "${spec}" from config.`,
|
|
545
|
+
patch: { plugins: next },
|
|
546
|
+
restartRequired: true
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
function errorResult(message) {
|
|
550
|
+
return { code: 1, level: "error", message };
|
|
551
|
+
}
|
|
552
|
+
function isRecord(value) {
|
|
553
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
export {
|
|
557
|
+
PLUGIN_AUDIT_ENTRIES,
|
|
558
|
+
runPluginManagementCommand
|
|
559
|
+
};
|
|
560
|
+
//# sourceMappingURL=chunk-XWEGWYDU.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/plugin-management.ts"],
|
|
4
|
+
"sourcesContent": ["import * as fs from 'node:fs/promises';\nimport { atomicWrite } from '@wrongstack/core/utils';\nimport type { Config, PluginConfig, PluginManagerConfig } from '@wrongstack/core/types';\nimport { OFFICIAL_PLUGIN_AUDIT_ENTRIES } from '@wrongstack/plugins/audit';\n\nexport interface PluginAuditEntry {\n name: string;\n risk: 'low' | 'medium' | 'high';\n summary: string;\n defaultState: 'active' | 'inactive';\n canDisable: boolean;\n}\n\n/** Host-owned plugins that are not published by @wrongstack/plugins. */\nconst HOST_PLUGIN_AUDIT_ENTRIES: readonly PluginAuditEntry[] = [\n {\n name: 'wstack-prompts',\n risk: 'medium',\n summary: 'Prompt library and prompt authoring commands.',\n defaultState: 'active',\n canDisable: true,\n },\n {\n name: 'wstack-sync',\n risk: 'medium',\n summary: 'Cloud sync commands for prompts, skills, settings, memory, and history.',\n defaultState: 'active',\n canDisable: true,\n },\n {\n name: 'wstack-git',\n risk: 'high',\n summary: 'Git commands for commit, status checks, and push.',\n defaultState: 'active',\n canDisable: true,\n },\n {\n name: 'wstack-observability',\n risk: 'low',\n summary: 'Runtime metrics and health slash commands.',\n defaultState: 'active',\n canDisable: true,\n },\n {\n name: 'wstack-chimera',\n risk: 'medium',\n summary: 'Spawns a post-session code review subagent when explicitly enabled.',\n defaultState: 'inactive',\n canDisable: true,\n },\n {\n name: 'wstack-skills',\n risk: 'medium',\n summary: 'Skill library, authoring, install, update, and uninstall commands.',\n defaultState: 'active',\n canDisable: true,\n },\n {\n name: 'wstack-plan',\n risk: 'medium',\n summary: 'Strategic plan board slash command.',\n defaultState: 'active',\n canDisable: true,\n },\n {\n name: '@wrongstack/plug-lsp',\n risk: 'medium',\n summary: 'Language Server Protocol tools and slash commands.',\n defaultState: 'inactive',\n canDisable: true,\n },\n {\n name: 'telegram',\n risk: 'medium',\n summary: 'Telegram bridge for messages, approvals, and notifications.',\n defaultState: 'inactive',\n canDisable: true,\n },\n] as const;\n\nexport const PLUGIN_AUDIT_ENTRIES: readonly PluginAuditEntry[] = Object.freeze([\n ...HOST_PLUGIN_AUDIT_ENTRIES,\n ...OFFICIAL_PLUGIN_AUDIT_ENTRIES,\n]);\n\nexport const OFFICIAL_PLUGINS = [\n {\n alias: 'telegram',\n specifier: '@wrongstack/telegram',\n description: 'Telegram bridge for prompts, notifications, and slash commands.',\n },\n {\n alias: 'lsp',\n specifier: '@wrongstack/plug-lsp',\n description: 'Language Server Protocol tools for code intelligence.',\n },\n] as const;\n\nexport interface PluginManagementDeps {\n config: Config;\n configPath: string;\n}\n\nexport interface PluginManagementResult {\n code: number;\n level: 'output' | 'info' | 'error';\n message: string;\n patch?: {\n plugins?: (string | PluginConfig)[] | undefined;\n features?: Record<string, unknown>;\n pluginManager?: PluginManagerConfig | undefined;\n /**\n * Full replacement `extensions` map (patchConfig is a SHALLOW merge,\n * so per-plugin llm overrides must ship the whole merged object).\n */\n extensions?: Record<string, Record<string, unknown>> | undefined;\n };\n restartRequired?: boolean | undefined;\n}\n\nconst OFFICIAL_ALIASES = new Map<string, string>(\n OFFICIAL_PLUGINS.flatMap((p) => [\n [p.alias, p.specifier],\n [p.specifier, p.specifier],\n ]),\n);\n\nexport async function runPluginManagementCommand(\n args: string[],\n deps: PluginManagementDeps,\n): Promise<PluginManagementResult> {\n const sub = args[0];\n if (!sub || sub === 'list' || sub === 'status') {\n return {\n code: 0,\n level: 'output',\n message: renderConfiguredPlugins(deps.config),\n };\n }\n if (sub === 'official' || sub === 'officials') {\n return {\n code: 0,\n level: 'output',\n message: renderOfficialPlugins(deps.config),\n };\n }\n if (sub === 'report' || sub === 'audit' || sub === 'menu') {\n return {\n code: 0,\n level: 'output',\n message: renderPluginAuditReport(deps.config),\n };\n }\n if (sub === 'add' || sub === 'install') {\n const spec = args[1];\n if (!spec) {\n return errorResult('Usage: wstack plugin add <specifier|official-alias> [--disabled]');\n }\n return upsertPlugin(\n resolvePluginSpecifier(spec),\n { enabled: !args.includes('--disabled') },\n deps,\n 'Added',\n );\n }\n if (sub === 'remove' || sub === 'rm' || sub === 'uninstall') {\n const spec = args[1];\n if (!spec) {\n return errorResult('Usage: wstack plugin remove <specifier|official-alias>');\n }\n return removePlugin(resolvePluginSpecifier(spec), deps);\n }\n if (sub === 'enable' || sub === 'disable') {\n const spec = args[1];\n if (!spec) {\n return errorResult(`Usage: wstack plugin ${sub} <specifier|official-alias>`);\n }\n return upsertPlugin(\n resolvePluginSpecifier(spec),\n { enabled: sub === 'enable' },\n deps,\n sub === 'enable' ? 'Enabled' : 'Disabled',\n );\n }\n if (sub === 'toggle') {\n const spec = args[1];\n if (!spec) {\n return errorResult('Usage: wstack plugin toggle <plugin-name|official-alias>');\n }\n return togglePlugin(resolvePluginToggleSpecifier(spec), deps);\n }\n if (sub === 'manager') {\n return runPluginManagerPolicyCommand(args.slice(1), deps);\n }\n if (sub === 'llm') {\n return runPluginLlmCommand(args.slice(1), deps);\n }\n return errorResult(\n `Unknown plugin subcommand: ${sub}\\nUsage: wstack plugin [list|status|report|menu|official|add|install|remove|enable|disable|toggle|manager|llm]`,\n );\n}\n\nconst PLUGIN_MANAGER_POLICY_USAGE = [\n 'Usage:',\n ' wstack plugin manager List plugins locked against LLM state changes.',\n ' wstack plugin manager lock <plugin|*> Prevent plugin_manager from enabling/disabling it.',\n ' wstack plugin manager unlock <plugin|*> Restore plugin_manager enable/disable access.',\n '',\n 'This policy affects only the LLM-facing plugin_manager tool. Human /plugin and',\n 'wstack plugin enable/disable commands remain available.',\n].join('\\n');\n\nasync function runPluginManagerPolicyCommand(\n args: string[],\n deps: PluginManagementDeps,\n): Promise<PluginManagementResult> {\n const action = args[0] ?? 'list';\n if (action === 'list') {\n const locked = deps.config.pluginManager?.locked ?? [];\n return {\n code: 0,\n level: 'output',\n message:\n locked.length === 0\n ? 'LLM plugin-manager policy: no plugins are locked.'\n : `LLM plugin-manager policy \u2014 locked (${locked.length}):\\n${locked.map((name) => ` ${name}`).join('\\n')}`,\n };\n }\n\n if (action !== 'lock' && action !== 'unlock') {\n return errorResult(PLUGIN_MANAGER_POLICY_USAGE);\n }\n const rawName = args[1];\n if (!rawName) return errorResult(PLUGIN_MANAGER_POLICY_USAGE);\n const name = rawName === '*' ? '*' : resolvePluginToggleSpecifier(rawName);\n\n const existing = await readConfig(deps.configPath);\n const filePolicy = isRecord(existing.pluginManager) ? existing.pluginManager : undefined;\n const current = Array.isArray(filePolicy?.['locked'])\n ? filePolicy['locked'].filter((entry): entry is string => typeof entry === 'string')\n : [...(deps.config.pluginManager?.locked ?? [])];\n const canonical = canonicalPolicyName(name);\n const next =\n action === 'lock'\n ? current.some((entry) => canonicalPolicyName(entry) === canonical)\n ? current\n : [...current, name]\n : current.filter((entry) => canonicalPolicyName(entry) !== canonical);\n\n const pluginManager: PluginManagerConfig = { locked: next };\n existing.pluginManager = { ...(filePolicy ?? {}), ...pluginManager };\n await atomicWrite(deps.configPath, JSON.stringify(existing, null, 2), { mode: 0o600 });\n\n return {\n code: 0,\n level: 'info',\n message:\n action === 'lock'\n ? `Locked \"${name}\" against LLM enable/disable changes. Human plugin commands still work.`\n : `Unlocked \"${name}\" for LLM enable/disable changes.`,\n patch: { pluginManager },\n };\n}\n\nfunction canonicalPolicyName(name: string): string {\n if (name === '*') return name;\n return resolvePluginToggleSpecifier(name).trim().toLowerCase();\n}\n\nconst PLUGIN_LLM_USAGE = [\n 'Usage:',\n ' wstack plugin llm List every per-plugin LLM override.',\n \" wstack plugin llm <plugin> Show one plugin's LLM override.\",\n ' wstack plugin llm <plugin> <provider> [model] Route this plugin through a provider (and model).',\n ' wstack plugin llm <plugin> - <model> Keep the session provider, override only the model.',\n ' wstack plugin llm <plugin> --clear Remove the override (back to the session default).',\n '',\n 'The override is stored as config.extensions.<plugin>.llm and is used by',\n 'every api.llm call the plugin makes. Without an override, plugins follow',\n 'the active session provider/model (the chat leader).',\n].join('\\n');\n\n/**\n * Render every configured per-plugin LLM override. Reads\n * `config.extensions.<plugin>.llm` across all plugins so the user can\n * see, at a glance, which plugins deviate from the session default.\n */\nfunction renderPluginLlmOverviews(config: Config, sessionDefault: string): string {\n const rows: Array<{ name: string; provider: string; model: string }> = [];\n for (const [pluginName, ext] of Object.entries(config.extensions ?? {})) {\n const llm = (ext as Record<string, unknown>)?.['llm'];\n if (llm && typeof llm === 'object') {\n const o = llm as { provider?: string; model?: string };\n rows.push({\n name: pluginName,\n provider: o.provider ?? '(session)',\n model: o.model ?? '(session)',\n });\n }\n }\n const lines = [`Per-plugin LLM routing (session default: ${sessionDefault}):`];\n if (rows.length === 0) {\n lines.push(\n ' No plugin overrides \u2014 every plugin follows the session default.',\n ' Set one with: wstack plugin llm <plugin> <provider> [model]',\n );\n } else {\n rows.sort((a, b) => a.name.localeCompare(b.name));\n for (const r of rows) {\n lines.push(` ${r.name.padEnd(24)} provider=${r.provider.padEnd(16)} model=${r.model}`);\n }\n lines.push('', 'Clear one with: wstack plugin llm <plugin> --clear');\n }\n return lines.join('\\n');\n}\n\n/**\n * `wstack plugin llm \u2026` \u2014 per-plugin LLM routing. The chat leader's\n * provider/model stays the DEFAULT; this stores an override under\n * `config.extensions[<plugin>].llm = { provider?, model? }` which\n * `api.llm` resolves ahead of the session default on every call.\n */\nasync function runPluginLlmCommand(\n args: string[],\n deps: PluginManagementDeps,\n): Promise<PluginManagementResult> {\n const sessionDefault = `${deps.config.provider ?? '?'} / ${deps.config.model ?? '?'}`;\n\n // \u2500\u2500 List: `plugin llm` (no name) or `plugin llm list` \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (args.length === 0 || args[0] === 'list') {\n return {\n code: 0,\n level: 'output',\n message: renderPluginLlmOverviews(deps.config, sessionDefault),\n };\n }\n\n const name = args[0];\n if (!name || name.startsWith('-')) return errorResult(PLUGIN_LLM_USAGE);\n\n const currentOverride = deps.config.extensions?.[name]?.['llm'];\n\n // \u2500\u2500 Show \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (args.length === 1) {\n const lines = [`LLM routing for plugin \"${name}\":`];\n if (currentOverride && typeof currentOverride === 'object') {\n const o = currentOverride as { provider?: string; model?: string };\n lines.push(\n ` override: provider=${o.provider ?? '(session)'} model=${o.model ?? '(session)'}`,\n ` session default: ${sessionDefault}`,\n );\n } else {\n lines.push(\n ` no override \u2014 follows the session default (${sessionDefault}).`,\n ` Set one with: wstack plugin llm ${name} <provider> [model]`,\n );\n }\n return { code: 0, level: 'output', message: lines.join('\\n') };\n }\n\n const existing = await readConfig(deps.configPath);\n const fileExtensions = isRecord(existing.extensions)\n ? (existing.extensions as Record<string, unknown>)\n : {};\n const pluginExt = isRecord(fileExtensions[name])\n ? { ...(fileExtensions[name] as Record<string, unknown>) }\n : {};\n\n // \u2500\u2500 Clear \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (args[1] === '--clear' || args[1] === 'clear') {\n if (!('llm' in pluginExt) && !currentOverride) {\n return { code: 0, level: 'info', message: `Plugin \"${name}\" has no LLM override.` };\n }\n delete pluginExt['llm'];\n if (Object.keys(pluginExt).length === 0) delete fileExtensions[name];\n else fileExtensions[name] = pluginExt;\n existing.extensions = fileExtensions;\n await atomicWrite(deps.configPath, JSON.stringify(existing, null, 2), { mode: 0o600 });\n const merged = mergeExtensionsForPatch(deps.config, fileExtensions);\n // The in-memory config may still carry the old override \u2014 the merge\n // above unions both sources, so drop the key explicitly.\n const mergedEntry = merged[name];\n if (mergedEntry) {\n delete mergedEntry['llm'];\n if (Object.keys(mergedEntry).length === 0) delete merged[name];\n }\n return {\n code: 0,\n level: 'info',\n message:\n `Cleared LLM override for \"${name}\" \u2014 it now follows the session default (${sessionDefault}). ` +\n 'Takes effect immediately for api.llm calls.',\n patch: { extensions: merged },\n };\n }\n\n // \u2500\u2500 Set \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const providerArg = args[1];\n const modelArg = args[2];\n if (!providerArg || providerArg.startsWith('--')) return errorResult(PLUGIN_LLM_USAGE);\n const provider = providerArg === '-' ? undefined : providerArg;\n const model = modelArg && modelArg !== '-' ? modelArg : undefined;\n if (!provider && !model) return errorResult(PLUGIN_LLM_USAGE);\n\n const llm: Record<string, unknown> = {};\n if (provider) llm['provider'] = provider;\n if (model) llm['model'] = model;\n pluginExt['llm'] = llm;\n fileExtensions[name] = pluginExt;\n existing.extensions = fileExtensions;\n await atomicWrite(deps.configPath, JSON.stringify(existing, null, 2), { mode: 0o600 });\n\n // Soft sanity note: an unknown provider name still works if the\n // models.dev catalog knows it, but flag likely typos against the\n // user's configured providers.\n const configured = Object.keys(deps.config.providers ?? {});\n const note =\n provider && configured.length > 0 && !configured.includes(provider)\n ? `\\nNote: \"${provider}\" is not in config.providers (configured: ${configured.join(', ')}). ` +\n 'Catalog providers (anthropic, openai, \u2026) still resolve if credentials are available.'\n : '';\n\n const merged = mergeExtensionsForPatch(deps.config, fileExtensions);\n return {\n code: 0,\n level: 'info',\n message:\n `Plugin \"${name}\" now routes api.llm calls via ` +\n `provider=${provider ?? '(session)'} model=${model ?? '(session)'}. ` +\n `Session default stays ${sessionDefault}. Takes effect immediately for api.llm calls.${note}`,\n patch: { extensions: merged },\n };\n}\n\n/**\n * patchConfig is a shallow merge \u2014 build the FULL extensions map:\n * in-memory config first, then the file's (just-written) entries win.\n */\nfunction mergeExtensionsForPatch(\n config: Config,\n fileExtensions: Record<string, unknown>,\n): Record<string, Record<string, unknown>> {\n const merged: Record<string, Record<string, unknown>> = {};\n for (const [k, v] of Object.entries(config.extensions ?? {})) {\n merged[k] = { ...v };\n }\n for (const [k, v] of Object.entries(fileExtensions)) {\n if (isRecord(v)) merged[k] = { ...(merged[k] ?? {}), ...v };\n }\n // A cleared plugin entry must disappear from the merged view too.\n for (const k of Object.keys(merged)) {\n if (!(k in fileExtensions) && !(k in (config.extensions ?? {}))) delete merged[k];\n }\n return merged;\n}\n\nexport function resolvePluginSpecifier(input: string): string {\n return OFFICIAL_ALIASES.get(input.toLowerCase()) ?? input;\n}\n\nfunction resolvePluginToggleSpecifier(input: string): string {\n if (input.toLowerCase() === '@wrongstack/telegram') return 'telegram';\n if (auditEntryFor(input)) return input;\n return resolvePluginSpecifier(input);\n}\n\nexport function renderOfficialPlugins(config?: Config): string {\n return [\n 'Official plugins:',\n ...OFFICIAL_PLUGINS.map((p) => {\n const state = config ? officialPluginState(config, p.specifier) : '';\n const status = state ? `${state.padEnd(14)} ` : '';\n return ` ${p.alias.padEnd(12)} ${status}${p.specifier.padEnd(24)} ${p.description}`;\n }),\n '',\n 'Use `wstack plugin add <alias>` or `/plugin install <alias>`.',\n ].join('\\n');\n}\n\nexport function renderConfiguredPlugins(config: Config): string {\n const plugins = config.plugins ?? [];\n if (plugins.length === 0) {\n return [\n 'No plugins configured.',\n 'Use `wstack plugin add <specifier>` or `/plugin install <official-alias>`.',\n ].join('\\n');\n }\n return plugins\n .map((p) => {\n const name = pluginName(p);\n const enabled = typeof p === 'object' && p.enabled === false ? 'disabled' : 'enabled';\n const official = OFFICIAL_PLUGINS.find((entry) => entry.specifier === name);\n const suffix = official ? ` (${official.alias})` : '';\n return ` ${`${name}${suffix}`.padEnd(44)} ${enabled}`;\n })\n .join('\\n');\n}\n\nexport function renderPluginAuditReport(config: Config): string {\n const configured = config.plugins ?? [];\n const lines = [\n 'Plugin audit report:',\n ' State shows the effective boot state. Default-active plugins run unless disabled in config.',\n ' Built-in audit rows are toggleable unless a future row explicitly marks itself locked.',\n '',\n ' Built-in audit entries:',\n ];\n\n for (const entry of PLUGIN_AUDIT_ENTRIES) {\n const { state, source } = effectiveAuditState(config, entry);\n const policy = entry.canDisable ? 'toggleable' : lockedReason(entry);\n lines.push(\n ` ${entry.name.padEnd(24)} ${state.padEnd(8)} ${source.padEnd(8)} risk=${entry.risk.padEnd(6)} ${policy.padEnd(24)} ${entry.summary}`,\n );\n }\n\n const extra = configured.filter(\n (plugin) => !PLUGIN_AUDIT_ENTRIES.some((entry) => pluginMatchesToggleSpec(plugin, entry.name)),\n );\n if (extra.length > 0) {\n lines.push('', ' Configured plugins outside the audit list:');\n for (const plugin of extra) {\n const name = pluginName(plugin);\n const state = typeof plugin === 'object' && plugin.enabled === false ? 'disabled' : 'enabled';\n lines.push(\n ` ${name.padEnd(24)} ${state.padEnd(8)} config risk=custom user-configured plugin`,\n );\n }\n }\n\n lines.push(\n '',\n 'Use `/plugin menu` in the TUI, or `wstack plugin toggle <name>` for toggleable rows.',\n );\n return lines.join('\\n');\n}\n\nasync function readConfig(file: string): Promise<Record<string, unknown>> {\n try {\n return JSON.parse(await fs.readFile(file, 'utf8')) as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n\nfunction pluginName(p: string | PluginConfig): string {\n return typeof p === 'string' ? p : p.name;\n}\n\nfunction pluginEntry(spec: string, enabled: boolean): string | PluginConfig {\n return enabled ? spec : { name: spec, enabled: false };\n}\n\nfunction pluginMatchesToggleSpec(p: string | PluginConfig, spec: string): boolean {\n const name = pluginName(p);\n if (spec === 'telegram') return name === 'telegram' || name === '@wrongstack/telegram';\n return name === spec;\n}\n\nfunction effectiveAuditState(\n config: Config,\n entry: PluginAuditEntry,\n): { state: 'enabled' | 'disabled'; source: 'config' | 'default' } {\n const configured = (config.plugins ?? []).find((plugin) =>\n pluginMatchesToggleSpec(plugin, entry.name),\n );\n if (configured) {\n return {\n state:\n typeof configured === 'object' && configured.enabled === false ? 'disabled' : 'enabled',\n source: 'config',\n };\n }\n return {\n state: entry.defaultState === 'active' ? 'enabled' : 'disabled',\n source: 'default',\n };\n}\n\nfunction lockedReason(entry: PluginAuditEntry): string {\n if (entry.canDisable) return 'toggleable';\n if (entry.name === 'secret-scanner') {\n return 'locked: safety guard';\n }\n return 'locked: core surface';\n}\n\nfunction auditEntryFor(spec: string): PluginAuditEntry | undefined {\n return PLUGIN_AUDIT_ENTRIES.find((entry) => entry.name === spec);\n}\n\nfunction officialPluginState(\n config: Config,\n spec: string,\n): 'enabled' | 'disabled' | 'not configured' {\n const match = (config.plugins ?? []).find((p) => pluginName(p) === spec);\n if (!match) return 'not configured';\n return typeof match === 'object' && match.enabled === false ? 'disabled' : 'enabled';\n}\n\nasync function togglePlugin(\n spec: string,\n deps: PluginManagementDeps,\n): Promise<PluginManagementResult> {\n const auditEntry = auditEntryFor(spec);\n if (auditEntry?.canDisable === false) {\n return errorResult(`Plugin \"${spec}\" is locked and cannot be toggled from the plugin menu.`);\n }\n\n const existing = await readConfig(deps.configPath);\n const plugins = Array.isArray(existing.plugins)\n ? (existing.plugins as Array<string | PluginConfig>)\n : [];\n const idx = plugins.findIndex((p) => pluginMatchesToggleSpec(p, spec));\n const configured = idx >= 0 ? plugins[idx] : undefined;\n const enabled = configured\n ? !(typeof configured === 'object' && configured.enabled === false)\n : auditEntry?.defaultState === 'active';\n\n if (!configured && !auditEntry) {\n return errorResult(\n `Plugin \"${spec}\" is not configured. Use \"wstack plugin add ${spec}\" first.`,\n );\n }\n\n let nextPlugins: Array<string | PluginConfig>;\n let nextEnabled: boolean;\n if (enabled) {\n nextEnabled = false;\n nextPlugins = plugins.filter((p) => !pluginMatchesToggleSpec(p, spec));\n if (auditEntry?.defaultState !== 'inactive') {\n nextPlugins.push({ name: spec, enabled: false });\n }\n } else {\n nextEnabled = true;\n if (auditEntry?.defaultState === 'active') {\n nextPlugins = plugins.filter((p) => !pluginMatchesToggleSpec(p, spec));\n } else {\n nextPlugins = plugins.filter((p) => !pluginMatchesToggleSpec(p, spec));\n nextPlugins.push(spec);\n }\n }\n\n const features = {\n ...(isRecord(deps.config.features) ? deps.config.features : {}),\n ...(isRecord(existing.features) ? existing.features : {}),\n plugins: true,\n };\n existing.plugins = nextPlugins;\n existing.features = features;\n await atomicWrite(deps.configPath, JSON.stringify(existing, null, 2), { mode: 0o600 });\n const restartRequired = spec === 'branch-guard' && !nextEnabled ? undefined : true;\n return {\n code: 0,\n level: 'info',\n message:\n `${nextEnabled ? 'Enabled' : 'Disabled'} \"${spec}\". Config written to ${deps.configPath}.` +\n (spec === 'branch-guard' && !nextEnabled\n ? ' The running branch-guard hook will disable itself on config update.'\n : ''),\n patch: { plugins: nextPlugins, features },\n restartRequired,\n };\n}\n\nasync function upsertPlugin(\n spec: string,\n opts: { enabled: boolean },\n deps: PluginManagementDeps,\n verb: string,\n): Promise<PluginManagementResult> {\n const existing = await readConfig(deps.configPath);\n const plugins = Array.isArray(existing.plugins)\n ? (existing.plugins as Array<string | PluginConfig>)\n : [];\n const idx = plugins.findIndex((p) => pluginName(p) === spec);\n const nextEntry = pluginEntry(spec, opts.enabled);\n if (idx >= 0) plugins[idx] = nextEntry;\n else plugins.push(nextEntry);\n const features = {\n ...(isRecord(deps.config.features) ? deps.config.features : {}),\n ...(isRecord(existing.features) ? existing.features : {}),\n plugins: true,\n };\n existing.plugins = plugins;\n existing.features = features;\n await atomicWrite(deps.configPath, JSON.stringify(existing, null, 2), { mode: 0o600 });\n const restartRequired = spec === 'branch-guard' && !opts.enabled ? undefined : true;\n return {\n code: 0,\n level: 'info',\n message:\n `${verb} \"${spec}\" (${opts.enabled ? 'enabled' : 'disabled'}). Config written to ${deps.configPath}.` +\n (spec === 'branch-guard' && !opts.enabled\n ? ' The running branch-guard hook will disable itself on config update.'\n : ''),\n patch: { plugins, features },\n restartRequired,\n };\n}\n\nasync function removePlugin(\n spec: string,\n deps: PluginManagementDeps,\n): Promise<PluginManagementResult> {\n const existing = await readConfig(deps.configPath);\n const plugins = Array.isArray(existing.plugins)\n ? (existing.plugins as Array<string | PluginConfig>)\n : [];\n const next = plugins.filter((p) => pluginName(p) !== spec);\n if (next.length === plugins.length) {\n return errorResult(`Plugin \"${spec}\" not in config.`);\n }\n existing.plugins = next;\n await atomicWrite(deps.configPath, JSON.stringify(existing, null, 2), { mode: 0o600 });\n return {\n code: 0,\n level: 'info',\n message: `Removed \"${spec}\" from config.`,\n patch: { plugins: next },\n restartRequired: true,\n };\n}\n\nfunction errorResult(message: string): PluginManagementResult {\n return { code: 1, level: 'error', message };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["name", "pluginName", "merged"]
|
|
7
|
+
}
|