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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
 
@@ -1202,6 +1202,15 @@ if [ -n "${TARGET_PR}" ]; then
1202
1202
  TARGET_SCOPE_PROMPT+=$'- latest review score: not found\n'
1203
1203
  TARGET_SCOPE_PROMPT+=$'- action: review\n'
1204
1204
  fi
1205
+ if [ -n "${NW_TARGET_LOCAL_CHECK_COMMAND:-}" ]; then
1206
+ TARGET_SCOPE_PROMPT+=$'\n## Local Check Failure From Merge Gate\n'
1207
+ TARGET_SCOPE_PROMPT+=$'- command: '"${NW_TARGET_LOCAL_CHECK_COMMAND}"$'\n'
1208
+ TARGET_SCOPE_PROMPT+=$'- action: fix the PR so this local command passes before the PR can merge\n'
1209
+ if [ -n "${NW_TARGET_LOCAL_CHECK_OUTPUT:-}" ]; then
1210
+ TRUNCATED_LOCAL_CHECK_OUTPUT=$(printf '%s' "${NW_TARGET_LOCAL_CHECK_OUTPUT}" | head -c 10000)
1211
+ TARGET_SCOPE_PROMPT+=$'\n### Local Check Output\n```text\n'"${TRUNCATED_LOCAL_CHECK_OUTPUT}"$'\n```\n'
1212
+ fi
1213
+ fi
1205
1214
  fi
1206
1215
 
1207
1216
  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.3",
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": {