@jonit-dev/night-watch-cli 1.8.14-beta.2 → 1.8.14-beta.4

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.
@@ -79,6 +79,7 @@ skip_if_job_paused "${SCRIPT_TYPE}" "${PROJECT_DIR}"
79
79
  MERGED_PRS=0
80
80
  FAILED_PRS=0
81
81
  MERGED_PR_LIST=""
82
+ LAST_LOCAL_CHECK_OUTPUT=""
82
83
 
83
84
  emit_result() {
84
85
  local status="${1:?status required}"
@@ -318,15 +319,22 @@ run_local_check_command_in_dir() {
318
319
  local expected_head="${2}"
319
320
  local check_dir="${3}"
320
321
  local check_exit=1
322
+ local output_file=""
323
+
324
+ output_file=$(mktemp "${TMPDIR:-/tmp}/night-watch-merger-local-check-${pr_number}.XXXXXX")
325
+ LAST_LOCAL_CHECK_OUTPUT=""
321
326
 
322
327
  set +e
323
328
  (
324
329
  cd "${check_dir}"
325
330
  bash -lc "${LOCAL_CHECK_COMMAND}"
326
- ) 2>&1 | tee -a "${LOG_FILE}"
331
+ ) 2>&1 | tee "${output_file}" | tee -a "${LOG_FILE}"
327
332
  check_exit=${PIPESTATUS[0]}
328
333
  set -e
329
334
 
335
+ LAST_LOCAL_CHECK_OUTPUT=$(head -c 10000 "${output_file}" 2>/dev/null || true)
336
+ rm -f "${output_file}" 2>/dev/null || true
337
+
330
338
  if [ "${check_exit}" -eq 0 ]; then
331
339
  log "INFO: PR #${pr_number}: Local checks passed for head ${expected_head}"
332
340
  return 0
@@ -393,6 +401,45 @@ run_local_checks_for_head() {
393
401
  return "${check_result}"
394
402
  }
395
403
 
404
+ run_reviewer_repair_for_pr() {
405
+ local pr_number="${1}"
406
+ local pr_branch="${2}"
407
+ local expected_head="${3}"
408
+ local elapsed=0
409
+ local remaining=0
410
+ local reviewer_exit=1
411
+
412
+ elapsed=$(( $(date +%s) - SCRIPT_START_TIME ))
413
+ remaining=$(( MAX_RUNTIME - elapsed - 30 ))
414
+ if [ "${remaining}" -lt 120 ]; then
415
+ log "INFO: PR #${pr_number} (${pr_branch}): Not enough merger runtime left for targeted reviewer repair (${remaining}s), skipping repair"
416
+ return 1
417
+ fi
418
+
419
+ log "INFO: PR #${pr_number} (${pr_branch}): Running targeted reviewer repair after local check failure on head ${expected_head}"
420
+
421
+ set +e
422
+ (
423
+ NW_TARGET_PR="${pr_number}" \
424
+ NW_REVIEWER_WORKER_MODE="1" \
425
+ NW_REVIEWER_PARALLEL="0" \
426
+ NW_REVIEWER_MAX_RUNTIME="${remaining}" \
427
+ NW_TARGET_LOCAL_CHECK_COMMAND="${LOCAL_CHECK_COMMAND}" \
428
+ NW_TARGET_LOCAL_CHECK_OUTPUT="${LAST_LOCAL_CHECK_OUTPUT}" \
429
+ bash "${SCRIPT_DIR}/night-watch-pr-reviewer-cron.sh" "${PROJECT_DIR}"
430
+ ) 2>&1 | tee -a "${LOG_FILE}"
431
+ reviewer_exit=${PIPESTATUS[0]}
432
+ set -e
433
+
434
+ if [ "${reviewer_exit}" -eq 0 ]; then
435
+ log "INFO: PR #${pr_number} (${pr_branch}): Targeted reviewer repair completed"
436
+ return 0
437
+ fi
438
+
439
+ log "INFO: PR #${pr_number} (${pr_branch}): Targeted reviewer repair failed (exit ${reviewer_exit})"
440
+ return 1
441
+ }
442
+
396
443
  ci_gate_allows_head() {
397
444
  local pr_number="${1}"
398
445
  local pr_branch="${2}"
@@ -415,7 +462,17 @@ ci_gate_allows_head() {
415
462
  if run_local_checks_for_head "${pr_number}" "${pr_branch}" "${expected_head}"; then
416
463
  return 0
417
464
  fi
418
- log "INFO: PR #${pr_number} (${pr_branch}): Local check fallback failed, skipping"
465
+ if run_reviewer_repair_for_pr "${pr_number}" "${pr_branch}" "${expected_head}"; then
466
+ local repaired_head=""
467
+ repaired_head=$(get_pr_head_oid "${pr_number}")
468
+ if [ -n "${repaired_head}" ]; then
469
+ log "INFO: PR #${pr_number} (${pr_branch}): Re-checking local checks after targeted repair on head ${repaired_head}"
470
+ if run_local_checks_for_head "${pr_number}" "${pr_branch}" "${repaired_head}"; then
471
+ return 0
472
+ fi
473
+ fi
474
+ fi
475
+ log "INFO: PR #${pr_number} (${pr_branch}): Local check fallback failed after repair attempt, skipping"
419
476
  return 1
420
477
  fi
421
478
 
@@ -858,6 +858,17 @@ while IFS=$'\t' read -r pr_number pr_branch pr_labels; do
858
858
  continue
859
859
  fi
860
860
 
861
+ if [ -n "${TARGET_PR}" ] && [ "${pr_number}" = "${TARGET_PR}" ] && [ -n "${NW_TARGET_LOCAL_CHECK_COMMAND:-}" ]; then
862
+ if [ "${local_ready_for_review_label_present}" -eq 1 ]; then
863
+ log "INFO: PR #${pr_number} (${pr_branch}) failed merge-gate local checks; removing stale ${READY_FOR_REVIEW_LABEL} label"
864
+ clear_ready_for_human_review_label "${pr_number}"
865
+ fi
866
+ log "INFO: PR #${pr_number} (${pr_branch}) failed merge-gate local checks; targeted repair required"
867
+ NEEDS_WORK=1
868
+ PRS_NEEDING_WORK="${PRS_NEEDING_WORK} #${pr_number}"
869
+ continue
870
+ fi
871
+
861
872
  if has_ready_for_human_review_marker "${all_comments}" "${current_head_sha}"; then
862
873
  SKIPPED_ALREADY_REVIEWED_CURRENT_HEAD=1
863
874
  log "INFO: PR #${pr_number} (${pr_branch}) is already marked ready for human review at head ${current_head_sha:0:12}; skipping repeat automated review"
@@ -1202,6 +1213,15 @@ if [ -n "${TARGET_PR}" ]; then
1202
1213
  TARGET_SCOPE_PROMPT+=$'- latest review score: not found\n'
1203
1214
  TARGET_SCOPE_PROMPT+=$'- action: review\n'
1204
1215
  fi
1216
+ if [ -n "${NW_TARGET_LOCAL_CHECK_COMMAND:-}" ]; then
1217
+ TARGET_SCOPE_PROMPT+=$'\n## Local Check Failure From Merge Gate\n'
1218
+ TARGET_SCOPE_PROMPT+=$'- command: '"${NW_TARGET_LOCAL_CHECK_COMMAND}"$'\n'
1219
+ TARGET_SCOPE_PROMPT+=$'- action: fix the PR so this local command passes before the PR can merge\n'
1220
+ if [ -n "${NW_TARGET_LOCAL_CHECK_OUTPUT:-}" ]; then
1221
+ TRUNCATED_LOCAL_CHECK_OUTPUT=$(printf '%s' "${NW_TARGET_LOCAL_CHECK_OUTPUT}" | head -c 10000)
1222
+ TARGET_SCOPE_PROMPT+=$'\n### Local Check Output\n```text\n'"${TRUNCATED_LOCAL_CHECK_OUTPUT}"$'\n```\n'
1223
+ fi
1224
+ fi
1205
1225
  fi
1206
1226
 
1207
1227
  PRD_CONTEXT_PROMPT=""
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jonit-dev/night-watch-cli",
3
- "version": "1.8.14-beta.2",
3
+ "version": "1.8.14-beta.4",
4
4
  "description": "AI agent that implements your specs, opens PRs, and reviews code overnight. Queue GitHub issues or PRDs, wake up to pull requests.",
5
5
  "type": "module",
6
6
  "bin": {