@jonit-dev/night-watch-cli 1.8.10-beta.7 → 1.8.11

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.
Files changed (135) hide show
  1. package/dist/cli.js +56 -25
  2. package/dist/commands/init.d.ts.map +1 -1
  3. package/dist/commands/init.js +3 -1
  4. package/dist/commands/init.js.map +1 -1
  5. package/dist/commands/run.d.ts.map +1 -1
  6. package/dist/commands/run.js +8 -6
  7. package/dist/commands/run.js.map +1 -1
  8. package/dist/scripts/night-watch-audit-cron.sh +6 -0
  9. package/dist/scripts/night-watch-cron.sh +37 -20
  10. package/dist/scripts/night-watch-helpers.sh +77 -5
  11. package/dist/scripts/night-watch-pr-reviewer-cron.sh +36 -11
  12. package/dist/scripts/night-watch-qa-cron.sh +6 -0
  13. package/dist/templates/night-watch.config.json +21 -1
  14. package/dist/web/assets/index-B6E6kOoR.js +406 -0
  15. package/dist/web/assets/index-C3BV1Hoa.js +406 -0
  16. package/dist/web/assets/index-DIMUXIP8.css +1 -0
  17. package/dist/web/assets/index-Ds8OqaCa.css +1 -0
  18. package/dist/web/assets/index-NR27JE3b.js +406 -0
  19. package/dist/web/index.html +2 -2
  20. package/package.json +1 -1
  21. package/dist/cli.d.ts +0 -3
  22. package/dist/cli.js.map +0 -1
  23. package/dist/commands/analytics.d.ts +0 -14
  24. package/dist/commands/analytics.js +0 -69
  25. package/dist/commands/analytics.js.map +0 -1
  26. package/dist/commands/audit.d.ts +0 -19
  27. package/dist/commands/audit.js +0 -144
  28. package/dist/commands/audit.js.map +0 -1
  29. package/dist/commands/board.d.ts +0 -9
  30. package/dist/commands/board.js +0 -702
  31. package/dist/commands/board.js.map +0 -1
  32. package/dist/commands/cancel.d.ts +0 -46
  33. package/dist/commands/cancel.js +0 -239
  34. package/dist/commands/cancel.js.map +0 -1
  35. package/dist/commands/cron.d.ts +0 -8
  36. package/dist/commands/cron.js +0 -134
  37. package/dist/commands/cron.js.map +0 -1
  38. package/dist/commands/dashboard/tab-actions.d.ts +0 -10
  39. package/dist/commands/dashboard/tab-actions.js +0 -247
  40. package/dist/commands/dashboard/tab-actions.js.map +0 -1
  41. package/dist/commands/dashboard/tab-config.d.ts +0 -21
  42. package/dist/commands/dashboard/tab-config.js +0 -874
  43. package/dist/commands/dashboard/tab-config.js.map +0 -1
  44. package/dist/commands/dashboard/tab-logs.d.ts +0 -10
  45. package/dist/commands/dashboard/tab-logs.js +0 -202
  46. package/dist/commands/dashboard/tab-logs.js.map +0 -1
  47. package/dist/commands/dashboard/tab-schedules.d.ts +0 -21
  48. package/dist/commands/dashboard/tab-schedules.js +0 -320
  49. package/dist/commands/dashboard/tab-schedules.js.map +0 -1
  50. package/dist/commands/dashboard/tab-status.d.ts +0 -32
  51. package/dist/commands/dashboard/tab-status.js +0 -424
  52. package/dist/commands/dashboard/tab-status.js.map +0 -1
  53. package/dist/commands/dashboard/types.d.ts +0 -42
  54. package/dist/commands/dashboard/types.js +0 -5
  55. package/dist/commands/dashboard/types.js.map +0 -1
  56. package/dist/commands/dashboard.d.ts +0 -11
  57. package/dist/commands/dashboard.js +0 -242
  58. package/dist/commands/dashboard.js.map +0 -1
  59. package/dist/commands/doctor.d.ts +0 -16
  60. package/dist/commands/doctor.js +0 -195
  61. package/dist/commands/doctor.js.map +0 -1
  62. package/dist/commands/history.d.ts +0 -7
  63. package/dist/commands/history.js +0 -49
  64. package/dist/commands/history.js.map +0 -1
  65. package/dist/commands/init.d.ts +0 -45
  66. package/dist/commands/install.d.ts +0 -65
  67. package/dist/commands/install.js +0 -405
  68. package/dist/commands/install.js.map +0 -1
  69. package/dist/commands/logs.d.ts +0 -15
  70. package/dist/commands/logs.js +0 -155
  71. package/dist/commands/logs.js.map +0 -1
  72. package/dist/commands/merge.d.ts +0 -26
  73. package/dist/commands/merge.js +0 -159
  74. package/dist/commands/merge.js.map +0 -1
  75. package/dist/commands/notify.d.ts +0 -7
  76. package/dist/commands/notify.js +0 -43
  77. package/dist/commands/notify.js.map +0 -1
  78. package/dist/commands/plan.d.ts +0 -19
  79. package/dist/commands/plan.js +0 -88
  80. package/dist/commands/plan.js.map +0 -1
  81. package/dist/commands/prd-state.d.ts +0 -12
  82. package/dist/commands/prd-state.js +0 -47
  83. package/dist/commands/prd-state.js.map +0 -1
  84. package/dist/commands/prd.d.ts +0 -18
  85. package/dist/commands/prd.js +0 -363
  86. package/dist/commands/prd.js.map +0 -1
  87. package/dist/commands/prds.d.ts +0 -13
  88. package/dist/commands/prds.js +0 -194
  89. package/dist/commands/prds.js.map +0 -1
  90. package/dist/commands/prs.d.ts +0 -14
  91. package/dist/commands/prs.js +0 -104
  92. package/dist/commands/prs.js.map +0 -1
  93. package/dist/commands/qa.d.ts +0 -34
  94. package/dist/commands/qa.js +0 -214
  95. package/dist/commands/qa.js.map +0 -1
  96. package/dist/commands/queue.d.ts +0 -8
  97. package/dist/commands/queue.js +0 -378
  98. package/dist/commands/queue.js.map +0 -1
  99. package/dist/commands/resolve.d.ts +0 -26
  100. package/dist/commands/resolve.js +0 -186
  101. package/dist/commands/resolve.js.map +0 -1
  102. package/dist/commands/retry.d.ts +0 -9
  103. package/dist/commands/retry.js +0 -71
  104. package/dist/commands/retry.js.map +0 -1
  105. package/dist/commands/review.d.ts +0 -82
  106. package/dist/commands/review.js +0 -479
  107. package/dist/commands/review.js.map +0 -1
  108. package/dist/commands/run.d.ts +0 -73
  109. package/dist/commands/serve.d.ts +0 -19
  110. package/dist/commands/serve.js +0 -142
  111. package/dist/commands/serve.js.map +0 -1
  112. package/dist/commands/shared/env-builder.d.ts +0 -49
  113. package/dist/commands/shared/env-builder.js +0 -151
  114. package/dist/commands/shared/env-builder.js.map +0 -1
  115. package/dist/commands/slice.d.ts +0 -35
  116. package/dist/commands/slice.js +0 -316
  117. package/dist/commands/slice.js.map +0 -1
  118. package/dist/commands/state.d.ts +0 -8
  119. package/dist/commands/state.js +0 -54
  120. package/dist/commands/state.js.map +0 -1
  121. package/dist/commands/status.d.ts +0 -14
  122. package/dist/commands/status.js +0 -297
  123. package/dist/commands/status.js.map +0 -1
  124. package/dist/commands/summary.d.ts +0 -14
  125. package/dist/commands/summary.js +0 -193
  126. package/dist/commands/summary.js.map +0 -1
  127. package/dist/commands/uninstall.d.ts +0 -25
  128. package/dist/commands/uninstall.js +0 -134
  129. package/dist/commands/uninstall.js.map +0 -1
  130. package/dist/commands/update.d.ts +0 -22
  131. package/dist/commands/update.js +0 -90
  132. package/dist/commands/update.js.map +0 -1
  133. package/dist/web/assets/index-BmRrWWHn.js +0 -406
  134. package/dist/web/assets/index-CgXj_KM1.css +0 -1
  135. package/dist/web/assets/index-Dr4zlyJf.js +0 -406
@@ -541,14 +541,14 @@ _is_lock_holder_alive() {
541
541
 
542
542
  append_exit_trap() {
543
543
  local command="${1:?command required}"
544
- local existing=""
545
544
 
546
- existing=$(trap -p EXIT | sed -n "s/^trap -- '\\(.*\\)' EXIT$/\\1/p")
547
- if [ -n "${existing}" ]; then
548
- trap "${existing}; ${command}" EXIT
545
+ if [ -n "${NW_EXIT_TRAP_CHAIN:-}" ]; then
546
+ NW_EXIT_TRAP_CHAIN="${NW_EXIT_TRAP_CHAIN}; ${command}"
549
547
  else
550
- trap "${command}" EXIT
548
+ NW_EXIT_TRAP_CHAIN="${command}"
551
549
  fi
550
+
551
+ trap "${NW_EXIT_TRAP_CHAIN}" EXIT
552
552
  }
553
553
 
554
554
  # ── Detect default branch ───────────────────────────────────────────────────
@@ -801,6 +801,31 @@ cleanup_worktrees() {
801
801
  git -C "${project_dir}" worktree prune >/dev/null 2>&1 || true
802
802
  }
803
803
 
804
+ cleanup_worktree_path() {
805
+ local project_dir="${1:?project_dir required}"
806
+ local worktree_dir="${2:?worktree_dir required}"
807
+
808
+ if [ -z "${worktree_dir}" ] || [ "${worktree_dir}" = "${project_dir}" ]; then
809
+ return 0
810
+ fi
811
+
812
+ git -C "${project_dir}" worktree prune >/dev/null 2>&1 || true
813
+
814
+ if git -C "${project_dir}" worktree list --porcelain 2>/dev/null \
815
+ | grep -qF "worktree ${worktree_dir}"; then
816
+ log "CLEANUP: Removing worktree ${worktree_dir}"
817
+ git -C "${project_dir}" worktree remove --force "${worktree_dir}" 2>/dev/null || true
818
+ fi
819
+
820
+ if [ -d "${worktree_dir}" ] && ! git -C "${project_dir}" worktree list --porcelain 2>/dev/null \
821
+ | grep -qF "worktree ${worktree_dir}"; then
822
+ log "CLEANUP: Removing stale worktree directory ${worktree_dir}"
823
+ rm -rf "${worktree_dir}" 2>/dev/null || true
824
+ fi
825
+
826
+ git -C "${project_dir}" worktree prune >/dev/null 2>&1 || true
827
+ }
828
+
804
829
  # Pick the best available ref for creating a new detached worktree.
805
830
  resolve_worktree_base_ref() {
806
831
  local project_dir="${1:?project_dir required}"
@@ -1169,6 +1194,53 @@ Proxy quota exhausted - falling back to native Claude (${model})"
1169
1194
  --data-urlencode "text=${msg}" > /dev/null 2>&1 || true
1170
1195
  }
1171
1196
 
1197
+ # Send an immediate Telegram warning when a rate-limit fallback was attempted
1198
+ # but no fallback preset/model is configured for the project.
1199
+ # Preferred input: NW_TELEGRAM_RATE_LIMIT_WEBHOOKS (JSON array with botToken/chatId).
1200
+ # Legacy fallback: NW_TELEGRAM_BOT_TOKEN + NW_TELEGRAM_CHAT_ID.
1201
+ # Usage: send_missing_fallback_configuration_warning <project_name>
1202
+ send_missing_fallback_configuration_warning() {
1203
+ local project_name="${1:-unknown}"
1204
+ local msg="⚠️ Rate Limit Fallback Unconfigured
1205
+
1206
+ Project: ${project_name}
1207
+ Rate-limit fallback was attempted, but no fallback preset/model is configured.
1208
+
1209
+ Configure one in Settings -> AI Providers -> Reliability & Fallbacks
1210
+ or set primaryFallbackPreset / primaryFallbackModel in night-watch.config.json."
1211
+
1212
+ # Preferred path: iterate all opted-in Telegram webhooks.
1213
+ if [ -n "${NW_TELEGRAM_RATE_LIMIT_WEBHOOKS:-}" ] && command -v jq >/dev/null 2>&1; then
1214
+ local sent=0
1215
+ local webhook_json
1216
+ while IFS= read -r webhook_json; do
1217
+ [ -z "${webhook_json}" ] && continue
1218
+ local bot_token
1219
+ local chat_id
1220
+ bot_token=$(printf '%s' "${webhook_json}" | jq -r '.botToken // empty' 2>/dev/null || true)
1221
+ chat_id=$(printf '%s' "${webhook_json}" | jq -r '.chatId // empty' 2>/dev/null || true)
1222
+ if [ -n "${bot_token}" ] && [ -n "${chat_id}" ]; then
1223
+ curl -s -X POST "https://api.telegram.org/bot${bot_token}/sendMessage" \
1224
+ --data-urlencode "chat_id=${chat_id}" \
1225
+ --data-urlencode "text=${msg}" > /dev/null 2>&1 || true
1226
+ sent=1
1227
+ fi
1228
+ done < <(printf '%s' "${NW_TELEGRAM_RATE_LIMIT_WEBHOOKS}" | jq -c '.[]?' 2>/dev/null || true)
1229
+
1230
+ if [ "${sent}" -eq 1 ]; then
1231
+ return 0
1232
+ fi
1233
+ fi
1234
+
1235
+ # Legacy single-webhook fallback.
1236
+ if [ -z "${NW_TELEGRAM_BOT_TOKEN:-}" ] || [ -z "${NW_TELEGRAM_CHAT_ID:-}" ]; then
1237
+ return 0
1238
+ fi
1239
+ curl -s -X POST "https://api.telegram.org/bot${NW_TELEGRAM_BOT_TOKEN}/sendMessage" \
1240
+ --data-urlencode "chat_id=${NW_TELEGRAM_CHAT_ID}" \
1241
+ --data-urlencode "text=${msg}" > /dev/null 2>&1 || true
1242
+ }
1243
+
1172
1244
  # ── Board mode issue discovery ────────────────────────────────────────────────
1173
1245
 
1174
1246
  # Get the next eligible issue from the board provider.
@@ -881,6 +881,12 @@ if [ -n "${TARGET_PR}" ]; then
881
881
  fi
882
882
  REVIEW_WORKTREE_DIR="$(dirname "${PROJECT_DIR}")/${REVIEW_WORKTREE_BASENAME}"
883
883
 
884
+ cleanup_reviewer_runner_worktree_on_exit() {
885
+ cleanup_worktree_path "${PROJECT_DIR}" "${REVIEW_WORKTREE_DIR}"
886
+ }
887
+
888
+ append_exit_trap "cleanup_reviewer_runner_worktree_on_exit"
889
+
884
890
  cleanup_reviewer_worktrees "${REVIEW_WORKTREE_BASENAME}"
885
891
 
886
892
  # Dry-run mode: print diagnostics and exit
@@ -995,7 +1001,20 @@ TOTAL_ATTEMPTS=1
995
1001
  if [ -n "${TARGET_PR}" ]; then
996
1002
  TOTAL_ATTEMPTS=$((REVIEWER_MAX_RETRIES + 1))
997
1003
  fi
998
- RUN_STARTED_AT=$(date +%s)
1004
+
1005
+ epoch_millis() {
1006
+ local now_ms
1007
+
1008
+ now_ms=$(date +%s%3N 2>/dev/null || true)
1009
+ if [[ "${now_ms}" =~ ^[0-9]+$ ]]; then
1010
+ printf "%s" "${now_ms}"
1011
+ return 0
1012
+ fi
1013
+
1014
+ printf "%s000" "$(date +%s)"
1015
+ }
1016
+
1017
+ RUN_STARTED_AT_MS=$(epoch_millis)
999
1018
 
1000
1019
  # Capture current HEAD of PR branch so we can detect if the reviewer pushed any commits.
1001
1020
  PR_BRANCH_HEAD_BEFORE=""
@@ -1004,13 +1023,22 @@ if [ -n "${TARGET_PR}" ]; then
1004
1023
  fi
1005
1024
 
1006
1025
  remaining_runtime_budget() {
1007
- local now_ts
1008
- local elapsed
1026
+ local now_ms
1027
+ local elapsed_ms
1028
+ local remaining_ms
1009
1029
  local remaining
1010
1030
 
1011
- now_ts=$(date +%s)
1012
- elapsed=$((now_ts - RUN_STARTED_AT))
1013
- remaining=$((MAX_RUNTIME - elapsed))
1031
+ now_ms=$(epoch_millis)
1032
+ elapsed_ms=$((now_ms - RUN_STARTED_AT_MS))
1033
+ remaining_ms=$((MAX_RUNTIME * 1000 - elapsed_ms))
1034
+ if [ "${remaining_ms}" -le 0 ]; then
1035
+ printf "0"
1036
+ return 0
1037
+ fi
1038
+
1039
+ # Round up to avoid shaving nearly a full second off attempt 1 when the
1040
+ # script crosses a wall-clock second boundary before entering `timeout`.
1041
+ remaining=$(( (remaining_ms + 999) / 1000 ))
1014
1042
  printf "%s" "${remaining}"
1015
1043
  }
1016
1044
 
@@ -1057,15 +1085,12 @@ for ATTEMPT in $(seq 1 "${TOTAL_ATTEMPTS}"); do
1057
1085
  # Retries only happen after a quick return (low score / invalid output / rate limit);
1058
1086
  # a timed-out provider run is not retried, so pre-splitting the budget would
1059
1087
  # incorrectly cap a 1h review to ~20m on attempt 1.
1060
- NOW_TS=$(date +%s)
1061
- ELAPSED=$((NOW_TS - RUN_STARTED_AT))
1062
- REMAINING_BUDGET=$((MAX_RUNTIME - ELAPSED))
1063
- if [ "${REMAINING_BUDGET}" -le 0 ]; then
1088
+ ATTEMPT_TIMEOUT=$(remaining_runtime_budget)
1089
+ if [ "${ATTEMPT_TIMEOUT}" -le 0 ]; then
1064
1090
  EXIT_CODE=124
1065
1091
  log "RETRY: Runtime budget exhausted before attempt ${ATTEMPT}"
1066
1092
  break
1067
1093
  fi
1068
- ATTEMPT_TIMEOUT="${REMAINING_BUDGET}"
1069
1094
  fi
1070
1095
 
1071
1096
  # Recreate worktree if it was removed unexpectedly between attempts.
@@ -481,6 +481,12 @@ else
481
481
  fi
482
482
  QA_WORKTREE_DIR="$(dirname "${PROJECT_DIR}")/${PROJECT_NAME}-nw-qa-runner"
483
483
 
484
+ cleanup_qa_worktree_on_exit() {
485
+ cleanup_worktree_path "${PROJECT_DIR}" "${QA_WORKTREE_DIR}"
486
+ }
487
+
488
+ append_exit_trap "cleanup_qa_worktree_on_exit"
489
+
484
490
  log "START: Found PR(s) needing QA:${PRS_NEEDING_QA}"
485
491
 
486
492
  cleanup_worktrees "${PROJECT_DIR}"
@@ -55,7 +55,9 @@
55
55
  "audit": 10
56
56
  }
57
57
  },
58
- "jobProviders": {},
58
+ "jobProviders": {
59
+ "reviewer": "g51claude"
60
+ },
59
61
  "autoMerge": false,
60
62
  "autoMergeMethod": "squash",
61
63
  "fallbackOnRateLimit": true,
@@ -73,5 +75,23 @@
73
75
  "enabled": true,
74
76
  "schedule": "50 3 * * 1",
75
77
  "maxRuntime": 1800
78
+ },
79
+ "providerPresets": {
80
+ "g51claude": {
81
+ "name": "GLM-5.1 Claude",
82
+ "command": "claude",
83
+ "promptFlag": "-p",
84
+ "autoApproveFlag": "--dangerously-skip-permissions",
85
+ "modelFlag": "--model",
86
+ "model": "glm-5.1",
87
+ "envVars": {
88
+ "ANTHROPIC_BASE_URL": "https://api.z.ai/api/anthropic",
89
+ "API_TIMEOUT_MS": "3000000",
90
+ "ANTHROPIC_DEFAULT_OPUS_MODEL": "glm-5.1",
91
+ "ANTHROPIC_DEFAULT_SONNET_MODEL": "glm-5.1",
92
+ "ANTHROPIC_AUTH_TOKEN": "efaeca456dab4ae69cb9ce1fa8d99a1a.KSTifNTWPS6NgC6L",
93
+ "ANTHROPIC_API_KEY": "efaeca456dab4ae69cb9ce1fa8d99a1a.KSTifNTWPS6NgC6L"
94
+ }
95
+ }
76
96
  }
77
97
  }