@jonit-dev/night-watch-cli 1.5.1 → 1.5.2

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.
@@ -15,12 +15,14 @@ PROJECT_DIR="${1:?Usage: $0 /path/to/project}"
15
15
  PROJECT_NAME=$(basename "${PROJECT_DIR}")
16
16
  LOG_DIR="${PROJECT_DIR}/logs"
17
17
  LOG_FILE="${LOG_DIR}/night-watch-pr-reviewer.log"
18
- LOCK_FILE="/tmp/night-watch-pr-reviewer-${PROJECT_NAME}.lock"
18
+ LOCK_FILE=""
19
19
  MAX_RUNTIME="${NW_REVIEWER_MAX_RUNTIME:-3600}" # 1 hour
20
20
  MAX_LOG_SIZE="524288" # 512 KB
21
21
  PROVIDER_CMD="${NW_PROVIDER_CMD:-claude}"
22
22
  MIN_REVIEW_SCORE="${NW_MIN_REVIEW_SCORE:-80}"
23
23
  BRANCH_PATTERNS_RAW="${NW_BRANCH_PATTERNS:-feat/,night-watch/}"
24
+ RUNTIME_MIRROR_DIR=""
25
+ RUNTIME_PROJECT_DIR=""
24
26
 
25
27
  # Ensure NVM / Node / Claude are on PATH
26
28
  export NVM_DIR="${HOME}/.nvm"
@@ -34,6 +36,8 @@ mkdir -p "${LOG_DIR}"
34
36
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
35
37
  # shellcheck source=night-watch-helpers.sh
36
38
  source "${SCRIPT_DIR}/night-watch-helpers.sh"
39
+ PROJECT_RUNTIME_KEY=$(project_runtime_key "${PROJECT_DIR}")
40
+ LOCK_FILE="/tmp/night-watch-pr-reviewer-${PROJECT_RUNTIME_KEY}.lock"
37
41
 
38
42
  # Validate provider
39
43
  if ! validate_provider "${PROVIDER_CMD}"; then
@@ -47,7 +51,37 @@ if ! acquire_lock "${LOCK_FILE}"; then
47
51
  exit 0
48
52
  fi
49
53
 
50
- cd "${PROJECT_DIR}"
54
+ cleanup_on_exit() {
55
+ rm -f "${LOCK_FILE}"
56
+
57
+ if [ -n "${RUNTIME_MIRROR_DIR}" ] && [ -n "${RUNTIME_PROJECT_DIR}" ]; then
58
+ cleanup_runtime_workspace "${RUNTIME_MIRROR_DIR}" "${RUNTIME_PROJECT_DIR}" || true
59
+ fi
60
+ }
61
+
62
+ trap cleanup_on_exit EXIT
63
+
64
+ if [ -n "${NW_DEFAULT_BRANCH:-}" ]; then
65
+ DEFAULT_BRANCH="${NW_DEFAULT_BRANCH}"
66
+ else
67
+ DEFAULT_BRANCH=$(detect_default_branch "${PROJECT_DIR}")
68
+ fi
69
+
70
+ runtime_info=()
71
+ if mapfile -t runtime_info < <(prepare_runtime_workspace "${PROJECT_DIR}" "${DEFAULT_BRANCH}" "${LOG_FILE}"); then
72
+ RUNTIME_MIRROR_DIR="${runtime_info[0]:-}"
73
+ RUNTIME_PROJECT_DIR="${runtime_info[1]:-}"
74
+ else
75
+ log "FAIL: Could not prepare runtime workspace for reviewer"
76
+ exit 1
77
+ fi
78
+
79
+ if [ -z "${RUNTIME_MIRROR_DIR}" ] || [ -z "${RUNTIME_PROJECT_DIR}" ]; then
80
+ log "FAIL: Runtime workspace paths are missing for reviewer"
81
+ exit 1
82
+ fi
83
+
84
+ cd "${RUNTIME_PROJECT_DIR}"
51
85
 
52
86
  # Convert comma-separated branch prefixes into a regex that matches branch starts.
53
87
  BRANCH_REGEX=""
@@ -122,38 +156,55 @@ fi
122
156
 
123
157
  log "START: Found PR(s) needing work:${PRS_NEEDING_WORK}"
124
158
 
125
- cleanup_worktrees "${PROJECT_DIR}"
126
-
127
159
  # Dry-run mode: print diagnostics and exit
128
160
  if [ "${NW_DRY_RUN:-0}" = "1" ]; then
129
161
  echo "=== Dry Run: PR Reviewer ==="
130
162
  echo "Provider: ${PROVIDER_CMD}"
131
163
  echo "Branch Patterns: ${BRANCH_PATTERNS_RAW}"
132
164
  echo "Min Review Score: ${MIN_REVIEW_SCORE}"
165
+ echo "Default Branch: ${DEFAULT_BRANCH}"
166
+ echo "Runtime Dir: ${RUNTIME_PROJECT_DIR}"
133
167
  echo "Open PRs needing work:${PRS_NEEDING_WORK}"
134
168
  echo "Timeout: ${MAX_RUNTIME}s"
135
169
  exit 0
136
170
  fi
137
171
 
172
+ if [ -f "${RUNTIME_PROJECT_DIR}/.claude/commands/night-watch-pr-reviewer.md" ]; then
173
+ REVIEW_WORKFLOW=$(cat "${RUNTIME_PROJECT_DIR}/.claude/commands/night-watch-pr-reviewer.md")
174
+ else
175
+ REVIEW_WORKFLOW=$(cat "${SCRIPT_DIR}/../templates/night-watch-pr-reviewer.md")
176
+ fi
177
+
178
+ REVIEW_PROMPT="You are running in an isolated runtime workspace at ${RUNTIME_PROJECT_DIR}.
179
+ Do not run git checkout/switch in ${PROJECT_DIR}.
180
+ Do not create or remove worktrees; the runtime controller handles that.
181
+ Apply all fixes only inside the current runtime workspace.
182
+
183
+ ${REVIEW_WORKFLOW}"
184
+
138
185
  EXIT_CODE=0
139
186
 
140
187
  case "${PROVIDER_CMD}" in
141
188
  claude)
142
- if timeout "${MAX_RUNTIME}" \
143
- claude -p "/night-watch-pr-reviewer" \
144
- --dangerously-skip-permissions \
145
- >> "${LOG_FILE}" 2>&1; then
189
+ if (
190
+ cd "${RUNTIME_PROJECT_DIR}" && timeout "${MAX_RUNTIME}" \
191
+ claude -p "${REVIEW_PROMPT}" \
192
+ --dangerously-skip-permissions \
193
+ >> "${LOG_FILE}" 2>&1
194
+ ); then
146
195
  EXIT_CODE=0
147
196
  else
148
197
  EXIT_CODE=$?
149
198
  fi
150
199
  ;;
151
200
  codex)
152
- if timeout "${MAX_RUNTIME}" \
153
- codex --quiet \
154
- --yolo \
155
- --prompt "$(cat "${PROJECT_DIR}/.claude/commands/night-watch-pr-reviewer.md")" \
156
- >> "${LOG_FILE}" 2>&1; then
201
+ if (
202
+ cd "${RUNTIME_PROJECT_DIR}" && timeout "${MAX_RUNTIME}" \
203
+ codex --quiet \
204
+ --yolo \
205
+ --prompt "${REVIEW_PROMPT}" \
206
+ >> "${LOG_FILE}" 2>&1
207
+ ); then
157
208
  EXIT_CODE=0
158
209
  else
159
210
  EXIT_CODE=$?
@@ -165,8 +216,6 @@ case "${PROVIDER_CMD}" in
165
216
  ;;
166
217
  esac
167
218
 
168
- cleanup_worktrees "${PROJECT_DIR}"
169
-
170
219
  if [ ${EXIT_CODE} -eq 0 ]; then
171
220
  log "DONE: PR reviewer completed successfully"
172
221
  elif [ ${EXIT_CODE} -eq 124 ]; then
@@ -67,18 +67,18 @@ A PR needs attention if **either** the review score is below 80 **or** any CI jo
67
67
 
68
68
  4. **Fix the PR**:
69
69
 
70
- a. **Check out the PR branch**:
70
+ a. **Use the pre-provisioned runtime workspace**:
71
+ - You are already running in an isolated runtime workspace.
72
+ - Do **not** run `git checkout`/`git switch` in the original project directory.
73
+ - Do **not** create/remove worktrees manually; the runtime controller handles isolation and cleanup.
74
+
75
+ b. **Check out the PR branch inside the runtime workspace**:
71
76
  ```
72
77
  git fetch origin
73
78
  git checkout <branch-name>
74
79
  git pull origin <branch-name>
75
80
  ```
76
-
77
- b. **Create a worktree** for the fixes:
78
- ```
79
- git worktree add ../${PROJECT_NAME}-nw-review-<branch-name> <branch-name>
80
- ```
81
- `cd` into worktree, run package install (npm install, yarn install, or pnpm install as appropriate).
81
+ Run package install (npm install, yarn install, or pnpm install as appropriate).
82
82
 
83
83
  c. **Address CI failures** (if any):
84
84
  - Read the failed job logs carefully to understand the root cause.
@@ -135,10 +135,6 @@ A PR needs attention if **either** the review score is below 80 **or** any CI jo
135
135
  Night Watch PR Reviewer"
136
136
  ```
137
137
 
138
- h. **Clean up worktree**: `git worktree remove ../${PROJECT_NAME}-nw-review-<branch-name>`
139
-
140
138
  5. **Repeat** for all open PRs that need work.
141
139
 
142
- 6. When done, return to ${DEFAULT_BRANCH}: `git checkout ${DEFAULT_BRANCH}`
143
-
144
140
  Start now. Check for open PRs that need review feedback addressed or CI failures fixed.
@@ -20,20 +20,13 @@ You are the Night Watch agent. Your job is to autonomously pick up PRD tickets a
20
20
 
21
21
  b. **Branch naming**: The branch MUST be named exactly `night-watch/<prd-filename-without-.md>`. Do NOT use `feat/`, `feature/`, or any other prefix. Example: for `health-check-endpoints.md` the branch is `night-watch/health-check-endpoints`.
22
22
 
23
- c. **Create a feature branch** from ${DEFAULT_BRANCH}:
23
+ c. **Use the pre-provisioned runtime workspace**:
24
+ - You are already running in an isolated runtime workspace.
25
+ - The target branch `night-watch/<prd-filename-without-.md>` is already prepared.
26
+ - Do **not** run `git checkout`/`git switch` in the original project directory.
27
+ - Do **not** create/remove worktrees manually; the runtime controller handles isolation and cleanup.
24
28
 
25
- ```
26
- git checkout ${DEFAULT_BRANCH} && git pull origin ${DEFAULT_BRANCH}
27
- git checkout -b night-watch/<prd-filename-without-.md>
28
- ```
29
-
30
- d. **Create a git worktree** for isolated work:
31
-
32
- ```
33
- git worktree add ../${PROJECT_NAME}-nw-<prd-name> night-watch/<prd-name>
34
- ```
35
-
36
- Then `cd` into the worktree and run package install (npm install, yarn install, or pnpm install as appropriate).
29
+ d. Install dependencies in the current runtime workspace (npm install, yarn install, or pnpm install as appropriate).
37
30
 
38
31
  e. **Implement the PRD using the PRD Executor workflow**:
39
32
  - Read `.claude/commands/prd-executor.md` and follow its full execution pipeline.
@@ -64,11 +57,9 @@ You are the Night Watch agent. Your job is to autonomously pick up PRD tickets a
64
57
  gh pr create --title "feat: <short title>" --body "<summary with PRD reference>"
65
58
  ```
66
59
 
67
- j. **Move PRD to done** (back in main repo on ${DEFAULT_BRANCH}):
60
+ j. **Move PRD to done**:
68
61
 
69
62
  ```
70
- cd ${PROJECT_DIR}
71
- git checkout ${DEFAULT_BRANCH}
72
63
  mkdir -p docs/PRDs/night-watch/done
73
64
  mv docs/PRDs/night-watch/<file>.md docs/PRDs/night-watch/done/
74
65
  ```
@@ -91,10 +82,8 @@ You are the Night Watch agent. Your job is to autonomously pick up PRD tickets a
91
82
 
92
83
  l. **Commit** the move + summary update, push ${DEFAULT_BRANCH}.
93
84
 
94
- m. **Clean up worktree**: `git worktree remove ../${PROJECT_NAME}-nw-<prd-name>`
95
-
96
- n. **STOP after this PRD**. Do NOT continue to the next PRD. One PRD per run prevents timeouts and reduces risk. The next cron trigger will pick up the next PRD.
85
+ m. **STOP after this PRD**. Do NOT continue to the next PRD. One PRD per run prevents timeouts and reduces risk. The next cron trigger will pick up the next PRD.
97
86
 
98
- 5. **On failure**: Do NOT move the PRD to done. Log the failure in NIGHT-WATCH-SUMMARY.md with status "Failed" and the reason. Clean up worktree and **stop** -- do not attempt the next PRD.
87
+ 5. **On failure**: Do NOT move the PRD to done. Log the failure in NIGHT-WATCH-SUMMARY.md with status "Failed" and the reason. The runtime controller handles cleanup. Then **stop** -- do not attempt the next PRD.
99
88
 
100
89
  Start now. Scan for available PRDs and process the first eligible one.