@jonit-dev/night-watch-cli 1.7.30 → 1.7.32
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/cli.js +17016 -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/{src/commands → commands}/audit.js +29 -33
- 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 +74 -38
- 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 +17 -35
- 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 +0 -92
- package/dist/src/cli.js.map +0 -1
- package/dist/src/commands/audit.d.ts.map +0 -1
- 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 -1386
- 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 -165
- 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-audit.md +0 -87
- 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
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
set -euo pipefail
|
|
3
|
-
|
|
4
|
-
# Night Watch QA Cron Runner (project-agnostic)
|
|
5
|
-
# Usage: night-watch-qa-cron.sh /path/to/project
|
|
6
|
-
#
|
|
7
|
-
# NOTE: This script expects environment variables to be set by the caller.
|
|
8
|
-
# The Node.js CLI will inject config values via environment variables.
|
|
9
|
-
# Required env vars (with defaults shown):
|
|
10
|
-
# NW_QA_MAX_RUNTIME=3600 - Maximum runtime in seconds (1 hour)
|
|
11
|
-
# NW_PROVIDER_CMD=claude - AI provider CLI to use (claude, codex, etc.)
|
|
12
|
-
# NW_BRANCH_PATTERNS=feat/,night-watch/ - Comma-separated branch prefixes to match
|
|
13
|
-
# NW_QA_SKIP_LABEL=skip-qa - Label to skip QA on a PR
|
|
14
|
-
# NW_QA_ARTIFACTS=both - Artifact mode (both, tests, report)
|
|
15
|
-
# NW_QA_AUTO_INSTALL_PLAYWRIGHT=1 - Auto-install Playwright browsers
|
|
16
|
-
# NW_DRY_RUN=0 - Set to 1 for dry-run mode (prints diagnostics only)
|
|
17
|
-
|
|
18
|
-
PROJECT_DIR="${1:?Usage: $0 /path/to/project}"
|
|
19
|
-
PROJECT_NAME=$(basename "${PROJECT_DIR}")
|
|
20
|
-
LOG_DIR="${PROJECT_DIR}/logs"
|
|
21
|
-
LOG_FILE="${LOG_DIR}/night-watch-qa.log"
|
|
22
|
-
MAX_RUNTIME="${NW_QA_MAX_RUNTIME:-3600}" # 1 hour
|
|
23
|
-
MAX_LOG_SIZE="524288" # 512 KB
|
|
24
|
-
PROVIDER_CMD="${NW_PROVIDER_CMD:-claude}"
|
|
25
|
-
BRANCH_PATTERNS_RAW="${NW_BRANCH_PATTERNS:-feat/,night-watch/}"
|
|
26
|
-
SKIP_LABEL="${NW_QA_SKIP_LABEL:-skip-qa}"
|
|
27
|
-
QA_ARTIFACTS="${NW_QA_ARTIFACTS:-both}"
|
|
28
|
-
QA_AUTO_INSTALL_PLAYWRIGHT="${NW_QA_AUTO_INSTALL_PLAYWRIGHT:-1}"
|
|
29
|
-
|
|
30
|
-
# Ensure NVM / Node / Claude are on PATH
|
|
31
|
-
export NVM_DIR="${HOME}/.nvm"
|
|
32
|
-
[ -s "${NVM_DIR}/nvm.sh" ] && . "${NVM_DIR}/nvm.sh"
|
|
33
|
-
|
|
34
|
-
# NOTE: Environment variables should be set by the caller (Node.js CLI).
|
|
35
|
-
# The .env.night-watch sourcing has been removed - config is now injected via env vars.
|
|
36
|
-
|
|
37
|
-
mkdir -p "${LOG_DIR}"
|
|
38
|
-
|
|
39
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
40
|
-
# shellcheck source=night-watch-helpers.sh
|
|
41
|
-
source "${SCRIPT_DIR}/night-watch-helpers.sh"
|
|
42
|
-
PROJECT_RUNTIME_KEY=$(project_runtime_key "${PROJECT_DIR}")
|
|
43
|
-
# NOTE: Lock file path must match qaLockPath() in src/utils/status-data.ts
|
|
44
|
-
LOCK_FILE="/tmp/night-watch-qa-${PROJECT_RUNTIME_KEY}.lock"
|
|
45
|
-
|
|
46
|
-
emit_result() {
|
|
47
|
-
local status="${1:?status required}"
|
|
48
|
-
local details="${2:-}"
|
|
49
|
-
if [ -n "${details}" ]; then
|
|
50
|
-
echo "NIGHT_WATCH_RESULT:${status}|${details}"
|
|
51
|
-
else
|
|
52
|
-
echo "NIGHT_WATCH_RESULT:${status}"
|
|
53
|
-
fi
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
# Validate provider
|
|
57
|
-
if ! validate_provider "${PROVIDER_CMD}"; then
|
|
58
|
-
echo "ERROR: Unknown provider: ${PROVIDER_CMD}" >&2
|
|
59
|
-
exit 1
|
|
60
|
-
fi
|
|
61
|
-
|
|
62
|
-
rotate_log
|
|
63
|
-
|
|
64
|
-
if ! acquire_lock "${LOCK_FILE}"; then
|
|
65
|
-
emit_result "skip_locked"
|
|
66
|
-
exit 0
|
|
67
|
-
fi
|
|
68
|
-
|
|
69
|
-
cd "${PROJECT_DIR}"
|
|
70
|
-
|
|
71
|
-
# Convert comma-separated branch prefixes into a regex that matches branch starts.
|
|
72
|
-
BRANCH_REGEX=""
|
|
73
|
-
IFS=',' read -r -a BRANCH_PATTERNS <<< "${BRANCH_PATTERNS_RAW}"
|
|
74
|
-
for pattern in "${BRANCH_PATTERNS[@]}"; do
|
|
75
|
-
trimmed_pattern=$(printf '%s' "${pattern}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
|
|
76
|
-
if [ -n "${trimmed_pattern}" ]; then
|
|
77
|
-
BRANCH_REGEX="${BRANCH_REGEX}${BRANCH_REGEX:+|}^${trimmed_pattern}"
|
|
78
|
-
fi
|
|
79
|
-
done
|
|
80
|
-
|
|
81
|
-
if [ -z "${BRANCH_REGEX}" ]; then
|
|
82
|
-
BRANCH_REGEX='^(feat/|night-watch/)'
|
|
83
|
-
fi
|
|
84
|
-
|
|
85
|
-
# List open PRs with their details for filtering
|
|
86
|
-
PR_JSON=$(gh pr list --state open --json number,headRefName,title,labels 2>/dev/null || echo "[]")
|
|
87
|
-
|
|
88
|
-
# Count PRs matching branch patterns
|
|
89
|
-
OPEN_PRS=$(
|
|
90
|
-
echo "${PR_JSON}" \
|
|
91
|
-
| jq -r '.[].headRefName' 2>/dev/null \
|
|
92
|
-
| { grep -E "${BRANCH_REGEX}" || true; } \
|
|
93
|
-
| wc -l \
|
|
94
|
-
| tr -d '[:space:]'
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
if [ "${OPEN_PRS}" -eq 0 ]; then
|
|
98
|
-
log "SKIP: No open PRs matching branch patterns (${BRANCH_PATTERNS_RAW})"
|
|
99
|
-
emit_result "skip_no_open_prs"
|
|
100
|
-
exit 0
|
|
101
|
-
fi
|
|
102
|
-
|
|
103
|
-
REPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner' 2>/dev/null || echo "")
|
|
104
|
-
|
|
105
|
-
# Collect PRs that need QA
|
|
106
|
-
PRS_NEEDING_QA=""
|
|
107
|
-
QA_NEEDED=0
|
|
108
|
-
|
|
109
|
-
while IFS=$'\t' read -r pr_number pr_branch pr_title pr_labels; do
|
|
110
|
-
if [ -z "${pr_number}" ] || [ -z "${pr_branch}" ]; then
|
|
111
|
-
continue
|
|
112
|
-
fi
|
|
113
|
-
|
|
114
|
-
# Filter by branch pattern
|
|
115
|
-
if ! printf '%s\n' "${pr_branch}" | grep -Eq "${BRANCH_REGEX}"; then
|
|
116
|
-
continue
|
|
117
|
-
fi
|
|
118
|
-
|
|
119
|
-
# Skip PRs with the skip label
|
|
120
|
-
if echo "${pr_labels}" | grep -q "${SKIP_LABEL}"; then
|
|
121
|
-
log "SKIP-QA: PR #${pr_number} (${pr_branch}) has '${SKIP_LABEL}' label"
|
|
122
|
-
continue
|
|
123
|
-
fi
|
|
124
|
-
|
|
125
|
-
# Skip PRs with [skip-qa] in their title
|
|
126
|
-
if echo "${pr_title}" | grep -qi '\[skip-qa\]'; then
|
|
127
|
-
log "SKIP-QA: PR #${pr_number} (${pr_branch}) has [skip-qa] in title"
|
|
128
|
-
continue
|
|
129
|
-
fi
|
|
130
|
-
|
|
131
|
-
# Skip PRs that already have a QA comment (idempotency)
|
|
132
|
-
ALL_COMMENTS=$(
|
|
133
|
-
{
|
|
134
|
-
gh pr view "${pr_number}" --json comments --jq '.comments[].body' 2>/dev/null || true
|
|
135
|
-
if [ -n "${REPO}" ]; then
|
|
136
|
-
gh api "repos/${REPO}/issues/${pr_number}/comments" --jq '.[].body' 2>/dev/null || true
|
|
137
|
-
fi
|
|
138
|
-
} | sort -u
|
|
139
|
-
)
|
|
140
|
-
if echo "${ALL_COMMENTS}" | grep -q '<!-- night-watch-qa-marker -->'; then
|
|
141
|
-
log "SKIP-QA: PR #${pr_number} (${pr_branch}) already has QA comment"
|
|
142
|
-
continue
|
|
143
|
-
fi
|
|
144
|
-
|
|
145
|
-
QA_NEEDED=1
|
|
146
|
-
PRS_NEEDING_QA="${PRS_NEEDING_QA} #${pr_number}"
|
|
147
|
-
done < <(
|
|
148
|
-
echo "${PR_JSON}" \
|
|
149
|
-
| jq -r '.[] | [.number, .headRefName, .title, ([.labels[].name] | join(","))] | @tsv' 2>/dev/null || true
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
if [ "${QA_NEEDED}" -eq 0 ]; then
|
|
153
|
-
log "SKIP: All ${OPEN_PRS} open PR(s) matching patterns already have QA comments"
|
|
154
|
-
emit_result "skip_all_qa_done"
|
|
155
|
-
exit 0
|
|
156
|
-
fi
|
|
157
|
-
|
|
158
|
-
PRS_NEEDING_QA=$(echo "${PRS_NEEDING_QA}" \
|
|
159
|
-
| sed -e 's/^[[:space:]]*//' -e 's/[[:space:]][[:space:]]*/ /g' -e 's/[[:space:]]*$//')
|
|
160
|
-
PRS_NEEDING_QA_CSV="${PRS_NEEDING_QA// /,}"
|
|
161
|
-
|
|
162
|
-
if [ -n "${NW_DEFAULT_BRANCH:-}" ]; then
|
|
163
|
-
DEFAULT_BRANCH="${NW_DEFAULT_BRANCH}"
|
|
164
|
-
else
|
|
165
|
-
DEFAULT_BRANCH=$(detect_default_branch "${PROJECT_DIR}")
|
|
166
|
-
fi
|
|
167
|
-
QA_WORKTREE_DIR="$(dirname "${PROJECT_DIR}")/${PROJECT_NAME}-nw-qa-runner"
|
|
168
|
-
|
|
169
|
-
log "START: Found PR(s) needing QA:${PRS_NEEDING_QA}"
|
|
170
|
-
|
|
171
|
-
cleanup_worktrees "${PROJECT_DIR}"
|
|
172
|
-
|
|
173
|
-
# Dry-run mode: print diagnostics and exit
|
|
174
|
-
if [ "${NW_DRY_RUN:-0}" = "1" ]; then
|
|
175
|
-
echo "=== Dry Run: QA Runner ==="
|
|
176
|
-
echo "Provider: ${PROVIDER_CMD}"
|
|
177
|
-
echo "Branch Patterns: ${BRANCH_PATTERNS_RAW}"
|
|
178
|
-
echo "Skip Label: ${SKIP_LABEL}"
|
|
179
|
-
echo "QA Artifacts: ${QA_ARTIFACTS}"
|
|
180
|
-
echo "Auto-install Playwright: ${QA_AUTO_INSTALL_PLAYWRIGHT}"
|
|
181
|
-
echo "Open PRs needing QA:${PRS_NEEDING_QA}"
|
|
182
|
-
echo "Default Branch: ${DEFAULT_BRANCH}"
|
|
183
|
-
echo "QA Worktree: ${QA_WORKTREE_DIR}"
|
|
184
|
-
echo "Timeout: ${MAX_RUNTIME}s"
|
|
185
|
-
exit 0
|
|
186
|
-
fi
|
|
187
|
-
|
|
188
|
-
EXIT_CODE=0
|
|
189
|
-
|
|
190
|
-
# Process each PR that needs QA
|
|
191
|
-
for pr_ref in ${PRS_NEEDING_QA}; do
|
|
192
|
-
pr_num="${pr_ref#\#}"
|
|
193
|
-
|
|
194
|
-
cleanup_worktrees "${PROJECT_DIR}"
|
|
195
|
-
if ! prepare_detached_worktree "${PROJECT_DIR}" "${QA_WORKTREE_DIR}" "${DEFAULT_BRANCH}" "${LOG_FILE}"; then
|
|
196
|
-
log "FAIL: Unable to create isolated QA worktree ${QA_WORKTREE_DIR} for PR #${pr_num}"
|
|
197
|
-
EXIT_CODE=1
|
|
198
|
-
break
|
|
199
|
-
fi
|
|
200
|
-
|
|
201
|
-
log "QA: Checking out PR #${pr_num} in worktree"
|
|
202
|
-
if ! (cd "${QA_WORKTREE_DIR}" && gh pr checkout "${pr_num}" >> "${LOG_FILE}" 2>&1); then
|
|
203
|
-
log "WARN: Failed to checkout PR #${pr_num}, skipping"
|
|
204
|
-
EXIT_CODE=1
|
|
205
|
-
cleanup_worktrees "${PROJECT_DIR}"
|
|
206
|
-
continue
|
|
207
|
-
fi
|
|
208
|
-
|
|
209
|
-
case "${PROVIDER_CMD}" in
|
|
210
|
-
claude)
|
|
211
|
-
if (
|
|
212
|
-
cd "${QA_WORKTREE_DIR}" && timeout "${MAX_RUNTIME}" \
|
|
213
|
-
claude -p "/night-watch-qa" \
|
|
214
|
-
--dangerously-skip-permissions \
|
|
215
|
-
>> "${LOG_FILE}" 2>&1
|
|
216
|
-
); then
|
|
217
|
-
log "QA: PR #${pr_num} — provider completed successfully"
|
|
218
|
-
else
|
|
219
|
-
local_exit=$?
|
|
220
|
-
log "QA: PR #${pr_num} — provider exited with code ${local_exit}"
|
|
221
|
-
if [ ${local_exit} -eq 124 ]; then
|
|
222
|
-
EXIT_CODE=124
|
|
223
|
-
break
|
|
224
|
-
fi
|
|
225
|
-
EXIT_CODE=${local_exit}
|
|
226
|
-
fi
|
|
227
|
-
;;
|
|
228
|
-
codex)
|
|
229
|
-
if (
|
|
230
|
-
cd "${QA_WORKTREE_DIR}" && timeout "${MAX_RUNTIME}" \
|
|
231
|
-
codex --quiet \
|
|
232
|
-
--yolo \
|
|
233
|
-
--prompt "$(cat "${QA_WORKTREE_DIR}/.claude/commands/night-watch-qa.md")" \
|
|
234
|
-
>> "${LOG_FILE}" 2>&1
|
|
235
|
-
); then
|
|
236
|
-
log "QA: PR #${pr_num} — provider completed successfully"
|
|
237
|
-
else
|
|
238
|
-
local_exit=$?
|
|
239
|
-
log "QA: PR #${pr_num} — provider exited with code ${local_exit}"
|
|
240
|
-
if [ ${local_exit} -eq 124 ]; then
|
|
241
|
-
EXIT_CODE=124
|
|
242
|
-
break
|
|
243
|
-
fi
|
|
244
|
-
EXIT_CODE=${local_exit}
|
|
245
|
-
fi
|
|
246
|
-
;;
|
|
247
|
-
*)
|
|
248
|
-
log "ERROR: Unknown provider: ${PROVIDER_CMD}"
|
|
249
|
-
exit 1
|
|
250
|
-
;;
|
|
251
|
-
esac
|
|
252
|
-
|
|
253
|
-
cleanup_worktrees "${PROJECT_DIR}"
|
|
254
|
-
done
|
|
255
|
-
|
|
256
|
-
cleanup_worktrees "${PROJECT_DIR}"
|
|
257
|
-
|
|
258
|
-
if [ ${EXIT_CODE} -eq 0 ]; then
|
|
259
|
-
log "DONE: QA runner completed successfully"
|
|
260
|
-
if [ -n "${REPO}" ]; then
|
|
261
|
-
emit_result "success_qa" "prs=${PRS_NEEDING_QA_CSV}|repo=${REPO}"
|
|
262
|
-
else
|
|
263
|
-
emit_result "success_qa" "prs=${PRS_NEEDING_QA_CSV}"
|
|
264
|
-
fi
|
|
265
|
-
elif [ ${EXIT_CODE} -eq 124 ]; then
|
|
266
|
-
log "TIMEOUT: QA runner killed after ${MAX_RUNTIME}s"
|
|
267
|
-
if [ -n "${REPO}" ]; then
|
|
268
|
-
emit_result "timeout" "prs=${PRS_NEEDING_QA_CSV}|repo=${REPO}"
|
|
269
|
-
else
|
|
270
|
-
emit_result "timeout" "prs=${PRS_NEEDING_QA_CSV}"
|
|
271
|
-
fi
|
|
272
|
-
else
|
|
273
|
-
log "FAIL: QA runner exited with code ${EXIT_CODE}"
|
|
274
|
-
if [ -n "${REPO}" ]; then
|
|
275
|
-
emit_result "failure" "prs=${PRS_NEEDING_QA_CSV}|repo=${REPO}"
|
|
276
|
-
else
|
|
277
|
-
emit_result "failure" "prs=${PRS_NEEDING_QA_CSV}"
|
|
278
|
-
fi
|
|
279
|
-
fi
|
|
280
|
-
|
|
281
|
-
exit "${EXIT_CODE}"
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
set -euo pipefail
|
|
3
|
-
|
|
4
|
-
# Night Watch Slicer Cron Runner (project-agnostic)
|
|
5
|
-
# Usage: night-watch-slicer-cron.sh /path/to/project
|
|
6
|
-
#
|
|
7
|
-
# This is a thin wrapper that acquires a lock and calls `night-watch slice`.
|
|
8
|
-
# The CLI command handles all the logic directly in TypeScript.
|
|
9
|
-
#
|
|
10
|
-
# NOTE: This script expects environment variables to be set by the caller.
|
|
11
|
-
# The Node.js CLI will inject config values via environment variables.
|
|
12
|
-
# Required env vars (with defaults shown):
|
|
13
|
-
# NW_SLICER_MAX_RUNTIME=600 - Maximum runtime in seconds (10 minutes)
|
|
14
|
-
# NW_PROVIDER_CMD=claude - AI provider CLI to use (claude, codex, etc.)
|
|
15
|
-
# NW_DRY_RUN=0 - Set to 1 for dry-run mode (prints diagnostics only)
|
|
16
|
-
|
|
17
|
-
PROJECT_DIR="${1:?Usage: $0 /path/to/project}"
|
|
18
|
-
PROJECT_NAME=$(basename "${PROJECT_DIR}")
|
|
19
|
-
LOG_DIR="${PROJECT_DIR}/logs"
|
|
20
|
-
LOG_FILE="${LOG_DIR}/night-watch-slicer.log"
|
|
21
|
-
LOCK_FILE=""
|
|
22
|
-
MAX_RUNTIME="${NW_SLICER_MAX_RUNTIME:-600}" # 10 minutes
|
|
23
|
-
MAX_LOG_SIZE="524288" # 512 KB
|
|
24
|
-
PROVIDER_CMD="${NW_PROVIDER_CMD:-claude}"
|
|
25
|
-
|
|
26
|
-
# Ensure NVM / Node / Night Watch CLI are on PATH
|
|
27
|
-
export NVM_DIR="${HOME}/.nvm"
|
|
28
|
-
[ -s "${NVM_DIR}/nvm.sh" ] && . "${NVM_DIR}/nvm.sh"
|
|
29
|
-
|
|
30
|
-
mkdir -p "${LOG_DIR}"
|
|
31
|
-
|
|
32
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
33
|
-
# shellcheck source=night-watch-helpers.sh
|
|
34
|
-
source "${SCRIPT_DIR}/night-watch-helpers.sh"
|
|
35
|
-
PROJECT_RUNTIME_KEY=$(project_runtime_key "${PROJECT_DIR}")
|
|
36
|
-
LOCK_FILE="/tmp/night-watch-slicer-${PROJECT_RUNTIME_KEY}.lock"
|
|
37
|
-
|
|
38
|
-
# Validate provider
|
|
39
|
-
if ! validate_provider "${PROVIDER_CMD}"; then
|
|
40
|
-
echo "ERROR: Unknown provider: ${PROVIDER_CMD}" >&2
|
|
41
|
-
exit 1
|
|
42
|
-
fi
|
|
43
|
-
|
|
44
|
-
rotate_log
|
|
45
|
-
|
|
46
|
-
if ! acquire_lock "${LOCK_FILE}"; then
|
|
47
|
-
exit 0
|
|
48
|
-
fi
|
|
49
|
-
|
|
50
|
-
cleanup_on_exit() {
|
|
51
|
-
rm -f "${LOCK_FILE}"
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
trap cleanup_on_exit EXIT
|
|
55
|
-
|
|
56
|
-
log "START: Running roadmap slicer for ${PROJECT_DIR}"
|
|
57
|
-
|
|
58
|
-
# Dry-run mode: print diagnostics and exit
|
|
59
|
-
if [ "${NW_DRY_RUN:-0}" = "1" ]; then
|
|
60
|
-
echo "=== Dry Run: Roadmap Slicer ==="
|
|
61
|
-
echo "Provider: ${PROVIDER_CMD}"
|
|
62
|
-
echo "Project Dir: ${PROJECT_DIR}"
|
|
63
|
-
echo "Timeout: ${MAX_RUNTIME}s"
|
|
64
|
-
exit 0
|
|
65
|
-
fi
|
|
66
|
-
|
|
67
|
-
# Resolve night-watch CLI
|
|
68
|
-
CLI_BIN=""
|
|
69
|
-
if ! CLI_BIN=$(resolve_night_watch_cli); then
|
|
70
|
-
log "ERROR: Could not resolve night-watch CLI"
|
|
71
|
-
exit 1
|
|
72
|
-
fi
|
|
73
|
-
|
|
74
|
-
# Run the slice command with timeout
|
|
75
|
-
EXIT_CODE=0
|
|
76
|
-
if timeout "${MAX_RUNTIME}" "${CLI_BIN}" slice >> "${LOG_FILE}" 2>&1; then
|
|
77
|
-
EXIT_CODE=0
|
|
78
|
-
else
|
|
79
|
-
EXIT_CODE=$?
|
|
80
|
-
fi
|
|
81
|
-
|
|
82
|
-
if [ ${EXIT_CODE} -eq 0 ]; then
|
|
83
|
-
log "DONE: Slicer completed successfully"
|
|
84
|
-
elif [ ${EXIT_CODE} -eq 124 ]; then
|
|
85
|
-
log "TIMEOUT: Slicer killed after ${MAX_RUNTIME}s"
|
|
86
|
-
else
|
|
87
|
-
log "FAIL: Slicer exited with code ${EXIT_CODE}"
|
|
88
|
-
fi
|
|
89
|
-
|
|
90
|
-
exit ${EXIT_CODE}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
|
|
3
|
-
# Tests for night-watch-helpers.sh claim functions
|
|
4
|
-
|
|
5
|
-
setup() {
|
|
6
|
-
# Source the helpers
|
|
7
|
-
SCRIPT_DIR="$(cd "$(dirname "${BATS_TEST_FILENAME}")" && pwd)"
|
|
8
|
-
|
|
9
|
-
# Set required globals
|
|
10
|
-
export LOG_FILE="/tmp/night-watch-test-$$.log"
|
|
11
|
-
|
|
12
|
-
source "${SCRIPT_DIR}/night-watch-helpers.sh"
|
|
13
|
-
|
|
14
|
-
# Create temp PRD directory
|
|
15
|
-
TEST_PRD_DIR=$(mktemp -d)
|
|
16
|
-
echo "# Test PRD" > "${TEST_PRD_DIR}/01-test-prd.md"
|
|
17
|
-
echo "# Test PRD 2" > "${TEST_PRD_DIR}/02-test-prd.md"
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
teardown() {
|
|
21
|
-
rm -rf "${TEST_PRD_DIR}"
|
|
22
|
-
rm -f "${LOG_FILE}"
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
@test "claim_prd creates .claim file with JSON" {
|
|
26
|
-
claim_prd "${TEST_PRD_DIR}" "01-test-prd.md"
|
|
27
|
-
|
|
28
|
-
[ -f "${TEST_PRD_DIR}/01-test-prd.md.claim" ]
|
|
29
|
-
|
|
30
|
-
local content
|
|
31
|
-
content=$(cat "${TEST_PRD_DIR}/01-test-prd.md.claim")
|
|
32
|
-
|
|
33
|
-
# Check JSON contains expected fields
|
|
34
|
-
echo "${content}" | grep -q '"timestamp":'
|
|
35
|
-
echo "${content}" | grep -q '"hostname":'
|
|
36
|
-
echo "${content}" | grep -q '"pid":'
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
@test "is_claimed returns 0 for active claim" {
|
|
40
|
-
claim_prd "${TEST_PRD_DIR}" "01-test-prd.md"
|
|
41
|
-
|
|
42
|
-
run is_claimed "${TEST_PRD_DIR}" "01-test-prd.md" 7200
|
|
43
|
-
[ "$status" -eq 0 ]
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
@test "is_claimed returns 1 for stale claim" {
|
|
47
|
-
# Write a claim with an old timestamp (1 second)
|
|
48
|
-
printf '{"timestamp":1000000000,"hostname":"test","pid":1}\n' \
|
|
49
|
-
> "${TEST_PRD_DIR}/01-test-prd.md.claim"
|
|
50
|
-
|
|
51
|
-
run is_claimed "${TEST_PRD_DIR}" "01-test-prd.md" 7200
|
|
52
|
-
[ "$status" -eq 1 ]
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
@test "is_claimed returns 1 for no claim" {
|
|
56
|
-
run is_claimed "${TEST_PRD_DIR}" "01-test-prd.md" 7200
|
|
57
|
-
[ "$status" -eq 1 ]
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
@test "release_claim removes .claim file" {
|
|
61
|
-
claim_prd "${TEST_PRD_DIR}" "01-test-prd.md"
|
|
62
|
-
[ -f "${TEST_PRD_DIR}/01-test-prd.md.claim" ]
|
|
63
|
-
|
|
64
|
-
release_claim "${TEST_PRD_DIR}" "01-test-prd.md"
|
|
65
|
-
[ ! -f "${TEST_PRD_DIR}/01-test-prd.md.claim" ]
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
@test "find_eligible_prd skips claimed PRD" {
|
|
69
|
-
# Claim the first PRD
|
|
70
|
-
claim_prd "${TEST_PRD_DIR}" "01-test-prd.md"
|
|
71
|
-
|
|
72
|
-
# find_eligible_prd should skip 01 and return 02
|
|
73
|
-
local result
|
|
74
|
-
result=$(find_eligible_prd "${TEST_PRD_DIR}" 7200)
|
|
75
|
-
|
|
76
|
-
[ "${result}" = "02-test-prd.md" ]
|
|
77
|
-
}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
You are the Night Watch Code Auditor. Your job is to scan the codebase for real engineering risks and write a structured, high-signal report.
|
|
2
|
-
|
|
3
|
-
## What to look for
|
|
4
|
-
|
|
5
|
-
### 1) Critical runtime and security risks
|
|
6
|
-
1. **Empty or swallowed catches** - `catch` blocks that discard meaningful errors in non-trivial paths.
|
|
7
|
-
2. **Critical TODOs/FIXMEs/HACKs** - comments mentioning `bug`, `security`, `race`, `leak`, `crash`, `hotfix`, `rollback`, `unsafe`.
|
|
8
|
-
3. **Hardcoded secrets or tokens** - API keys, passwords, tokens in source (exclude env var references).
|
|
9
|
-
4. **Unhandled promise rejections** - async flows with missing error handling.
|
|
10
|
-
5. **Unsafe type assertions** - `as any`, `as unknown as X`, dangerous non-null assertions (`!`) on uncertain input.
|
|
11
|
-
|
|
12
|
-
### 2) Scalability and performance hotspots
|
|
13
|
-
1. **N+1 / repeated expensive work** - repeated DB/API/file operations in loops.
|
|
14
|
-
2. **Unbounded processing** - full in-memory loading of large datasets, missing pagination/streaming/chunking.
|
|
15
|
-
3. **Blocking work on hot paths** - sync I/O or CPU-heavy work in frequent request/loop paths.
|
|
16
|
-
4. **Missing backpressure/limits** - unbounded queues, retries, fan-out, or concurrency.
|
|
17
|
-
|
|
18
|
-
### 3) Architecture and maintainability risks
|
|
19
|
-
1. **Architecture violations** - business logic mixed into transport/UI/glue layers; hidden cross-layer dependencies.
|
|
20
|
-
2. **SRP violations** - modules/functions/classes doing multiple unrelated responsibilities.
|
|
21
|
-
3. **DRY violations** - duplicated logic likely to drift and cause inconsistent behavior.
|
|
22
|
-
4. **KISS violations** - unnecessary complexity where simple solutions suffice.
|
|
23
|
-
5. **SOLID violations** - violations that materially reduce extensibility/testability and cause real risk.
|
|
24
|
-
6. **YAGNI violations** - speculative abstractions/features not needed by current behavior, adding maintenance cost.
|
|
25
|
-
|
|
26
|
-
## What to SKIP
|
|
27
|
-
|
|
28
|
-
- `node_modules/`, `dist/`, `.git/`, `coverage/`, generated files.
|
|
29
|
-
- Test files (`*.test.ts`, `*.spec.ts`, `__tests__/`) unless they expose production design flaws.
|
|
30
|
-
- Intentional no-op catches in file walkers/read-only probing paths (e.g., `catch { continue }`, `catch { return null }` when clearly harmless).
|
|
31
|
-
- Cosmetic style-only nits (formatting, naming preference, import order).
|
|
32
|
-
- Hypothetical principle violations without concrete impact.
|
|
33
|
-
|
|
34
|
-
## How to scan
|
|
35
|
-
|
|
36
|
-
Use file-reading/search tools and scan systematically, prioritizing:
|
|
37
|
-
- `src/` (core TypeScript implementation)
|
|
38
|
-
- `scripts/` (automation and shell execution paths)
|
|
39
|
-
|
|
40
|
-
For each potential issue, verify:
|
|
41
|
-
1. It is real and actionable.
|
|
42
|
-
2. It has concrete impact (correctness, security, scalability, operability, maintainability).
|
|
43
|
-
3. The fix direction is clear.
|
|
44
|
-
|
|
45
|
-
## Severity model
|
|
46
|
-
|
|
47
|
-
- **critical**: likely production outage/data loss/security exposure or severe architectural risk.
|
|
48
|
-
- **high**: significant bug/risk with near-term impact.
|
|
49
|
-
- **medium**: clear risk/smell that should be addressed soon.
|
|
50
|
-
- **low**: valid but lower urgency.
|
|
51
|
-
|
|
52
|
-
## Report format
|
|
53
|
-
|
|
54
|
-
Write findings to `logs/audit-report.md` using this exact format:
|
|
55
|
-
|
|
56
|
-
```markdown
|
|
57
|
-
# Code Audit Report
|
|
58
|
-
|
|
59
|
-
Generated: <ISO timestamp>
|
|
60
|
-
|
|
61
|
-
## Findings
|
|
62
|
-
|
|
63
|
-
### Finding 1
|
|
64
|
-
- **Location**: `src/path/to/file.ts:42`
|
|
65
|
-
- **Severity**: critical | high | medium | low
|
|
66
|
-
- **Category**: empty_catch | critical_todo | hardcoded_secret | unhandled_promise | unsafe_assertion | scalability_hotspot | architecture_violation | srp_violation | dry_violation | kiss_violation | solid_violation | yagni_violation
|
|
67
|
-
- **Description**: What the issue is, why it matters, and concrete impact
|
|
68
|
-
- **Snippet**: `the offending code`
|
|
69
|
-
- **Suggested Fix**: Specific fix direction (minimal, pragmatic)
|
|
70
|
-
|
|
71
|
-
### Finding 2
|
|
72
|
-
...
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
If you find **no actionable issues**, write exactly this to `logs/audit-report.md`:
|
|
76
|
-
|
|
77
|
-
```
|
|
78
|
-
NO_ISSUES_FOUND
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
## Rules
|
|
82
|
-
|
|
83
|
-
- Prioritize high-impact findings over volume. 3 strong findings beat 15 weak ones.
|
|
84
|
-
- Report principle violations (SRP/DRY/KISS/SOLID/YAGNI) only when they create concrete risk.
|
|
85
|
-
- Avoid theoretical architecture criticism without code evidence.
|
|
86
|
-
- Be decisive: skip noisy false positives.
|
|
87
|
-
- After writing the report, stop. Do NOT open PRs, push code, or make changes.
|