@jonit-dev/night-watch-cli 1.7.29 → 1.7.31
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/bin/night-watch.mjs +1 -1
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/{src/cli.js → cli.js} +1 -0
- package/dist/cli.js.map +1 -0
- package/dist/{src/commands → commands}/audit.d.ts +2 -2
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +105 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/{src/commands → commands}/board.d.ts +1 -1
- package/dist/commands/board.d.ts.map +1 -0
- package/dist/commands/board.js +664 -0
- package/dist/commands/board.js.map +1 -0
- package/dist/{src/commands → commands}/cancel.d.ts +3 -3
- package/dist/commands/cancel.d.ts.map +1 -0
- package/dist/{src/commands → commands}/cancel.js +18 -20
- package/dist/commands/cancel.js.map +1 -0
- package/dist/commands/dashboard/tab-actions.d.ts.map +1 -0
- package/dist/commands/dashboard/tab-actions.js.map +1 -0
- package/dist/{src/commands → commands}/dashboard/tab-config.d.ts +3 -3
- package/dist/commands/dashboard/tab-config.d.ts.map +1 -0
- package/dist/{src/commands → commands}/dashboard/tab-config.js +250 -187
- package/dist/commands/dashboard/tab-config.js.map +1 -0
- package/dist/{src/commands → commands}/dashboard/tab-logs.d.ts +1 -1
- package/dist/commands/dashboard/tab-logs.d.ts.map +1 -0
- package/dist/{src/commands → commands}/dashboard/tab-logs.js +62 -38
- package/dist/commands/dashboard/tab-logs.js.map +1 -0
- package/dist/{src/commands → commands}/dashboard/tab-schedules.d.ts +1 -1
- package/dist/commands/dashboard/tab-schedules.d.ts.map +1 -0
- package/dist/{src/commands → commands}/dashboard/tab-schedules.js +85 -76
- package/dist/commands/dashboard/tab-schedules.js.map +1 -0
- package/dist/{src/commands → commands}/dashboard/tab-status.d.ts +7 -7
- package/dist/commands/dashboard/tab-status.d.ts.map +1 -0
- package/dist/{src/commands → commands}/dashboard/tab-status.js +98 -95
- package/dist/commands/dashboard/tab-status.js.map +1 -0
- package/dist/{src/commands → commands}/dashboard/types.d.ts +3 -4
- package/dist/commands/dashboard/types.d.ts.map +1 -0
- package/dist/commands/dashboard/types.js.map +1 -0
- package/dist/{src/commands → commands}/dashboard.d.ts +2 -2
- package/dist/commands/dashboard.d.ts.map +1 -0
- package/dist/{src/commands → commands}/dashboard.js +32 -33
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/{src/commands → commands}/doctor.d.ts +2 -2
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/{src/commands → commands}/doctor.js +40 -43
- package/dist/commands/doctor.js.map +1 -0
- package/dist/{src/commands → commands}/history.d.ts +1 -1
- package/dist/commands/history.d.ts.map +1 -0
- package/dist/{src/commands → commands}/history.js +11 -18
- package/dist/commands/history.js.map +1 -0
- package/dist/{src/commands → commands}/init.d.ts +1 -1
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/{src/commands → commands}/init.js +62 -36
- package/dist/commands/init.js.map +1 -0
- package/dist/{src/commands → commands}/install.d.ts +2 -2
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/{src/commands → commands}/install.js +48 -50
- package/dist/commands/install.js.map +1 -0
- package/dist/{src/commands → commands}/logs.d.ts +1 -1
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/{src/commands → commands}/logs.js +29 -30
- package/dist/commands/logs.js.map +1 -0
- package/dist/{src/commands → commands}/prd-state.d.ts +1 -1
- package/dist/commands/prd-state.d.ts.map +1 -0
- package/dist/{src/commands → commands}/prd-state.js +14 -14
- package/dist/commands/prd-state.js.map +1 -0
- package/dist/{src/commands → commands}/prd.d.ts +1 -1
- package/dist/commands/prd.d.ts.map +1 -0
- package/dist/{src/commands → commands}/prd.js +57 -66
- package/dist/commands/prd.js.map +1 -0
- package/dist/{src/commands → commands}/prds.d.ts +1 -1
- package/dist/commands/prds.d.ts.map +1 -0
- package/dist/{src/commands → commands}/prds.js +51 -53
- package/dist/commands/prds.js.map +1 -0
- package/dist/{src/commands → commands}/prs.d.ts +1 -1
- package/dist/commands/prs.d.ts.map +1 -0
- package/dist/{src/commands → commands}/prs.js +22 -24
- package/dist/commands/prs.js.map +1 -0
- package/dist/{src/commands → commands}/qa.d.ts +2 -2
- package/dist/commands/qa.d.ts.map +1 -0
- package/dist/{src/commands → commands}/qa.js +50 -51
- package/dist/commands/qa.js.map +1 -0
- package/dist/{src/commands → commands}/retry.d.ts +1 -1
- package/dist/commands/retry.d.ts.map +1 -0
- package/dist/{src/commands → commands}/retry.js +9 -10
- package/dist/commands/retry.js.map +1 -0
- package/dist/{src/commands → commands}/review.d.ts +2 -2
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/{src/commands → commands}/review.js +68 -59
- package/dist/commands/review.js.map +1 -0
- package/dist/{src/commands → commands}/run.d.ts +2 -2
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/{src/commands → commands}/run.js +87 -83
- package/dist/commands/run.js.map +1 -0
- package/dist/{src/commands → commands}/serve.d.ts +2 -2
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/{src/commands → commands}/serve.js +18 -18
- package/dist/commands/serve.js.map +1 -0
- package/dist/{src/commands → commands}/slice.d.ts +2 -2
- package/dist/commands/slice.d.ts.map +1 -0
- package/dist/{src/commands → commands}/slice.js +50 -46
- package/dist/commands/slice.js.map +1 -0
- package/dist/{src/commands → commands}/state.d.ts +1 -1
- package/dist/commands/state.d.ts.map +1 -0
- package/dist/{src/commands → commands}/state.js +20 -22
- package/dist/commands/state.js.map +1 -0
- package/dist/{src/commands → commands}/status.d.ts +1 -1
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/{src/commands → commands}/status.js +75 -54
- package/dist/commands/status.js.map +1 -0
- package/dist/{src/commands → commands}/uninstall.d.ts +1 -1
- package/dist/commands/uninstall.d.ts.map +1 -0
- package/dist/{src/commands → commands}/uninstall.js +12 -14
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/{src/commands → commands}/update.d.ts +1 -1
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/{src/commands → commands}/update.js +23 -23
- package/dist/commands/update.js.map +1 -0
- package/package.json +18 -42
- package/LICENSE +0 -21
- package/README.md +0 -132
- package/dist/shared/types.d.ts +0 -226
- package/dist/shared/types.d.ts.map +0 -1
- package/dist/shared/types.js +0 -7
- package/dist/shared/types.js.map +0 -1
- package/dist/src/agents/soul-compiler.d.ts +0 -11
- package/dist/src/agents/soul-compiler.d.ts.map +0 -1
- package/dist/src/agents/soul-compiler.js +0 -157
- package/dist/src/agents/soul-compiler.js.map +0 -1
- package/dist/src/board/factory.d.ts +0 -3
- package/dist/src/board/factory.d.ts.map +0 -1
- package/dist/src/board/factory.js +0 -10
- package/dist/src/board/factory.js.map +0 -1
- package/dist/src/board/providers/github-graphql.d.ts +0 -16
- package/dist/src/board/providers/github-graphql.d.ts.map +0 -1
- package/dist/src/board/providers/github-graphql.js +0 -43
- package/dist/src/board/providers/github-graphql.js.map +0 -1
- package/dist/src/board/providers/github-projects.d.ts +0 -51
- package/dist/src/board/providers/github-projects.d.ts.map +0 -1
- package/dist/src/board/providers/github-projects.js +0 -672
- package/dist/src/board/providers/github-projects.js.map +0 -1
- package/dist/src/board/types.d.ts +0 -60
- package/dist/src/board/types.d.ts.map +0 -1
- package/dist/src/board/types.js +0 -4
- package/dist/src/board/types.js.map +0 -1
- package/dist/src/cli.d.ts +0 -3
- package/dist/src/cli.d.ts.map +0 -1
- package/dist/src/cli.js.map +0 -1
- package/dist/src/commands/audit.d.ts.map +0 -1
- package/dist/src/commands/audit.js +0 -98
- package/dist/src/commands/audit.js.map +0 -1
- package/dist/src/commands/board.d.ts.map +0 -1
- package/dist/src/commands/board.js +0 -294
- package/dist/src/commands/board.js.map +0 -1
- package/dist/src/commands/cancel.d.ts.map +0 -1
- package/dist/src/commands/cancel.js.map +0 -1
- package/dist/src/commands/dashboard/tab-actions.d.ts.map +0 -1
- package/dist/src/commands/dashboard/tab-actions.js.map +0 -1
- package/dist/src/commands/dashboard/tab-config.d.ts.map +0 -1
- package/dist/src/commands/dashboard/tab-config.js.map +0 -1
- package/dist/src/commands/dashboard/tab-logs.d.ts.map +0 -1
- package/dist/src/commands/dashboard/tab-logs.js.map +0 -1
- package/dist/src/commands/dashboard/tab-schedules.d.ts.map +0 -1
- package/dist/src/commands/dashboard/tab-schedules.js.map +0 -1
- package/dist/src/commands/dashboard/tab-status.d.ts.map +0 -1
- package/dist/src/commands/dashboard/tab-status.js.map +0 -1
- package/dist/src/commands/dashboard/types.d.ts.map +0 -1
- package/dist/src/commands/dashboard/types.js.map +0 -1
- package/dist/src/commands/dashboard.d.ts.map +0 -1
- package/dist/src/commands/dashboard.js.map +0 -1
- package/dist/src/commands/doctor.d.ts.map +0 -1
- package/dist/src/commands/doctor.js.map +0 -1
- package/dist/src/commands/history.d.ts.map +0 -1
- package/dist/src/commands/history.js.map +0 -1
- package/dist/src/commands/init.d.ts.map +0 -1
- package/dist/src/commands/init.js.map +0 -1
- package/dist/src/commands/install.d.ts.map +0 -1
- package/dist/src/commands/install.js.map +0 -1
- package/dist/src/commands/logs.d.ts.map +0 -1
- package/dist/src/commands/logs.js.map +0 -1
- package/dist/src/commands/prd-state.d.ts.map +0 -1
- package/dist/src/commands/prd-state.js.map +0 -1
- package/dist/src/commands/prd.d.ts.map +0 -1
- package/dist/src/commands/prd.js.map +0 -1
- package/dist/src/commands/prds.d.ts.map +0 -1
- package/dist/src/commands/prds.js.map +0 -1
- package/dist/src/commands/prs.d.ts.map +0 -1
- package/dist/src/commands/prs.js.map +0 -1
- package/dist/src/commands/qa.d.ts.map +0 -1
- package/dist/src/commands/qa.js.map +0 -1
- package/dist/src/commands/retry.d.ts.map +0 -1
- package/dist/src/commands/retry.js.map +0 -1
- package/dist/src/commands/review.d.ts.map +0 -1
- package/dist/src/commands/review.js.map +0 -1
- package/dist/src/commands/run.d.ts.map +0 -1
- package/dist/src/commands/run.js.map +0 -1
- package/dist/src/commands/serve.d.ts.map +0 -1
- package/dist/src/commands/serve.js.map +0 -1
- package/dist/src/commands/slice.d.ts.map +0 -1
- package/dist/src/commands/slice.js.map +0 -1
- package/dist/src/commands/state.d.ts.map +0 -1
- package/dist/src/commands/state.js.map +0 -1
- package/dist/src/commands/status.d.ts.map +0 -1
- package/dist/src/commands/status.js.map +0 -1
- package/dist/src/commands/uninstall.d.ts.map +0 -1
- package/dist/src/commands/uninstall.js.map +0 -1
- package/dist/src/commands/update.d.ts.map +0 -1
- package/dist/src/commands/update.js.map +0 -1
- package/dist/src/config.d.ts +0 -23
- package/dist/src/config.d.ts.map +0 -1
- package/dist/src/config.js +0 -671
- package/dist/src/config.js.map +0 -1
- package/dist/src/constants.d.ts +0 -67
- package/dist/src/constants.d.ts.map +0 -1
- package/dist/src/constants.js +0 -131
- package/dist/src/constants.js.map +0 -1
- package/dist/src/server/index.d.ts +0 -23
- package/dist/src/server/index.d.ts.map +0 -1
- package/dist/src/server/index.js +0 -1704
- package/dist/src/server/index.js.map +0 -1
- package/dist/src/slack/channel-manager.d.ts +0 -32
- package/dist/src/slack/channel-manager.d.ts.map +0 -1
- package/dist/src/slack/channel-manager.js +0 -128
- package/dist/src/slack/channel-manager.js.map +0 -1
- package/dist/src/slack/client.d.ts +0 -76
- package/dist/src/slack/client.d.ts.map +0 -1
- package/dist/src/slack/client.js +0 -193
- package/dist/src/slack/client.js.map +0 -1
- package/dist/src/slack/deliberation.d.ts +0 -87
- package/dist/src/slack/deliberation.d.ts.map +0 -1
- package/dist/src/slack/deliberation.js +0 -1354
- package/dist/src/slack/deliberation.js.map +0 -1
- package/dist/src/slack/index.d.ts +0 -6
- package/dist/src/slack/index.d.ts.map +0 -1
- package/dist/src/slack/index.js +0 -5
- package/dist/src/slack/index.js.map +0 -1
- package/dist/src/slack/interaction-listener.d.ts +0 -130
- package/dist/src/slack/interaction-listener.d.ts.map +0 -1
- package/dist/src/slack/interaction-listener.js +0 -1329
- package/dist/src/slack/interaction-listener.js.map +0 -1
- package/dist/src/storage/json-state-migrator.d.ts +0 -24
- package/dist/src/storage/json-state-migrator.d.ts.map +0 -1
- package/dist/src/storage/json-state-migrator.js +0 -197
- package/dist/src/storage/json-state-migrator.js.map +0 -1
- package/dist/src/storage/repositories/index.d.ts +0 -25
- package/dist/src/storage/repositories/index.d.ts.map +0 -1
- package/dist/src/storage/repositories/index.js +0 -45
- package/dist/src/storage/repositories/index.js.map +0 -1
- package/dist/src/storage/repositories/interfaces.d.ts +0 -60
- package/dist/src/storage/repositories/interfaces.d.ts.map +0 -1
- package/dist/src/storage/repositories/interfaces.js +0 -6
- package/dist/src/storage/repositories/interfaces.js.map +0 -1
- package/dist/src/storage/repositories/sqlite/agent-persona-repository.d.ts +0 -33
- package/dist/src/storage/repositories/sqlite/agent-persona-repository.d.ts.map +0 -1
- package/dist/src/storage/repositories/sqlite/agent-persona-repository.js +0 -715
- package/dist/src/storage/repositories/sqlite/agent-persona-repository.js.map +0 -1
- package/dist/src/storage/repositories/sqlite/execution-history-repository.d.ts +0 -21
- package/dist/src/storage/repositories/sqlite/execution-history-repository.d.ts.map +0 -1
- package/dist/src/storage/repositories/sqlite/execution-history-repository.js +0 -94
- package/dist/src/storage/repositories/sqlite/execution-history-repository.js.map +0 -1
- package/dist/src/storage/repositories/sqlite/prd-state-repository.d.ts +0 -17
- package/dist/src/storage/repositories/sqlite/prd-state-repository.d.ts.map +0 -1
- package/dist/src/storage/repositories/sqlite/prd-state-repository.js +0 -74
- package/dist/src/storage/repositories/sqlite/prd-state-repository.js.map +0 -1
- package/dist/src/storage/repositories/sqlite/project-registry-repository.d.ts +0 -17
- package/dist/src/storage/repositories/sqlite/project-registry-repository.d.ts.map +0 -1
- package/dist/src/storage/repositories/sqlite/project-registry-repository.js +0 -43
- package/dist/src/storage/repositories/sqlite/project-registry-repository.js.map +0 -1
- package/dist/src/storage/repositories/sqlite/roadmap-state-repository.d.ts +0 -14
- package/dist/src/storage/repositories/sqlite/roadmap-state-repository.d.ts.map +0 -1
- package/dist/src/storage/repositories/sqlite/roadmap-state-repository.js +0 -47
- package/dist/src/storage/repositories/sqlite/roadmap-state-repository.js.map +0 -1
- package/dist/src/storage/repositories/sqlite/slack-discussion-repository.d.ts +0 -20
- package/dist/src/storage/repositories/sqlite/slack-discussion-repository.d.ts.map +0 -1
- package/dist/src/storage/repositories/sqlite/slack-discussion-repository.js +0 -88
- package/dist/src/storage/repositories/sqlite/slack-discussion-repository.js.map +0 -1
- package/dist/src/storage/sqlite/client.d.ts +0 -23
- package/dist/src/storage/sqlite/client.d.ts.map +0 -1
- package/dist/src/storage/sqlite/client.js +0 -47
- package/dist/src/storage/sqlite/client.js.map +0 -1
- package/dist/src/storage/sqlite/migrations.d.ts +0 -11
- package/dist/src/storage/sqlite/migrations.d.ts.map +0 -1
- package/dist/src/storage/sqlite/migrations.js +0 -94
- package/dist/src/storage/sqlite/migrations.js.map +0 -1
- package/dist/src/templates/prd-template.d.ts +0 -11
- package/dist/src/templates/prd-template.d.ts.map +0 -1
- package/dist/src/templates/prd-template.js +0 -166
- package/dist/src/templates/prd-template.js.map +0 -1
- package/dist/src/templates/slicer-prompt.d.ts +0 -54
- package/dist/src/templates/slicer-prompt.d.ts.map +0 -1
- package/dist/src/templates/slicer-prompt.js +0 -163
- package/dist/src/templates/slicer-prompt.js.map +0 -1
- package/dist/src/types.d.ts +0 -140
- package/dist/src/types.d.ts.map +0 -1
- package/dist/src/types.js +0 -5
- package/dist/src/types.js.map +0 -1
- package/dist/src/utils/avatar-generator.d.ts +0 -6
- package/dist/src/utils/avatar-generator.d.ts.map +0 -1
- package/dist/src/utils/avatar-generator.js +0 -133
- package/dist/src/utils/avatar-generator.js.map +0 -1
- package/dist/src/utils/checks.d.ts +0 -55
- package/dist/src/utils/checks.d.ts.map +0 -1
- package/dist/src/utils/checks.js +0 -246
- package/dist/src/utils/checks.js.map +0 -1
- package/dist/src/utils/config-writer.d.ts +0 -16
- package/dist/src/utils/config-writer.d.ts.map +0 -1
- package/dist/src/utils/config-writer.js +0 -45
- package/dist/src/utils/config-writer.js.map +0 -1
- package/dist/src/utils/crontab.d.ts +0 -62
- package/dist/src/utils/crontab.d.ts.map +0 -1
- package/dist/src/utils/crontab.js +0 -168
- package/dist/src/utils/crontab.js.map +0 -1
- package/dist/src/utils/execution-history.d.ts +0 -54
- package/dist/src/utils/execution-history.d.ts.map +0 -1
- package/dist/src/utils/execution-history.js +0 -80
- package/dist/src/utils/execution-history.js.map +0 -1
- package/dist/src/utils/github.d.ts +0 -40
- package/dist/src/utils/github.d.ts.map +0 -1
- package/dist/src/utils/github.js +0 -126
- package/dist/src/utils/github.js.map +0 -1
- package/dist/src/utils/notify.d.ts +0 -64
- package/dist/src/utils/notify.d.ts.map +0 -1
- package/dist/src/utils/notify.js +0 -405
- package/dist/src/utils/notify.js.map +0 -1
- package/dist/src/utils/prd-states.d.ts +0 -16
- package/dist/src/utils/prd-states.d.ts.map +0 -1
- package/dist/src/utils/prd-states.js +0 -28
- package/dist/src/utils/prd-states.js.map +0 -1
- package/dist/src/utils/registry.d.ts +0 -45
- package/dist/src/utils/registry.d.ts.map +0 -1
- package/dist/src/utils/registry.js +0 -86
- package/dist/src/utils/registry.js.map +0 -1
- package/dist/src/utils/roadmap-parser.d.ts +0 -45
- package/dist/src/utils/roadmap-parser.d.ts.map +0 -1
- package/dist/src/utils/roadmap-parser.js +0 -136
- package/dist/src/utils/roadmap-parser.js.map +0 -1
- package/dist/src/utils/roadmap-scanner.d.ts +0 -92
- package/dist/src/utils/roadmap-scanner.d.ts.map +0 -1
- package/dist/src/utils/roadmap-scanner.js +0 -349
- package/dist/src/utils/roadmap-scanner.js.map +0 -1
- package/dist/src/utils/roadmap-state.d.ts +0 -90
- package/dist/src/utils/roadmap-state.d.ts.map +0 -1
- package/dist/src/utils/roadmap-state.js +0 -154
- package/dist/src/utils/roadmap-state.js.map +0 -1
- package/dist/src/utils/script-result.d.ts +0 -12
- package/dist/src/utils/script-result.d.ts.map +0 -1
- package/dist/src/utils/script-result.js +0 -46
- package/dist/src/utils/script-result.js.map +0 -1
- package/dist/src/utils/shell.d.ts +0 -27
- package/dist/src/utils/shell.d.ts.map +0 -1
- package/dist/src/utils/shell.js +0 -64
- package/dist/src/utils/shell.js.map +0 -1
- package/dist/src/utils/status-data.d.ts +0 -148
- package/dist/src/utils/status-data.d.ts.map +0 -1
- package/dist/src/utils/status-data.js +0 -548
- package/dist/src/utils/status-data.js.map +0 -1
- package/dist/src/utils/ui.d.ts +0 -55
- package/dist/src/utils/ui.d.ts.map +0 -1
- package/dist/src/utils/ui.js +0 -121
- package/dist/src/utils/ui.js.map +0 -1
- package/scripts/night-watch-audit-cron.sh +0 -149
- package/scripts/night-watch-cron.sh +0 -484
- package/scripts/night-watch-helpers.sh +0 -499
- package/scripts/night-watch-pr-reviewer-cron.sh +0 -528
- package/scripts/night-watch-qa-cron.sh +0 -281
- package/scripts/night-watch-slicer-cron.sh +0 -90
- package/scripts/test-helpers.bats +0 -77
- package/templates/night-watch-pr-reviewer.md +0 -174
- package/templates/night-watch-qa.md +0 -157
- package/templates/night-watch-slicer.md +0 -219
- package/templates/night-watch.config.json +0 -30
- package/templates/night-watch.md +0 -94
- package/templates/prd-executor.md +0 -235
- package/templates/prd.md +0 -26
- package/web/dist/assets/index-BiJf9LFT.js +0 -458
- package/web/dist/assets/index-OpSgvsYu.css +0 -1
- package/web/dist/avatars/carlos.webp +0 -0
- package/web/dist/avatars/dev.webp +0 -0
- package/web/dist/avatars/maya.webp +0 -0
- package/web/dist/avatars/priya.webp +0 -0
- package/web/dist/index.html +0 -82
- /package/dist/{src/commands → commands}/dashboard/tab-actions.d.ts +0 -0
- /package/dist/{src/commands → commands}/dashboard/tab-actions.js +0 -0
- /package/dist/{src/commands → commands}/dashboard/types.js +0 -0
|
@@ -2,79 +2,98 @@
|
|
|
2
2
|
* Config tab for the dashboard TUI
|
|
3
3
|
* Allows viewing and editing all configuration fields
|
|
4
4
|
*/
|
|
5
|
-
import blessed from
|
|
6
|
-
import { VALID_PROVIDERS } from
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { performInstall } from "../install.js";
|
|
5
|
+
import blessed from 'blessed';
|
|
6
|
+
import { VALID_PROVIDERS, saveConfig, } from '@night-watch/core';
|
|
7
|
+
import { performUninstall } from '../uninstall.js';
|
|
8
|
+
import { performInstall } from '../install.js';
|
|
10
9
|
const SENSITIVE_PATTERNS = /TOKEN|KEY|SECRET|PASSWORD/i;
|
|
11
|
-
const WEBHOOK_TYPES = [
|
|
10
|
+
const WEBHOOK_TYPES = ['slack', 'discord', 'telegram'];
|
|
12
11
|
const NOTIFICATION_EVENTS = [
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
'run_started',
|
|
13
|
+
'run_succeeded',
|
|
14
|
+
'run_failed',
|
|
15
|
+
'run_timeout',
|
|
16
|
+
'review_completed',
|
|
17
|
+
'pr_auto_merged',
|
|
18
|
+
'rate_limit_fallback',
|
|
19
|
+
'qa_completed',
|
|
21
20
|
];
|
|
22
21
|
/**
|
|
23
22
|
* GLM-5 default provider environment configuration
|
|
24
23
|
*/
|
|
25
24
|
const GLM5_DEFAULTS = {
|
|
26
|
-
ANTHROPIC_BASE_URL:
|
|
27
|
-
API_TIMEOUT_MS:
|
|
28
|
-
ANTHROPIC_DEFAULT_OPUS_MODEL:
|
|
29
|
-
ANTHROPIC_DEFAULT_SONNET_MODEL:
|
|
25
|
+
ANTHROPIC_BASE_URL: 'https://api.z.ai/api/anthropic',
|
|
26
|
+
API_TIMEOUT_MS: '3000000',
|
|
27
|
+
ANTHROPIC_DEFAULT_OPUS_MODEL: 'glm-5',
|
|
28
|
+
ANTHROPIC_DEFAULT_SONNET_MODEL: 'glm-5',
|
|
30
29
|
};
|
|
31
30
|
export const CONFIG_FIELDS = [
|
|
32
|
-
{ key:
|
|
33
|
-
{ key:
|
|
34
|
-
{ key:
|
|
35
|
-
{ key:
|
|
36
|
-
{ key:
|
|
37
|
-
{ key:
|
|
38
|
-
{ key:
|
|
39
|
-
{ key:
|
|
31
|
+
{ key: 'provider', label: 'Provider', type: 'enum', options: [...VALID_PROVIDERS] },
|
|
32
|
+
{ key: 'reviewerEnabled', label: 'Reviewer Enabled', type: 'boolean' },
|
|
33
|
+
{ key: 'defaultBranch', label: 'Default Branch', type: 'string' },
|
|
34
|
+
{ key: 'prdDir', label: 'PRD Directory', type: 'string' },
|
|
35
|
+
{ key: 'branchPrefix', label: 'Branch Prefix', type: 'string' },
|
|
36
|
+
{ key: 'branchPatterns', label: 'Branch Patterns', type: 'string[]' },
|
|
37
|
+
{ key: 'cronSchedule', label: 'Executor Schedule', type: 'string' },
|
|
38
|
+
{ key: 'reviewerSchedule', label: 'Reviewer Schedule', type: 'string' },
|
|
40
39
|
{
|
|
41
|
-
key:
|
|
42
|
-
|
|
40
|
+
key: 'maxRuntime',
|
|
41
|
+
label: 'Max Runtime (s)',
|
|
42
|
+
type: 'number',
|
|
43
|
+
validate: (v) => {
|
|
44
|
+
const n = parseInt(v, 10);
|
|
45
|
+
return isNaN(n) || n <= 0 ? 'Must be a positive integer' : null;
|
|
46
|
+
},
|
|
43
47
|
},
|
|
44
48
|
{
|
|
45
|
-
key:
|
|
46
|
-
|
|
49
|
+
key: 'reviewerMaxRuntime',
|
|
50
|
+
label: 'Reviewer Max Runtime (s)',
|
|
51
|
+
type: 'number',
|
|
52
|
+
validate: (v) => {
|
|
53
|
+
const n = parseInt(v, 10);
|
|
54
|
+
return isNaN(n) || n <= 0 ? 'Must be a positive integer' : null;
|
|
55
|
+
},
|
|
47
56
|
},
|
|
48
57
|
{
|
|
49
|
-
key:
|
|
50
|
-
|
|
58
|
+
key: 'minReviewScore',
|
|
59
|
+
label: 'Min Review Score',
|
|
60
|
+
type: 'number',
|
|
61
|
+
validate: (v) => {
|
|
62
|
+
const n = parseInt(v, 10);
|
|
63
|
+
return isNaN(n) || n < 0 || n > 100 ? 'Must be 0-100' : null;
|
|
64
|
+
},
|
|
51
65
|
},
|
|
52
66
|
{
|
|
53
|
-
key:
|
|
54
|
-
|
|
67
|
+
key: 'maxLogSize',
|
|
68
|
+
label: 'Max Log Size (bytes)',
|
|
69
|
+
type: 'number',
|
|
70
|
+
validate: (v) => {
|
|
71
|
+
const n = parseInt(v, 10);
|
|
72
|
+
return isNaN(n) || n <= 0 ? 'Must be a positive integer' : null;
|
|
73
|
+
},
|
|
55
74
|
},
|
|
56
|
-
{ key:
|
|
57
|
-
{ key:
|
|
75
|
+
{ key: 'providerEnv', label: 'Provider Env Vars', type: 'keyvalue' },
|
|
76
|
+
{ key: 'notifications', label: 'Notifications', type: 'webhooks' },
|
|
58
77
|
];
|
|
59
78
|
function maskValue(key, value) {
|
|
60
79
|
if (SENSITIVE_PATTERNS.test(key) && value.length > 6) {
|
|
61
|
-
return value.slice(0, 3) +
|
|
80
|
+
return value.slice(0, 3) + '***' + value.slice(-3);
|
|
62
81
|
}
|
|
63
82
|
return value;
|
|
64
83
|
}
|
|
65
84
|
function formatFieldValue(config, field) {
|
|
66
85
|
const value = config[field.key];
|
|
67
|
-
if (field.type ===
|
|
68
|
-
return value.join(
|
|
86
|
+
if (field.type === 'string[]' && Array.isArray(value)) {
|
|
87
|
+
return value.join(', ');
|
|
69
88
|
}
|
|
70
|
-
if (field.type ===
|
|
89
|
+
if (field.type === 'keyvalue') {
|
|
71
90
|
const env = value;
|
|
72
91
|
const count = Object.keys(env).length;
|
|
73
|
-
return count > 0 ? `${count} variable(s) set` :
|
|
92
|
+
return count > 0 ? `${count} variable(s) set` : '(none)';
|
|
74
93
|
}
|
|
75
|
-
if (field.type ===
|
|
94
|
+
if (field.type === 'webhooks') {
|
|
76
95
|
const notif = value;
|
|
77
|
-
return notif.webhooks.length > 0 ? `${notif.webhooks.length} webhook(s)` :
|
|
96
|
+
return notif.webhooks.length > 0 ? `${notif.webhooks.length} webhook(s)` : '(none)';
|
|
78
97
|
}
|
|
79
98
|
return String(value);
|
|
80
99
|
}
|
|
@@ -85,25 +104,25 @@ export function createConfigTab() {
|
|
|
85
104
|
const container = blessed.box({
|
|
86
105
|
top: 0,
|
|
87
106
|
left: 0,
|
|
88
|
-
width:
|
|
89
|
-
height:
|
|
107
|
+
width: '100%',
|
|
108
|
+
height: '100%',
|
|
90
109
|
hidden: true,
|
|
91
110
|
});
|
|
92
111
|
const configList = blessed.list({
|
|
93
112
|
top: 0,
|
|
94
113
|
left: 0,
|
|
95
|
-
width:
|
|
96
|
-
height:
|
|
97
|
-
border: { type:
|
|
98
|
-
label:
|
|
114
|
+
width: '100%',
|
|
115
|
+
height: '100%-3',
|
|
116
|
+
border: { type: 'line' },
|
|
117
|
+
label: '[ Configuration ]',
|
|
99
118
|
tags: true,
|
|
100
119
|
scrollable: true,
|
|
101
120
|
alwaysScroll: true,
|
|
102
|
-
scrollbar: { style: { bg:
|
|
121
|
+
scrollbar: { style: { bg: 'blue' } },
|
|
103
122
|
style: {
|
|
104
|
-
border: { fg:
|
|
105
|
-
selected: { bg:
|
|
106
|
-
item: { fg:
|
|
123
|
+
border: { fg: 'cyan' },
|
|
124
|
+
selected: { bg: 'blue', fg: 'white' },
|
|
125
|
+
item: { fg: 'white' },
|
|
107
126
|
},
|
|
108
127
|
keys: true,
|
|
109
128
|
vi: false,
|
|
@@ -113,12 +132,12 @@ export function createConfigTab() {
|
|
|
113
132
|
const statusBar = blessed.box({
|
|
114
133
|
bottom: 0,
|
|
115
134
|
left: 0,
|
|
116
|
-
width:
|
|
135
|
+
width: '100%',
|
|
117
136
|
height: 3,
|
|
118
|
-
border: { type:
|
|
137
|
+
border: { type: 'line' },
|
|
119
138
|
tags: true,
|
|
120
|
-
style: { border: { fg:
|
|
121
|
-
content:
|
|
139
|
+
style: { border: { fg: 'white' } },
|
|
140
|
+
content: '',
|
|
122
141
|
});
|
|
123
142
|
container.append(configList);
|
|
124
143
|
container.append(statusBar);
|
|
@@ -130,8 +149,10 @@ export function createConfigTab() {
|
|
|
130
149
|
const value = hasChange
|
|
131
150
|
? formatFieldValue({ ...config, ...pendingChanges }, field)
|
|
132
151
|
: formatFieldValue(config, field);
|
|
133
|
-
const marker = hasChange ?
|
|
134
|
-
const editHint = field.type ===
|
|
152
|
+
const marker = hasChange ? ' {yellow-fg}*{/yellow-fg}' : '';
|
|
153
|
+
const editHint = field.type === 'keyvalue' || field.type === 'webhooks'
|
|
154
|
+
? ' {#888888-fg}(Enter to manage){/#888888-fg}'
|
|
155
|
+
: '';
|
|
135
156
|
return ` ${field.label}: ${value}${marker}${editHint}`;
|
|
136
157
|
});
|
|
137
158
|
}
|
|
@@ -141,7 +162,7 @@ export function createConfigTab() {
|
|
|
141
162
|
statusBar.setContent(` {yellow-fg}${changeCount} unsaved change(s){/yellow-fg} | s:Save & Apply u:Undo All`);
|
|
142
163
|
}
|
|
143
164
|
else {
|
|
144
|
-
statusBar.setContent(
|
|
165
|
+
statusBar.setContent(' No pending changes');
|
|
145
166
|
}
|
|
146
167
|
}
|
|
147
168
|
function refreshList(config) {
|
|
@@ -161,21 +182,21 @@ export function createConfigTab() {
|
|
|
161
182
|
function buildItems() {
|
|
162
183
|
const entries = Object.entries(editableEnv);
|
|
163
184
|
if (entries.length === 0)
|
|
164
|
-
return [
|
|
185
|
+
return [' (no variables set)'];
|
|
165
186
|
return entries.map(([k, v]) => ` ${k} = ${maskValue(k, v)}`);
|
|
166
187
|
}
|
|
167
188
|
const kvList = blessed.list({
|
|
168
|
-
top:
|
|
169
|
-
left:
|
|
170
|
-
width:
|
|
189
|
+
top: 'center',
|
|
190
|
+
left: 'center',
|
|
191
|
+
width: '70%',
|
|
171
192
|
height: Math.min(Object.keys(editableEnv).length + 4, 20),
|
|
172
|
-
border: { type:
|
|
173
|
-
label:
|
|
193
|
+
border: { type: 'line' },
|
|
194
|
+
label: '[ Provider Env Vars | a:Add Enter:Edit d:Delete Esc:Done ]',
|
|
174
195
|
tags: true,
|
|
175
196
|
style: {
|
|
176
|
-
border: { fg:
|
|
177
|
-
selected: { bg:
|
|
178
|
-
item: { fg:
|
|
197
|
+
border: { fg: 'cyan' },
|
|
198
|
+
selected: { bg: 'blue', fg: 'white' },
|
|
199
|
+
item: { fg: 'white' },
|
|
179
200
|
},
|
|
180
201
|
keys: true,
|
|
181
202
|
vi: false,
|
|
@@ -193,37 +214,37 @@ export function createConfigTab() {
|
|
|
193
214
|
}
|
|
194
215
|
function promptTextbox(label, initialValue, cb) {
|
|
195
216
|
const input = blessed.textbox({
|
|
196
|
-
top:
|
|
197
|
-
left:
|
|
198
|
-
width:
|
|
217
|
+
top: 'center',
|
|
218
|
+
left: 'center',
|
|
219
|
+
width: '50%',
|
|
199
220
|
height: 3,
|
|
200
|
-
border: { type:
|
|
221
|
+
border: { type: 'line' },
|
|
201
222
|
label: `[ ${label} ]`,
|
|
202
223
|
tags: true,
|
|
203
|
-
style: { border: { fg:
|
|
224
|
+
style: { border: { fg: 'yellow' }, fg: 'white' },
|
|
204
225
|
inputOnFocus: true,
|
|
205
226
|
});
|
|
206
227
|
ctx.screen.append(input);
|
|
207
228
|
input.setValue(initialValue);
|
|
208
229
|
input.focus();
|
|
209
230
|
ctx.screen.render();
|
|
210
|
-
input.on(
|
|
231
|
+
input.on('submit', (value) => {
|
|
211
232
|
input.destroy();
|
|
212
233
|
cb(value.trim());
|
|
213
234
|
});
|
|
214
|
-
input.on(
|
|
235
|
+
input.on('cancel', () => {
|
|
215
236
|
input.destroy();
|
|
216
237
|
cb(null);
|
|
217
238
|
});
|
|
218
239
|
}
|
|
219
|
-
kvList.key([
|
|
220
|
-
promptTextbox(
|
|
240
|
+
kvList.key(['a'], () => {
|
|
241
|
+
promptTextbox('Variable Name', '', (key) => {
|
|
221
242
|
if (!key) {
|
|
222
243
|
kvList.focus();
|
|
223
244
|
ctx.screen.render();
|
|
224
245
|
return;
|
|
225
246
|
}
|
|
226
|
-
promptTextbox(`Value for ${key}`,
|
|
247
|
+
promptTextbox(`Value for ${key}`, '', (value) => {
|
|
227
248
|
if (value !== null) {
|
|
228
249
|
editableEnv[key] = value;
|
|
229
250
|
pendingChanges.providerEnv = { ...editableEnv };
|
|
@@ -234,7 +255,7 @@ export function createConfigTab() {
|
|
|
234
255
|
});
|
|
235
256
|
});
|
|
236
257
|
});
|
|
237
|
-
kvList.key([
|
|
258
|
+
kvList.key(['enter'], () => {
|
|
238
259
|
const keys = Object.keys(editableEnv);
|
|
239
260
|
if (keys.length === 0)
|
|
240
261
|
return;
|
|
@@ -252,7 +273,7 @@ export function createConfigTab() {
|
|
|
252
273
|
ctx.screen.render();
|
|
253
274
|
});
|
|
254
275
|
});
|
|
255
|
-
kvList.key([
|
|
276
|
+
kvList.key(['d'], () => {
|
|
256
277
|
const keys = Object.keys(editableEnv);
|
|
257
278
|
if (keys.length === 0)
|
|
258
279
|
return;
|
|
@@ -264,7 +285,7 @@ export function createConfigTab() {
|
|
|
264
285
|
pendingChanges.providerEnv = { ...editableEnv };
|
|
265
286
|
refreshKvList();
|
|
266
287
|
});
|
|
267
|
-
kvList.key([
|
|
288
|
+
kvList.key(['escape'], () => {
|
|
268
289
|
kvList.destroy();
|
|
269
290
|
ctx.setEditing(false);
|
|
270
291
|
if (currentConfig)
|
|
@@ -278,29 +299,34 @@ export function createConfigTab() {
|
|
|
278
299
|
const currentNotif = pendingChanges.notifications
|
|
279
300
|
? pendingChanges.notifications
|
|
280
301
|
: config.notifications;
|
|
281
|
-
const editableWebhooks = currentNotif.webhooks.map((w) => ({
|
|
302
|
+
const editableWebhooks = currentNotif.webhooks.map((w) => ({
|
|
303
|
+
...w,
|
|
304
|
+
events: [...w.events],
|
|
305
|
+
}));
|
|
282
306
|
function buildItems() {
|
|
283
307
|
if (editableWebhooks.length === 0)
|
|
284
|
-
return [
|
|
308
|
+
return [' (no webhooks configured)'];
|
|
285
309
|
return editableWebhooks.map((w) => {
|
|
286
|
-
const identifier = w.type ===
|
|
287
|
-
? `token:${maskValue(
|
|
288
|
-
:
|
|
310
|
+
const identifier = w.type === 'telegram'
|
|
311
|
+
? `token:${maskValue('TOKEN', w.botToken || '')}`
|
|
312
|
+
: w.url
|
|
313
|
+
? maskValue('URL', w.url)
|
|
314
|
+
: 'no url';
|
|
289
315
|
return ` [${w.type}] ${identifier} events: ${w.events.length}`;
|
|
290
316
|
});
|
|
291
317
|
}
|
|
292
318
|
const whList = blessed.list({
|
|
293
|
-
top:
|
|
294
|
-
left:
|
|
295
|
-
width:
|
|
319
|
+
top: 'center',
|
|
320
|
+
left: 'center',
|
|
321
|
+
width: '70%',
|
|
296
322
|
height: Math.min(editableWebhooks.length + 4, 20),
|
|
297
|
-
border: { type:
|
|
298
|
-
label:
|
|
323
|
+
border: { type: 'line' },
|
|
324
|
+
label: '[ Webhooks | a:Add Enter:Edit d:Delete Esc:Done ]',
|
|
299
325
|
tags: true,
|
|
300
326
|
style: {
|
|
301
|
-
border: { fg:
|
|
302
|
-
selected: { bg:
|
|
303
|
-
item: { fg:
|
|
327
|
+
border: { fg: 'cyan' },
|
|
328
|
+
selected: { bg: 'blue', fg: 'white' },
|
|
329
|
+
item: { fg: 'white' },
|
|
304
330
|
},
|
|
305
331
|
keys: true,
|
|
306
332
|
vi: false,
|
|
@@ -317,37 +343,49 @@ export function createConfigTab() {
|
|
|
317
343
|
ctx.screen.render();
|
|
318
344
|
}
|
|
319
345
|
function stageWebhookChanges() {
|
|
320
|
-
pendingChanges.notifications = {
|
|
346
|
+
pendingChanges.notifications = {
|
|
347
|
+
webhooks: editableWebhooks.map((w) => ({ ...w, events: [...w.events] })),
|
|
348
|
+
};
|
|
321
349
|
}
|
|
322
350
|
function promptTextbox(label, initialValue, cb) {
|
|
323
351
|
const input = blessed.textbox({
|
|
324
|
-
top:
|
|
325
|
-
left:
|
|
326
|
-
width:
|
|
352
|
+
top: 'center',
|
|
353
|
+
left: 'center',
|
|
354
|
+
width: '50%',
|
|
327
355
|
height: 3,
|
|
328
|
-
border: { type:
|
|
356
|
+
border: { type: 'line' },
|
|
329
357
|
label: `[ ${label} ]`,
|
|
330
358
|
tags: true,
|
|
331
|
-
style: { border: { fg:
|
|
359
|
+
style: { border: { fg: 'yellow' }, fg: 'white' },
|
|
332
360
|
inputOnFocus: true,
|
|
333
361
|
});
|
|
334
362
|
ctx.screen.append(input);
|
|
335
363
|
input.setValue(initialValue);
|
|
336
364
|
input.focus();
|
|
337
365
|
ctx.screen.render();
|
|
338
|
-
input.on(
|
|
339
|
-
|
|
366
|
+
input.on('submit', (value) => {
|
|
367
|
+
input.destroy();
|
|
368
|
+
cb(value.trim());
|
|
369
|
+
});
|
|
370
|
+
input.on('cancel', () => {
|
|
371
|
+
input.destroy();
|
|
372
|
+
cb(null);
|
|
373
|
+
});
|
|
340
374
|
}
|
|
341
375
|
function selectType(cb) {
|
|
342
376
|
const typeList = blessed.list({
|
|
343
|
-
top:
|
|
344
|
-
left:
|
|
377
|
+
top: 'center',
|
|
378
|
+
left: 'center',
|
|
345
379
|
width: 30,
|
|
346
380
|
height: WEBHOOK_TYPES.length + 2,
|
|
347
|
-
border: { type:
|
|
348
|
-
label:
|
|
381
|
+
border: { type: 'line' },
|
|
382
|
+
label: '[ Webhook Type ]',
|
|
349
383
|
tags: true,
|
|
350
|
-
style: {
|
|
384
|
+
style: {
|
|
385
|
+
border: { fg: 'yellow' },
|
|
386
|
+
selected: { bg: 'blue', fg: 'white' },
|
|
387
|
+
item: { fg: 'white' },
|
|
388
|
+
},
|
|
351
389
|
keys: true,
|
|
352
390
|
vi: false,
|
|
353
391
|
interactive: true,
|
|
@@ -356,35 +394,42 @@ export function createConfigTab() {
|
|
|
356
394
|
ctx.screen.append(typeList);
|
|
357
395
|
typeList.focus();
|
|
358
396
|
ctx.screen.render();
|
|
359
|
-
typeList.on(
|
|
397
|
+
typeList.on('select', (_item, index) => {
|
|
360
398
|
typeList.destroy();
|
|
361
399
|
cb(WEBHOOK_TYPES[index]);
|
|
362
400
|
});
|
|
363
|
-
typeList.key([
|
|
401
|
+
typeList.key(['escape'], () => {
|
|
402
|
+
typeList.destroy();
|
|
403
|
+
cb(null);
|
|
404
|
+
});
|
|
364
405
|
}
|
|
365
406
|
function selectEvents(current, cb) {
|
|
366
407
|
const selected = new Set(current);
|
|
367
408
|
const evList = blessed.list({
|
|
368
|
-
top:
|
|
369
|
-
left:
|
|
409
|
+
top: 'center',
|
|
410
|
+
left: 'center',
|
|
370
411
|
width: 40,
|
|
371
412
|
height: NOTIFICATION_EVENTS.length + 3,
|
|
372
|
-
border: { type:
|
|
373
|
-
label:
|
|
413
|
+
border: { type: 'line' },
|
|
414
|
+
label: '[ Events | Space:Toggle Enter:Done ]',
|
|
374
415
|
tags: true,
|
|
375
|
-
style: {
|
|
416
|
+
style: {
|
|
417
|
+
border: { fg: 'yellow' },
|
|
418
|
+
selected: { bg: 'blue', fg: 'white' },
|
|
419
|
+
item: { fg: 'white' },
|
|
420
|
+
},
|
|
376
421
|
keys: true,
|
|
377
422
|
vi: false,
|
|
378
423
|
interactive: true,
|
|
379
424
|
});
|
|
380
425
|
function renderEvents() {
|
|
381
|
-
evList.setItems(NOTIFICATION_EVENTS.map((e) => ` ${selected.has(e) ?
|
|
426
|
+
evList.setItems(NOTIFICATION_EVENTS.map((e) => ` ${selected.has(e) ? '[x]' : '[ ]'} ${e}`));
|
|
382
427
|
}
|
|
383
428
|
renderEvents();
|
|
384
429
|
ctx.screen.append(evList);
|
|
385
430
|
evList.focus();
|
|
386
431
|
ctx.screen.render();
|
|
387
|
-
evList.key([
|
|
432
|
+
evList.key(['space'], () => {
|
|
388
433
|
const idx = evList.selected;
|
|
389
434
|
if (idx >= 0 && idx < NOTIFICATION_EVENTS.length) {
|
|
390
435
|
const ev = NOTIFICATION_EVENTS[idx];
|
|
@@ -397,11 +442,14 @@ export function createConfigTab() {
|
|
|
397
442
|
ctx.screen.render();
|
|
398
443
|
}
|
|
399
444
|
});
|
|
400
|
-
evList.key([
|
|
445
|
+
evList.key(['enter'], () => {
|
|
401
446
|
evList.destroy();
|
|
402
447
|
cb([...selected]);
|
|
403
448
|
});
|
|
404
|
-
evList.key([
|
|
449
|
+
evList.key(['escape'], () => {
|
|
450
|
+
evList.destroy();
|
|
451
|
+
cb(null);
|
|
452
|
+
});
|
|
405
453
|
}
|
|
406
454
|
function addWebhookWizard() {
|
|
407
455
|
selectType((type) => {
|
|
@@ -412,14 +460,14 @@ export function createConfigTab() {
|
|
|
412
460
|
}
|
|
413
461
|
const webhook = { type, events: [...NOTIFICATION_EVENTS] };
|
|
414
462
|
const askCredentials = (done) => {
|
|
415
|
-
if (type ===
|
|
416
|
-
promptTextbox(
|
|
463
|
+
if (type === 'telegram') {
|
|
464
|
+
promptTextbox('Bot Token', '', (botToken) => {
|
|
417
465
|
if (botToken === null) {
|
|
418
466
|
done(false);
|
|
419
467
|
return;
|
|
420
468
|
}
|
|
421
469
|
webhook.botToken = botToken;
|
|
422
|
-
promptTextbox(
|
|
470
|
+
promptTextbox('Chat ID', '', (chatId) => {
|
|
423
471
|
if (chatId === null) {
|
|
424
472
|
done(false);
|
|
425
473
|
return;
|
|
@@ -430,7 +478,7 @@ export function createConfigTab() {
|
|
|
430
478
|
});
|
|
431
479
|
}
|
|
432
480
|
else {
|
|
433
|
-
promptTextbox(
|
|
481
|
+
promptTextbox('Webhook URL', '', (url) => {
|
|
434
482
|
if (url === null) {
|
|
435
483
|
done(false);
|
|
436
484
|
return;
|
|
@@ -472,15 +520,15 @@ export function createConfigTab() {
|
|
|
472
520
|
}
|
|
473
521
|
webhook.type = type;
|
|
474
522
|
const askCredentials = (done) => {
|
|
475
|
-
if (type ===
|
|
476
|
-
promptTextbox(
|
|
523
|
+
if (type === 'telegram') {
|
|
524
|
+
promptTextbox('Bot Token', webhook.botToken || '', (botToken) => {
|
|
477
525
|
if (botToken === null) {
|
|
478
526
|
done(false);
|
|
479
527
|
return;
|
|
480
528
|
}
|
|
481
529
|
webhook.botToken = botToken;
|
|
482
530
|
webhook.url = undefined;
|
|
483
|
-
promptTextbox(
|
|
531
|
+
promptTextbox('Chat ID', webhook.chatId || '', (chatId) => {
|
|
484
532
|
if (chatId === null) {
|
|
485
533
|
done(false);
|
|
486
534
|
return;
|
|
@@ -491,7 +539,7 @@ export function createConfigTab() {
|
|
|
491
539
|
});
|
|
492
540
|
}
|
|
493
541
|
else {
|
|
494
|
-
promptTextbox(
|
|
542
|
+
promptTextbox('Webhook URL', webhook.url || '', (url) => {
|
|
495
543
|
if (url === null) {
|
|
496
544
|
done(false);
|
|
497
545
|
return;
|
|
@@ -524,8 +572,8 @@ export function createConfigTab() {
|
|
|
524
572
|
});
|
|
525
573
|
});
|
|
526
574
|
}
|
|
527
|
-
whList.key([
|
|
528
|
-
whList.key([
|
|
575
|
+
whList.key(['a'], () => addWebhookWizard());
|
|
576
|
+
whList.key(['enter'], () => {
|
|
529
577
|
if (editableWebhooks.length === 0)
|
|
530
578
|
return;
|
|
531
579
|
const idx = whList.selected;
|
|
@@ -533,7 +581,7 @@ export function createConfigTab() {
|
|
|
533
581
|
editWebhook(idx);
|
|
534
582
|
}
|
|
535
583
|
});
|
|
536
|
-
whList.key([
|
|
584
|
+
whList.key(['d'], () => {
|
|
537
585
|
if (editableWebhooks.length === 0)
|
|
538
586
|
return;
|
|
539
587
|
const idx = whList.selected;
|
|
@@ -543,7 +591,7 @@ export function createConfigTab() {
|
|
|
543
591
|
refreshWhList();
|
|
544
592
|
}
|
|
545
593
|
});
|
|
546
|
-
whList.key([
|
|
594
|
+
whList.key(['escape'], () => {
|
|
547
595
|
whList.destroy();
|
|
548
596
|
ctx.setEditing(false);
|
|
549
597
|
if (currentConfig)
|
|
@@ -555,27 +603,27 @@ export function createConfigTab() {
|
|
|
555
603
|
// ── GLM-5 Quick Setup ──────────────────────────────────────────────────
|
|
556
604
|
function showGlm5Setup(ctx) {
|
|
557
605
|
const inputBox = blessed.textbox({
|
|
558
|
-
top:
|
|
559
|
-
left:
|
|
560
|
-
width:
|
|
606
|
+
top: 'center',
|
|
607
|
+
left: 'center',
|
|
608
|
+
width: '60%',
|
|
561
609
|
height: 3,
|
|
562
|
-
border: { type:
|
|
563
|
-
label:
|
|
610
|
+
border: { type: 'line' },
|
|
611
|
+
label: '[ GLM-5 Quick Setup: Enter API Key ]',
|
|
564
612
|
tags: true,
|
|
565
|
-
style: { border: { fg:
|
|
613
|
+
style: { border: { fg: 'cyan' }, fg: 'white' },
|
|
566
614
|
inputOnFocus: true,
|
|
567
615
|
});
|
|
568
616
|
ctx.setEditing(true);
|
|
569
617
|
ctx.screen.append(inputBox);
|
|
570
|
-
inputBox.setValue(
|
|
618
|
+
inputBox.setValue('');
|
|
571
619
|
inputBox.focus();
|
|
572
620
|
ctx.screen.render();
|
|
573
|
-
inputBox.on(
|
|
621
|
+
inputBox.on('submit', (value) => {
|
|
574
622
|
const apiKey = value.trim();
|
|
575
623
|
inputBox.destroy();
|
|
576
624
|
ctx.setEditing(false);
|
|
577
625
|
if (!apiKey) {
|
|
578
|
-
ctx.showMessage(
|
|
626
|
+
ctx.showMessage('No API key provided', 'error');
|
|
579
627
|
configList.focus();
|
|
580
628
|
ctx.screen.render();
|
|
581
629
|
return;
|
|
@@ -585,13 +633,13 @@ export function createConfigTab() {
|
|
|
585
633
|
ANTHROPIC_AUTH_TOKEN: apiKey,
|
|
586
634
|
...GLM5_DEFAULTS,
|
|
587
635
|
};
|
|
588
|
-
ctx.showMessage(
|
|
636
|
+
ctx.showMessage('GLM-5 configured. Press s to save.', 'success');
|
|
589
637
|
if (currentConfig)
|
|
590
638
|
refreshList(currentConfig);
|
|
591
639
|
configList.focus();
|
|
592
640
|
ctx.screen.render();
|
|
593
641
|
});
|
|
594
|
-
inputBox.on(
|
|
642
|
+
inputBox.on('cancel', () => {
|
|
595
643
|
inputBox.destroy();
|
|
596
644
|
ctx.setEditing(false);
|
|
597
645
|
configList.focus();
|
|
@@ -600,31 +648,31 @@ export function createConfigTab() {
|
|
|
600
648
|
}
|
|
601
649
|
// ── Standard Editor ─────────────────────────────────────────────────────
|
|
602
650
|
function showEditor(ctx, field, config) {
|
|
603
|
-
if (field.type ===
|
|
651
|
+
if (field.type === 'keyvalue') {
|
|
604
652
|
showKeyValueEditor(ctx, config);
|
|
605
653
|
return;
|
|
606
654
|
}
|
|
607
|
-
if (field.type ===
|
|
655
|
+
if (field.type === 'webhooks') {
|
|
608
656
|
showWebhookEditor(ctx, config);
|
|
609
657
|
return;
|
|
610
658
|
}
|
|
611
659
|
const currentValue = field.key in pendingChanges
|
|
612
660
|
? String(pendingChanges[field.key])
|
|
613
661
|
: formatFieldValue(config, field);
|
|
614
|
-
if (field.type ===
|
|
615
|
-
const options = field.type ===
|
|
662
|
+
if (field.type === 'enum' || field.type === 'boolean') {
|
|
663
|
+
const options = field.type === 'boolean' ? ['true', 'false'] : field.options || [];
|
|
616
664
|
const selectorList = blessed.list({
|
|
617
|
-
top:
|
|
618
|
-
left:
|
|
665
|
+
top: 'center',
|
|
666
|
+
left: 'center',
|
|
619
667
|
width: Math.max(30, ...options.map((o) => o.length + 6)),
|
|
620
668
|
height: options.length + 2,
|
|
621
|
-
border: { type:
|
|
669
|
+
border: { type: 'line' },
|
|
622
670
|
label: `[ ${field.label} ]`,
|
|
623
671
|
tags: true,
|
|
624
672
|
style: {
|
|
625
|
-
border: { fg:
|
|
626
|
-
selected: { bg:
|
|
627
|
-
item: { fg:
|
|
673
|
+
border: { fg: 'cyan' },
|
|
674
|
+
selected: { bg: 'blue', fg: 'white' },
|
|
675
|
+
item: { fg: 'white' },
|
|
628
676
|
},
|
|
629
677
|
keys: true,
|
|
630
678
|
vi: false,
|
|
@@ -640,10 +688,10 @@ export function createConfigTab() {
|
|
|
640
688
|
ctx.screen.append(selectorList);
|
|
641
689
|
selectorList.focus();
|
|
642
690
|
ctx.screen.render();
|
|
643
|
-
selectorList.on(
|
|
691
|
+
selectorList.on('select', (_item, index) => {
|
|
644
692
|
const selected = options[index];
|
|
645
|
-
if (field.type ===
|
|
646
|
-
pendingChanges[field.key] = selected ===
|
|
693
|
+
if (field.type === 'boolean') {
|
|
694
|
+
pendingChanges[field.key] = selected === 'true';
|
|
647
695
|
}
|
|
648
696
|
else {
|
|
649
697
|
pendingChanges[field.key] = selected;
|
|
@@ -654,7 +702,7 @@ export function createConfigTab() {
|
|
|
654
702
|
configList.focus();
|
|
655
703
|
ctx.screen.render();
|
|
656
704
|
});
|
|
657
|
-
selectorList.key([
|
|
705
|
+
selectorList.key(['escape'], () => {
|
|
658
706
|
selectorList.destroy();
|
|
659
707
|
ctx.setEditing(false);
|
|
660
708
|
configList.focus();
|
|
@@ -664,16 +712,16 @@ export function createConfigTab() {
|
|
|
664
712
|
}
|
|
665
713
|
// Text input for string, number, string[]
|
|
666
714
|
const inputBox = blessed.textbox({
|
|
667
|
-
top:
|
|
668
|
-
left:
|
|
669
|
-
width:
|
|
715
|
+
top: 'center',
|
|
716
|
+
left: 'center',
|
|
717
|
+
width: '60%',
|
|
670
718
|
height: 3,
|
|
671
|
-
border: { type:
|
|
719
|
+
border: { type: 'line' },
|
|
672
720
|
label: `[ ${field.label} ]`,
|
|
673
721
|
tags: true,
|
|
674
722
|
style: {
|
|
675
|
-
border: { fg:
|
|
676
|
-
fg:
|
|
723
|
+
border: { fg: 'cyan' },
|
|
724
|
+
fg: 'white',
|
|
677
725
|
},
|
|
678
726
|
inputOnFocus: true,
|
|
679
727
|
});
|
|
@@ -682,12 +730,12 @@ export function createConfigTab() {
|
|
|
682
730
|
inputBox.setValue(currentValue);
|
|
683
731
|
inputBox.focus();
|
|
684
732
|
ctx.screen.render();
|
|
685
|
-
inputBox.on(
|
|
733
|
+
inputBox.on('submit', (value) => {
|
|
686
734
|
// Validate
|
|
687
735
|
if (field.validate) {
|
|
688
736
|
const error = field.validate(value);
|
|
689
737
|
if (error) {
|
|
690
|
-
ctx.showMessage(error,
|
|
738
|
+
ctx.showMessage(error, 'error');
|
|
691
739
|
inputBox.destroy();
|
|
692
740
|
ctx.setEditing(false);
|
|
693
741
|
configList.focus();
|
|
@@ -696,11 +744,14 @@ export function createConfigTab() {
|
|
|
696
744
|
}
|
|
697
745
|
}
|
|
698
746
|
// Apply value
|
|
699
|
-
if (field.type ===
|
|
747
|
+
if (field.type === 'number') {
|
|
700
748
|
pendingChanges[field.key] = parseInt(value, 10);
|
|
701
749
|
}
|
|
702
|
-
else if (field.type ===
|
|
703
|
-
pendingChanges[field.key] = value
|
|
750
|
+
else if (field.type === 'string[]') {
|
|
751
|
+
pendingChanges[field.key] = value
|
|
752
|
+
.split(',')
|
|
753
|
+
.map((s) => s.trim())
|
|
754
|
+
.filter((s) => s.length > 0);
|
|
704
755
|
}
|
|
705
756
|
else {
|
|
706
757
|
pendingChanges[field.key] = value;
|
|
@@ -711,7 +762,7 @@ export function createConfigTab() {
|
|
|
711
762
|
configList.focus();
|
|
712
763
|
ctx.screen.render();
|
|
713
764
|
});
|
|
714
|
-
inputBox.on(
|
|
765
|
+
inputBox.on('cancel', () => {
|
|
715
766
|
inputBox.destroy();
|
|
716
767
|
ctx.setEditing(false);
|
|
717
768
|
configList.focus();
|
|
@@ -722,7 +773,9 @@ export function createConfigTab() {
|
|
|
722
773
|
let activeCtx = null;
|
|
723
774
|
function bindKeys(ctx) {
|
|
724
775
|
const handlers = [
|
|
725
|
-
[
|
|
776
|
+
[
|
|
777
|
+
['enter'],
|
|
778
|
+
() => {
|
|
726
779
|
const idx = configList.selected;
|
|
727
780
|
if (idx === undefined || idx < 0 || idx >= CONFIG_FIELDS.length)
|
|
728
781
|
return;
|
|
@@ -730,35 +783,38 @@ export function createConfigTab() {
|
|
|
730
783
|
if (currentConfig) {
|
|
731
784
|
showEditor(ctx, field, currentConfig);
|
|
732
785
|
}
|
|
733
|
-
}
|
|
734
|
-
|
|
786
|
+
},
|
|
787
|
+
],
|
|
788
|
+
[
|
|
789
|
+
['s'],
|
|
790
|
+
() => {
|
|
735
791
|
if (Object.keys(pendingChanges).length === 0) {
|
|
736
|
-
ctx.showMessage(
|
|
792
|
+
ctx.showMessage('No changes to save', 'info');
|
|
737
793
|
return;
|
|
738
794
|
}
|
|
739
795
|
// Save config
|
|
740
796
|
const result = saveConfig(ctx.projectDir, pendingChanges);
|
|
741
797
|
if (!result.success) {
|
|
742
|
-
ctx.showMessage(`Save failed: ${result.error}`,
|
|
798
|
+
ctx.showMessage(`Save failed: ${result.error}`, 'error');
|
|
743
799
|
return;
|
|
744
800
|
}
|
|
745
801
|
// Check if schedules changed - reinstall cron
|
|
746
|
-
const scheduleChanged =
|
|
747
|
-
|
|
748
|
-
|
|
802
|
+
const scheduleChanged = 'cronSchedule' in pendingChanges ||
|
|
803
|
+
'reviewerSchedule' in pendingChanges ||
|
|
804
|
+
'reviewerEnabled' in pendingChanges;
|
|
749
805
|
if (scheduleChanged) {
|
|
750
806
|
performUninstall(ctx.projectDir, { keepLogs: true });
|
|
751
807
|
const newConfig = ctx.reloadConfig();
|
|
752
808
|
const installResult = performInstall(ctx.projectDir, newConfig);
|
|
753
809
|
if (!installResult.success) {
|
|
754
|
-
ctx.showMessage(`Config saved but cron reinstall failed: ${installResult.error}`,
|
|
810
|
+
ctx.showMessage(`Config saved but cron reinstall failed: ${installResult.error}`, 'error');
|
|
755
811
|
}
|
|
756
812
|
else {
|
|
757
|
-
ctx.showMessage(
|
|
813
|
+
ctx.showMessage('Config saved & cron reinstalled', 'success');
|
|
758
814
|
}
|
|
759
815
|
}
|
|
760
816
|
else {
|
|
761
|
-
ctx.showMessage(
|
|
817
|
+
ctx.showMessage('Config saved', 'success');
|
|
762
818
|
}
|
|
763
819
|
// Reload config
|
|
764
820
|
currentConfig = ctx.reloadConfig();
|
|
@@ -768,20 +824,27 @@ export function createConfigTab() {
|
|
|
768
824
|
}
|
|
769
825
|
refreshList(currentConfig);
|
|
770
826
|
ctx.screen.render();
|
|
771
|
-
}
|
|
772
|
-
|
|
827
|
+
},
|
|
828
|
+
],
|
|
829
|
+
[
|
|
830
|
+
['u'],
|
|
831
|
+
() => {
|
|
773
832
|
for (const key of Object.keys(pendingChanges)) {
|
|
774
833
|
delete pendingChanges[key];
|
|
775
834
|
}
|
|
776
835
|
if (currentConfig) {
|
|
777
836
|
refreshList(currentConfig);
|
|
778
837
|
}
|
|
779
|
-
ctx.showMessage(
|
|
838
|
+
ctx.showMessage('Changes undone', 'info');
|
|
780
839
|
ctx.screen.render();
|
|
781
|
-
}
|
|
782
|
-
|
|
840
|
+
},
|
|
841
|
+
],
|
|
842
|
+
[
|
|
843
|
+
['g'],
|
|
844
|
+
() => {
|
|
783
845
|
showGlm5Setup(ctx);
|
|
784
|
-
}
|
|
846
|
+
},
|
|
847
|
+
],
|
|
785
848
|
];
|
|
786
849
|
for (const [keys, handler] of handlers) {
|
|
787
850
|
ctx.screen.key(keys, handler);
|
|
@@ -797,10 +860,10 @@ export function createConfigTab() {
|
|
|
797
860
|
activeKeyHandlers = [];
|
|
798
861
|
}
|
|
799
862
|
return {
|
|
800
|
-
name:
|
|
863
|
+
name: 'Config',
|
|
801
864
|
container,
|
|
802
865
|
activate(ctx) {
|
|
803
|
-
ctx.setFooter(
|
|
866
|
+
ctx.setFooter(' \u2191\u2193:Navigate Enter:Edit g:GLM-5 Setup s:Save u:Undo q:Quit');
|
|
804
867
|
currentConfig = ctx.config;
|
|
805
868
|
refreshList(currentConfig);
|
|
806
869
|
configList.focus();
|