@jonit-dev/night-watch-cli 1.7.45 → 1.7.47
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/dist/cli.js +8 -0
- package/dist/commands/audit.d.ts.map +1 -1
- package/dist/commands/audit.js +21 -1
- package/dist/commands/audit.js.map +1 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +20 -12
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/logs.d.ts.map +1 -1
- package/dist/commands/logs.js +37 -5
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/qa.d.ts.map +1 -1
- package/dist/commands/qa.js +20 -0
- package/dist/commands/qa.js.map +1 -1
- package/dist/commands/review.d.ts.map +1 -1
- package/dist/commands/review.js +4 -0
- package/dist/commands/review.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +12 -6
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/slice.d.ts.map +1 -1
- package/dist/commands/slice.js +88 -17
- package/dist/commands/slice.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +75 -0
- package/dist/commands/status.js.map +1 -1
- package/dist/scripts/night-watch-audit-cron.sh +19 -0
- package/dist/scripts/night-watch-cron.sh +9 -2
- package/dist/scripts/night-watch-helpers.sh +46 -0
- package/dist/scripts/night-watch-qa-cron.sh +19 -0
- package/dist/scripts/night-watch-slicer-cron.sh +10 -1
- package/dist/templates/night-watch-slicer.md +18 -3
- package/dist/templates/night-watch.config.json +1 -0
- package/dist/templates/night-watch.md +10 -37
- package/package.json +1 -1
|
@@ -58,6 +58,10 @@ if ! acquire_lock "${LOCK_FILE}"; then
|
|
|
58
58
|
exit 0
|
|
59
59
|
fi
|
|
60
60
|
|
|
61
|
+
send_telegram_status_message "🔎 Night Watch Auditor: started" "Project: ${PROJECT_NAME}
|
|
62
|
+
Provider: ${PROVIDER_CMD}
|
|
63
|
+
Running code quality audit."
|
|
64
|
+
|
|
61
65
|
# Dry-run mode: print diagnostics and exit
|
|
62
66
|
if [ "${NW_DRY_RUN:-0}" = "1" ]; then
|
|
63
67
|
echo "=== Dry Run: Code Auditor ==="
|
|
@@ -71,6 +75,9 @@ fi
|
|
|
71
75
|
|
|
72
76
|
if [ ! -f "${AUDIT_PROMPT_TEMPLATE}" ]; then
|
|
73
77
|
log "FAIL: Missing bundled audit prompt template at ${AUDIT_PROMPT_TEMPLATE}"
|
|
78
|
+
send_telegram_status_message "🔎 Night Watch Auditor: failed" "Project: ${PROJECT_NAME}
|
|
79
|
+
Missing prompt template:
|
|
80
|
+
${AUDIT_PROMPT_TEMPLATE}"
|
|
74
81
|
emit_result "failure_missing_prompt"
|
|
75
82
|
exit 1
|
|
76
83
|
fi
|
|
@@ -90,6 +97,8 @@ cleanup_worktrees "${PROJECT_DIR}" "${AUDIT_WORKTREE_BASENAME}"
|
|
|
90
97
|
|
|
91
98
|
if ! prepare_detached_worktree "${PROJECT_DIR}" "${AUDIT_WORKTREE_DIR}" "${DEFAULT_BRANCH}" "${LOG_FILE}"; then
|
|
92
99
|
log "FAIL: Unable to create isolated audit worktree ${AUDIT_WORKTREE_DIR}"
|
|
100
|
+
send_telegram_status_message "🔎 Night Watch Auditor: failed" "Project: ${PROJECT_NAME}
|
|
101
|
+
Failed to create audit worktree."
|
|
93
102
|
emit_result "failure" "reason=worktree_setup_failed"
|
|
94
103
|
exit 1
|
|
95
104
|
fi
|
|
@@ -146,22 +155,32 @@ cleanup_worktrees "${PROJECT_DIR}" "${AUDIT_WORKTREE_BASENAME}"
|
|
|
146
155
|
if [ "${EXIT_CODE}" -eq 0 ]; then
|
|
147
156
|
if [ ! -f "${REPORT_FILE}" ]; then
|
|
148
157
|
log "FAIL: Audit provider exited 0 but no report was generated at ${REPORT_FILE}"
|
|
158
|
+
send_telegram_status_message "🔎 Night Watch Auditor: failed" "Project: ${PROJECT_NAME}
|
|
159
|
+
Provider exited successfully but no report file was generated."
|
|
149
160
|
emit_result "failure_no_report"
|
|
150
161
|
exit 1
|
|
151
162
|
fi
|
|
152
163
|
|
|
153
164
|
if grep -q "NO_ISSUES_FOUND" "${REPORT_FILE}" 2>/dev/null; then
|
|
154
165
|
log "DONE: Audit complete — no actionable issues found"
|
|
166
|
+
send_telegram_status_message "🔎 Night Watch Auditor: complete (clean)" "Project: ${PROJECT_NAME}
|
|
167
|
+
No actionable issues found."
|
|
155
168
|
emit_result "skip_clean"
|
|
156
169
|
else
|
|
157
170
|
log "DONE: Audit complete — report written to ${REPORT_FILE}"
|
|
171
|
+
send_telegram_status_message "🔎 Night Watch Auditor: complete" "Project: ${PROJECT_NAME}
|
|
172
|
+
Report: ${REPORT_FILE}"
|
|
158
173
|
emit_result "success_audit"
|
|
159
174
|
fi
|
|
160
175
|
elif [ "${EXIT_CODE}" -eq 124 ]; then
|
|
161
176
|
log "TIMEOUT: Audit killed after ${MAX_RUNTIME}s"
|
|
177
|
+
send_telegram_status_message "🔎 Night Watch Auditor: timeout" "Project: ${PROJECT_NAME}
|
|
178
|
+
Timeout: ${MAX_RUNTIME}s"
|
|
162
179
|
emit_result "timeout"
|
|
163
180
|
else
|
|
164
181
|
log "FAIL: Audit exited with code ${EXIT_CODE}"
|
|
182
|
+
send_telegram_status_message "🔎 Night Watch Auditor: failed" "Project: ${PROJECT_NAME}
|
|
183
|
+
Exit code: ${EXIT_CODE}"
|
|
165
184
|
emit_result "failure" "provider_exit=${EXIT_CODE}"
|
|
166
185
|
fi
|
|
167
186
|
|
|
@@ -74,6 +74,13 @@ if ! acquire_lock "${LOCK_FILE}"; then
|
|
|
74
74
|
exit 0
|
|
75
75
|
fi
|
|
76
76
|
|
|
77
|
+
# Ensure all repo-scoped gh/night-watch commands run against this project.
|
|
78
|
+
if ! cd "${PROJECT_DIR}"; then
|
|
79
|
+
log "ERROR: Cannot access project directory ${PROJECT_DIR}"
|
|
80
|
+
emit_result "failure" "reason=invalid_project_dir"
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
83
|
+
|
|
77
84
|
cleanup_worktrees "${PROJECT_DIR}"
|
|
78
85
|
|
|
79
86
|
ISSUE_NUMBER="" # board mode: GitHub issue number
|
|
@@ -221,7 +228,7 @@ ${ISSUE_BODY}
|
|
|
221
228
|
- Install dependencies if needed and implement in the current worktree only
|
|
222
229
|
|
|
223
230
|
## Implementation — PRD Executor Workflow
|
|
224
|
-
Read .claude/commands/prd-executor.md and follow
|
|
231
|
+
Read .claude/skills/prd-executor/SKILL.md (preferred) or .claude/commands/prd-executor.md (fallback), and follow the FULL execution pipeline:
|
|
225
232
|
1. Parse the PRD into phases and extract dependencies
|
|
226
233
|
2. Build a dependency graph to identify parallelism
|
|
227
234
|
3. Create a task list with one task per phase
|
|
@@ -249,7 +256,7 @@ else
|
|
|
249
256
|
- Install dependencies if needed and implement in the current worktree only
|
|
250
257
|
|
|
251
258
|
## Implementation — PRD Executor Workflow
|
|
252
|
-
Read .claude/commands/prd-executor.md and follow
|
|
259
|
+
Read .claude/skills/prd-executor/SKILL.md (preferred) or .claude/commands/prd-executor.md (fallback), and follow the FULL execution pipeline:
|
|
253
260
|
1. Parse the PRD into phases and extract dependencies
|
|
254
261
|
2. Build a dependency graph to identify parallelism
|
|
255
262
|
3. Create a task list with one task per phase
|
|
@@ -445,6 +445,52 @@ check_rate_limited() {
|
|
|
445
445
|
fi
|
|
446
446
|
}
|
|
447
447
|
|
|
448
|
+
# Send a generic Telegram status message.
|
|
449
|
+
# Preferred input: NW_TELEGRAM_STATUS_WEBHOOKS (JSON array with botToken/chatId).
|
|
450
|
+
# Legacy fallback: NW_TELEGRAM_BOT_TOKEN + NW_TELEGRAM_CHAT_ID.
|
|
451
|
+
# Usage: send_telegram_status_message <title> [body]
|
|
452
|
+
send_telegram_status_message() {
|
|
453
|
+
local title="${1:-Night Watch}"
|
|
454
|
+
local body="${2:-}"
|
|
455
|
+
local msg="${title}"
|
|
456
|
+
if [ -n "${body}" ]; then
|
|
457
|
+
msg="${title}
|
|
458
|
+
|
|
459
|
+
${body}"
|
|
460
|
+
fi
|
|
461
|
+
|
|
462
|
+
# Preferred path: iterate all configured Telegram webhooks.
|
|
463
|
+
if [ -n "${NW_TELEGRAM_STATUS_WEBHOOKS:-}" ] && command -v jq >/dev/null 2>&1; then
|
|
464
|
+
local sent=0
|
|
465
|
+
local webhook_json
|
|
466
|
+
while IFS= read -r webhook_json; do
|
|
467
|
+
[ -z "${webhook_json}" ] && continue
|
|
468
|
+
local bot_token
|
|
469
|
+
local chat_id
|
|
470
|
+
bot_token=$(printf '%s' "${webhook_json}" | jq -r '.botToken // empty' 2>/dev/null || true)
|
|
471
|
+
chat_id=$(printf '%s' "${webhook_json}" | jq -r '.chatId // empty' 2>/dev/null || true)
|
|
472
|
+
if [ -n "${bot_token}" ] && [ -n "${chat_id}" ]; then
|
|
473
|
+
curl -s -X POST "https://api.telegram.org/bot${bot_token}/sendMessage" \
|
|
474
|
+
--data-urlencode "chat_id=${chat_id}" \
|
|
475
|
+
--data-urlencode "text=${msg}" > /dev/null 2>&1 || true
|
|
476
|
+
sent=1
|
|
477
|
+
fi
|
|
478
|
+
done < <(printf '%s' "${NW_TELEGRAM_STATUS_WEBHOOKS}" | jq -c '.[]?' 2>/dev/null || true)
|
|
479
|
+
|
|
480
|
+
if [ "${sent}" -eq 1 ]; then
|
|
481
|
+
return 0
|
|
482
|
+
fi
|
|
483
|
+
fi
|
|
484
|
+
|
|
485
|
+
# Legacy single-webhook fallback.
|
|
486
|
+
if [ -z "${NW_TELEGRAM_BOT_TOKEN:-}" ] || [ -z "${NW_TELEGRAM_CHAT_ID:-}" ]; then
|
|
487
|
+
return 0
|
|
488
|
+
fi
|
|
489
|
+
curl -s -X POST "https://api.telegram.org/bot${NW_TELEGRAM_BOT_TOKEN}/sendMessage" \
|
|
490
|
+
--data-urlencode "chat_id=${NW_TELEGRAM_CHAT_ID}" \
|
|
491
|
+
--data-urlencode "text=${msg}" > /dev/null 2>&1 || true
|
|
492
|
+
}
|
|
493
|
+
|
|
448
494
|
# Send an immediate Telegram warning when the rate-limit fallback is triggered.
|
|
449
495
|
# Preferred input: NW_TELEGRAM_RATE_LIMIT_WEBHOOKS (JSON array with botToken/chatId).
|
|
450
496
|
# Legacy fallback: NW_TELEGRAM_BOT_TOKEN + NW_TELEGRAM_CHAT_ID.
|
|
@@ -68,6 +68,10 @@ fi
|
|
|
68
68
|
|
|
69
69
|
cd "${PROJECT_DIR}"
|
|
70
70
|
|
|
71
|
+
send_telegram_status_message "🧪 Night Watch QA: started" "Project: ${PROJECT_NAME}
|
|
72
|
+
Provider: ${PROVIDER_CMD}
|
|
73
|
+
Scanning open PRs for QA candidates."
|
|
74
|
+
|
|
71
75
|
# Convert comma-separated branch prefixes into a regex that matches branch starts.
|
|
72
76
|
BRANCH_REGEX=""
|
|
73
77
|
IFS=',' read -r -a BRANCH_PATTERNS <<< "${BRANCH_PATTERNS_RAW}"
|
|
@@ -96,6 +100,8 @@ OPEN_PRS=$(
|
|
|
96
100
|
|
|
97
101
|
if [ "${OPEN_PRS}" -eq 0 ]; then
|
|
98
102
|
log "SKIP: No open PRs matching branch patterns (${BRANCH_PATTERNS_RAW})"
|
|
103
|
+
send_telegram_status_message "🧪 Night Watch QA: no matching PRs" "Project: ${PROJECT_NAME}
|
|
104
|
+
Branch patterns: ${BRANCH_PATTERNS_RAW}"
|
|
99
105
|
emit_result "skip_no_open_prs"
|
|
100
106
|
exit 0
|
|
101
107
|
fi
|
|
@@ -151,6 +157,8 @@ done < <(
|
|
|
151
157
|
|
|
152
158
|
if [ "${QA_NEEDED}" -eq 0 ]; then
|
|
153
159
|
log "SKIP: All ${OPEN_PRS} open PR(s) matching patterns already have QA comments"
|
|
160
|
+
send_telegram_status_message "🧪 Night Watch QA: nothing to do" "Project: ${PROJECT_NAME}
|
|
161
|
+
All matching PRs already have QA results."
|
|
154
162
|
emit_result "skip_all_qa_done"
|
|
155
163
|
exit 0
|
|
156
164
|
fi
|
|
@@ -190,6 +198,9 @@ EXIT_CODE=0
|
|
|
190
198
|
# Process each PR that needs QA
|
|
191
199
|
for pr_ref in ${PRS_NEEDING_QA}; do
|
|
192
200
|
pr_num="${pr_ref#\#}"
|
|
201
|
+
send_telegram_status_message "🧪 Night Watch QA: processing PR #${pr_num}" "Project: ${PROJECT_NAME}
|
|
202
|
+
Provider: ${PROVIDER_CMD}
|
|
203
|
+
Artifacts: ${QA_ARTIFACTS}"
|
|
193
204
|
|
|
194
205
|
cleanup_worktrees "${PROJECT_DIR}"
|
|
195
206
|
if ! prepare_detached_worktree "${PROJECT_DIR}" "${QA_WORKTREE_DIR}" "${DEFAULT_BRANCH}" "${LOG_FILE}"; then
|
|
@@ -257,6 +268,8 @@ cleanup_worktrees "${PROJECT_DIR}"
|
|
|
257
268
|
|
|
258
269
|
if [ ${EXIT_CODE} -eq 0 ]; then
|
|
259
270
|
log "DONE: QA runner completed successfully"
|
|
271
|
+
send_telegram_status_message "🧪 Night Watch QA: completed" "Project: ${PROJECT_NAME}
|
|
272
|
+
Processed PRs: ${PRS_NEEDING_QA_CSV}"
|
|
260
273
|
if [ -n "${REPO}" ]; then
|
|
261
274
|
emit_result "success_qa" "prs=${PRS_NEEDING_QA_CSV}|repo=${REPO}"
|
|
262
275
|
else
|
|
@@ -264,6 +277,9 @@ if [ ${EXIT_CODE} -eq 0 ]; then
|
|
|
264
277
|
fi
|
|
265
278
|
elif [ ${EXIT_CODE} -eq 124 ]; then
|
|
266
279
|
log "TIMEOUT: QA runner killed after ${MAX_RUNTIME}s"
|
|
280
|
+
send_telegram_status_message "🧪 Night Watch QA: timeout" "Project: ${PROJECT_NAME}
|
|
281
|
+
Timeout: ${MAX_RUNTIME}s
|
|
282
|
+
Processed PRs: ${PRS_NEEDING_QA_CSV}"
|
|
267
283
|
if [ -n "${REPO}" ]; then
|
|
268
284
|
emit_result "timeout" "prs=${PRS_NEEDING_QA_CSV}|repo=${REPO}"
|
|
269
285
|
else
|
|
@@ -271,6 +287,9 @@ elif [ ${EXIT_CODE} -eq 124 ]; then
|
|
|
271
287
|
fi
|
|
272
288
|
else
|
|
273
289
|
log "FAIL: QA runner exited with code ${EXIT_CODE}"
|
|
290
|
+
send_telegram_status_message "🧪 Night Watch QA: failed" "Project: ${PROJECT_NAME}
|
|
291
|
+
Exit code: ${EXIT_CODE}
|
|
292
|
+
Processed PRs: ${PRS_NEEDING_QA_CSV}"
|
|
274
293
|
if [ -n "${REPO}" ]; then
|
|
275
294
|
emit_result "failure" "prs=${PRS_NEEDING_QA_CSV}|repo=${REPO}"
|
|
276
295
|
else
|
|
@@ -17,7 +17,7 @@ set -euo pipefail
|
|
|
17
17
|
PROJECT_DIR="${1:?Usage: $0 /path/to/project}"
|
|
18
18
|
PROJECT_NAME=$(basename "${PROJECT_DIR}")
|
|
19
19
|
LOG_DIR="${PROJECT_DIR}/logs"
|
|
20
|
-
LOG_FILE="${LOG_DIR}/
|
|
20
|
+
LOG_FILE="${LOG_DIR}/slicer.log"
|
|
21
21
|
LOCK_FILE=""
|
|
22
22
|
MAX_RUNTIME="${NW_SLICER_MAX_RUNTIME:-600}" # 10 minutes
|
|
23
23
|
MAX_LOG_SIZE="524288" # 512 KB
|
|
@@ -54,6 +54,9 @@ cleanup_on_exit() {
|
|
|
54
54
|
trap cleanup_on_exit EXIT
|
|
55
55
|
|
|
56
56
|
log "START: Running roadmap slicer for ${PROJECT_DIR}"
|
|
57
|
+
send_telegram_status_message "📋 Night Watch Planner: started" "Project: ${PROJECT_NAME}
|
|
58
|
+
Provider: ${PROVIDER_CMD}
|
|
59
|
+
Planning next roadmap item into a PRD."
|
|
57
60
|
|
|
58
61
|
# Dry-run mode: print diagnostics and exit
|
|
59
62
|
if [ "${NW_DRY_RUN:-0}" = "1" ]; then
|
|
@@ -81,10 +84,16 @@ fi
|
|
|
81
84
|
|
|
82
85
|
if [ ${EXIT_CODE} -eq 0 ]; then
|
|
83
86
|
log "DONE: Slicer completed successfully"
|
|
87
|
+
send_telegram_status_message "📋 Night Watch Planner: completed" "Project: ${PROJECT_NAME}
|
|
88
|
+
PRD planning run finished successfully."
|
|
84
89
|
elif [ ${EXIT_CODE} -eq 124 ]; then
|
|
85
90
|
log "TIMEOUT: Slicer killed after ${MAX_RUNTIME}s"
|
|
91
|
+
send_telegram_status_message "📋 Night Watch Planner: timeout" "Project: ${PROJECT_NAME}
|
|
92
|
+
Timeout: ${MAX_RUNTIME}s"
|
|
86
93
|
else
|
|
87
94
|
log "FAIL: Slicer exited with code ${EXIT_CODE}"
|
|
95
|
+
send_telegram_status_message "📋 Night Watch Planner: failed" "Project: ${PROJECT_NAME}
|
|
96
|
+
Exit code: ${EXIT_CODE}"
|
|
88
97
|
fi
|
|
89
98
|
|
|
90
99
|
exit ${EXIT_CODE}
|
|
@@ -21,6 +21,8 @@ The PRD directory is: `{{PRD_DIR}}`
|
|
|
21
21
|
|
|
22
22
|
## Your Task
|
|
23
23
|
|
|
24
|
+
0. **Load Planner Skill** - Read and apply `.claude/skills/prd-creator/SKILL.md` before writing the PRD. If unavailable, continue with the instructions in this template.
|
|
25
|
+
|
|
24
26
|
1. **Explore the Codebase** - Read relevant existing files to understand the project structure, patterns, and conventions. Look for:
|
|
25
27
|
- CLAUDE.md or similar AI assistant documentation files
|
|
26
28
|
- Existing code patterns in the area you'll be modifying
|
|
@@ -61,7 +63,7 @@ COMPLEXITY SCORE (sum all that apply):
|
|
|
61
63
|
|
|
62
64
|
Your PRD MUST follow this exact structure:
|
|
63
65
|
|
|
64
|
-
|
|
66
|
+
````markdown
|
|
65
67
|
# PRD: [Title from roadmap item]
|
|
66
68
|
|
|
67
69
|
**Depends on:** [List any prerequisite PRDs/files, or omit if none]
|
|
@@ -77,24 +79,29 @@ Your PRD MUST follow this exact structure:
|
|
|
77
79
|
**Problem:** [1-2 sentences describing the issue being solved]
|
|
78
80
|
|
|
79
81
|
**Files Analyzed:**
|
|
82
|
+
|
|
80
83
|
- `path/to/file.ts` — [what the file does]
|
|
81
84
|
- [List all files you inspected before planning]
|
|
82
85
|
|
|
83
86
|
**Current Behavior:**
|
|
87
|
+
|
|
84
88
|
- [3-5 bullets describing current state]
|
|
85
89
|
|
|
86
90
|
### Integration Points Checklist
|
|
87
91
|
|
|
88
92
|
**How will this feature be reached?**
|
|
93
|
+
|
|
89
94
|
- [ ] Entry point identified: [e.g., route, event, cron, CLI command]
|
|
90
95
|
- [ ] Caller file identified: [file that will invoke this new code]
|
|
91
96
|
- [ ] Registration/wiring needed: [e.g., add route to router, register handler, add menu item]
|
|
92
97
|
|
|
93
98
|
**Is this user-facing?**
|
|
99
|
+
|
|
94
100
|
- [ ] YES → UI components required (list them)
|
|
95
101
|
- [ ] NO → Internal/background feature (explain how it's triggered)
|
|
96
102
|
|
|
97
103
|
**Full user flow:**
|
|
104
|
+
|
|
98
105
|
1. User does: [action]
|
|
99
106
|
2. Triggers: [what code path]
|
|
100
107
|
3. Reaches new feature via: [specific connection point]
|
|
@@ -105,6 +112,7 @@ Your PRD MUST follow this exact structure:
|
|
|
105
112
|
## 2. Solution
|
|
106
113
|
|
|
107
114
|
**Approach:**
|
|
115
|
+
|
|
108
116
|
- [3-5 bullets explaining the chosen solution]
|
|
109
117
|
|
|
110
118
|
**Architecture Diagram** <!-- (MEDIUM/HIGH complexity) -->:
|
|
@@ -113,8 +121,10 @@ Your PRD MUST follow this exact structure:
|
|
|
113
121
|
flowchart LR
|
|
114
122
|
A[Component A] --> B[Component B] --> C[Component C]
|
|
115
123
|
```
|
|
124
|
+
````
|
|
116
125
|
|
|
117
126
|
**Key Decisions:**
|
|
127
|
+
|
|
118
128
|
- [Library/framework choices, error-handling strategy, reused utilities]
|
|
119
129
|
|
|
120
130
|
**Data Changes:** [New schemas/migrations, or "None"]
|
|
@@ -140,6 +150,7 @@ sequenceDiagram
|
|
|
140
150
|
## 4. Execution Phases
|
|
141
151
|
|
|
142
152
|
**CRITICAL RULES:**
|
|
153
|
+
|
|
143
154
|
1. Each phase = ONE user-testable vertical slice
|
|
144
155
|
2. Max 5 files per phase (split if larger)
|
|
145
156
|
3. Each phase MUST include concrete tests
|
|
@@ -148,9 +159,11 @@ sequenceDiagram
|
|
|
148
159
|
### Phase 1: [Name] — [User-visible outcome in 1 sentence]
|
|
149
160
|
|
|
150
161
|
**Files (max 5):**
|
|
162
|
+
|
|
151
163
|
- `src/path/file.ts` — [what changes]
|
|
152
164
|
|
|
153
165
|
**Implementation:**
|
|
166
|
+
|
|
154
167
|
- [ ] Step 1
|
|
155
168
|
- [ ] Step 2
|
|
156
169
|
|
|
@@ -160,6 +173,7 @@ sequenceDiagram
|
|
|
160
173
|
| `src/__tests__/feature.test.ts` | `should do X when Y` | `expect(result).toBe(Z)` |
|
|
161
174
|
|
|
162
175
|
**Verification Plan:**
|
|
176
|
+
|
|
163
177
|
1. **Unit Tests:** File and test names
|
|
164
178
|
2. **Integration Test:** (if applicable)
|
|
165
179
|
3. **User Verification:**
|
|
@@ -183,7 +197,8 @@ sequenceDiagram
|
|
|
183
197
|
- [ ] Feature is reachable (entry point connected, not orphaned code)
|
|
184
198
|
- [ ] [additional criterion specific to this feature]
|
|
185
199
|
- [ ] [additional criterion specific to this feature]
|
|
186
|
-
|
|
200
|
+
|
|
201
|
+
````
|
|
187
202
|
|
|
188
203
|
---
|
|
189
204
|
|
|
@@ -216,4 +231,4 @@ After writing the PRD file, report:
|
|
|
216
231
|
|
|
217
232
|
### Summary
|
|
218
233
|
[1-2 sentences summarizing the PRD content]
|
|
219
|
-
|
|
234
|
+
````
|
|
@@ -2,9 +2,9 @@ You are the Night Watch agent. Your job is to autonomously pick up PRD tickets a
|
|
|
2
2
|
|
|
3
3
|
## Instructions
|
|
4
4
|
|
|
5
|
-
1. **Scan for PRDs**:
|
|
5
|
+
1. **Scan for PRDs**: Use `night-watch prd list --json` to get available PRDs. Each PRD is a ticket.
|
|
6
6
|
|
|
7
|
-
2. **Check dependencies**:
|
|
7
|
+
2. **Check dependencies**: For each PRD, verify its dependencies are satisfied (depended-on PRD is marked as done). Skip PRDs with unmet dependencies.
|
|
8
8
|
|
|
9
9
|
3. **Check for already-in-progress PRDs**: Before processing any PRD, check if a PR already exists for it:
|
|
10
10
|
|
|
@@ -30,11 +30,11 @@ You are the Night Watch agent. Your job is to autonomously pick up PRD tickets a
|
|
|
30
30
|
d. `cd` into the worktree and run package install (npm install, yarn install, or pnpm install as appropriate). Keep all implementation steps inside this worktree.
|
|
31
31
|
|
|
32
32
|
e. **Implement the PRD using the PRD Executor workflow**:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
- Read `.claude/skills/prd-executor/SKILL.md` (preferred) or `.claude/commands/prd-executor.md` (fallback), and follow the full execution pipeline.
|
|
34
|
+
- This means: parse the PRD phases, build a dependency graph, create a task list, and execute phases in parallel waves using agent swarms.
|
|
35
|
+
- Maximize parallelism — launch all independent phases concurrently.
|
|
36
|
+
- Run the project's verify/test command between waves to catch issues early.
|
|
37
|
+
- Follow all project conventions from AI assistant documentation files (e.g., CLAUDE.md, AGENTS.md, or similar).
|
|
38
38
|
|
|
39
39
|
f. **Write tests** as specified in each PRD phase (the prd-executor agents handle this per-phase).
|
|
40
40
|
|
|
@@ -58,37 +58,10 @@ You are the Night Watch agent. Your job is to autonomously pick up PRD tickets a
|
|
|
58
58
|
gh pr create --title "feat: <short title>" --body "<summary with PRD reference>"
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
j. **
|
|
61
|
+
j. **Mark PRD as done**: `night-watch prd done <filename>`
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
cd ${PROJECT_DIR}
|
|
65
|
-
git checkout ${DEFAULT_BRANCH}
|
|
66
|
-
mkdir -p docs/PRDs/night-watch/done
|
|
67
|
-
mv docs/PRDs/night-watch/<file>.md docs/PRDs/night-watch/done/
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
k. **Update summary**: Append to `docs/PRDs/night-watch/NIGHT-WATCH-SUMMARY.md`:
|
|
71
|
-
|
|
72
|
-
```
|
|
73
|
-
## <Title>
|
|
74
|
-
- **PRD**: <filename>
|
|
75
|
-
- **Branch**: night-watch/<name>
|
|
76
|
-
- **PR**: <url>
|
|
77
|
-
- **Date**: <YYYY-MM-DD>
|
|
78
|
-
- **Status**: PR Opened
|
|
79
|
-
### What was done
|
|
80
|
-
<bullet points>
|
|
81
|
-
### Files changed
|
|
82
|
-
<list>
|
|
83
|
-
---
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
l. **Commit** the move + summary update, push ${DEFAULT_BRANCH}.
|
|
87
|
-
|
|
88
|
-
m. **Clean up worktree**: `git worktree remove ../${PROJECT_NAME}-nw-<prd-name>`
|
|
89
|
-
|
|
90
|
-
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.
|
|
63
|
+
k. **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.
|
|
91
64
|
|
|
92
|
-
5. **On failure**: Do NOT
|
|
65
|
+
5. **On failure**: Do NOT mark the PRD as done. Log the failure and clean up worktree. **Stop** -- do not attempt the next PRD.
|
|
93
66
|
|
|
94
67
|
Start now. Scan for available PRDs and process the first eligible one.
|