@jonit-dev/night-watch-cli 1.5.9 → 1.7.0

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 (100) hide show
  1. package/dist/cli.js +6 -0
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/init.d.ts +13 -0
  4. package/dist/commands/init.d.ts.map +1 -1
  5. package/dist/commands/init.js +39 -11
  6. package/dist/commands/init.js.map +1 -1
  7. package/dist/commands/install.d.ts +2 -0
  8. package/dist/commands/install.d.ts.map +1 -1
  9. package/dist/commands/install.js +23 -0
  10. package/dist/commands/install.js.map +1 -1
  11. package/dist/commands/slice.d.ts +26 -0
  12. package/dist/commands/slice.d.ts.map +1 -0
  13. package/dist/commands/slice.js +175 -0
  14. package/dist/commands/slice.js.map +1 -0
  15. package/dist/commands/state.d.ts +8 -0
  16. package/dist/commands/state.d.ts.map +1 -0
  17. package/dist/commands/state.js +56 -0
  18. package/dist/commands/state.js.map +1 -0
  19. package/dist/commands/uninstall.js +2 -2
  20. package/dist/commands/uninstall.js.map +1 -1
  21. package/dist/config.d.ts.map +1 -1
  22. package/dist/config.js +32 -1
  23. package/dist/config.js.map +1 -1
  24. package/dist/constants.d.ts +4 -0
  25. package/dist/constants.d.ts.map +1 -1
  26. package/dist/constants.js +7 -0
  27. package/dist/constants.js.map +1 -1
  28. package/dist/server/index.d.ts.map +1 -1
  29. package/dist/server/index.js +11 -13
  30. package/dist/server/index.js.map +1 -1
  31. package/dist/storage/json-state-migrator.d.ts +24 -0
  32. package/dist/storage/json-state-migrator.d.ts.map +1 -0
  33. package/dist/storage/json-state-migrator.js +197 -0
  34. package/dist/storage/json-state-migrator.js.map +1 -0
  35. package/dist/storage/repositories/index.d.ts +23 -0
  36. package/dist/storage/repositories/index.d.ts.map +1 -0
  37. package/dist/storage/repositories/index.js +37 -0
  38. package/dist/storage/repositories/index.js.map +1 -0
  39. package/dist/storage/repositories/interfaces.d.ts +37 -0
  40. package/dist/storage/repositories/interfaces.d.ts.map +1 -0
  41. package/dist/storage/repositories/interfaces.js +6 -0
  42. package/dist/storage/repositories/interfaces.js.map +1 -0
  43. package/dist/storage/repositories/sqlite/execution-history-repository.d.ts +21 -0
  44. package/dist/storage/repositories/sqlite/execution-history-repository.d.ts.map +1 -0
  45. package/dist/storage/repositories/sqlite/execution-history-repository.js +94 -0
  46. package/dist/storage/repositories/sqlite/execution-history-repository.js.map +1 -0
  47. package/dist/storage/repositories/sqlite/prd-state-repository.d.ts +17 -0
  48. package/dist/storage/repositories/sqlite/prd-state-repository.d.ts.map +1 -0
  49. package/dist/storage/repositories/sqlite/prd-state-repository.js +74 -0
  50. package/dist/storage/repositories/sqlite/prd-state-repository.js.map +1 -0
  51. package/dist/storage/repositories/sqlite/project-registry-repository.d.ts +16 -0
  52. package/dist/storage/repositories/sqlite/project-registry-repository.d.ts.map +1 -0
  53. package/dist/storage/repositories/sqlite/project-registry-repository.js +34 -0
  54. package/dist/storage/repositories/sqlite/project-registry-repository.js.map +1 -0
  55. package/dist/storage/repositories/sqlite/roadmap-state-repository.d.ts +14 -0
  56. package/dist/storage/repositories/sqlite/roadmap-state-repository.d.ts.map +1 -0
  57. package/dist/storage/repositories/sqlite/roadmap-state-repository.js +47 -0
  58. package/dist/storage/repositories/sqlite/roadmap-state-repository.js.map +1 -0
  59. package/dist/storage/sqlite/client.d.ts +23 -0
  60. package/dist/storage/sqlite/client.d.ts.map +1 -0
  61. package/dist/storage/sqlite/client.js +47 -0
  62. package/dist/storage/sqlite/client.js.map +1 -0
  63. package/dist/storage/sqlite/migrations.d.ts +11 -0
  64. package/dist/storage/sqlite/migrations.d.ts.map +1 -0
  65. package/dist/storage/sqlite/migrations.js +57 -0
  66. package/dist/storage/sqlite/migrations.js.map +1 -0
  67. package/dist/templates/slicer-prompt.d.ts +54 -0
  68. package/dist/templates/slicer-prompt.d.ts.map +1 -0
  69. package/dist/templates/slicer-prompt.js +163 -0
  70. package/dist/templates/slicer-prompt.js.map +1 -0
  71. package/dist/types.d.ts +6 -0
  72. package/dist/types.d.ts.map +1 -1
  73. package/dist/utils/execution-history.d.ts +11 -5
  74. package/dist/utils/execution-history.d.ts.map +1 -1
  75. package/dist/utils/execution-history.js +27 -130
  76. package/dist/utils/execution-history.js.map +1 -1
  77. package/dist/utils/prd-states.d.ts +1 -2
  78. package/dist/utils/prd-states.d.ts.map +1 -1
  79. package/dist/utils/prd-states.js +10 -42
  80. package/dist/utils/prd-states.js.map +1 -1
  81. package/dist/utils/registry.d.ts +9 -4
  82. package/dist/utils/registry.d.ts.map +1 -1
  83. package/dist/utils/registry.js +21 -33
  84. package/dist/utils/registry.js.map +1 -1
  85. package/dist/utils/roadmap-scanner.d.ts +34 -2
  86. package/dist/utils/roadmap-scanner.d.ts.map +1 -1
  87. package/dist/utils/roadmap-scanner.js +218 -105
  88. package/dist/utils/roadmap-scanner.js.map +1 -1
  89. package/dist/utils/roadmap-state.d.ts +13 -6
  90. package/dist/utils/roadmap-state.d.ts.map +1 -1
  91. package/dist/utils/roadmap-state.js +50 -27
  92. package/dist/utils/roadmap-state.js.map +1 -1
  93. package/package.json +9 -4
  94. package/scripts/night-watch-cron.sh +65 -24
  95. package/scripts/night-watch-slicer-cron.sh +90 -0
  96. package/templates/night-watch-slicer.md +219 -0
  97. package/templates/night-watch.config.json +1 -0
  98. package/web/dist/assets/{index-CP0r6Epl.js → index-D4AfwSvr.js} +52 -52
  99. package/web/dist/assets/index-Dx_ZY5CY.css +1 -0
  100. package/web/dist/index.html +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jonit-dev/night-watch-cli",
3
- "version": "1.5.9",
3
+ "version": "1.7.0",
4
4
  "description": "Autonomous PRD execution using AI Provider CLIs + cron",
5
5
  "type": "module",
6
6
  "bin": {
@@ -19,6 +19,9 @@
19
19
  "build:cli": "tsc",
20
20
  "test": "vitest run",
21
21
  "dev": "tsx src/cli.ts",
22
+ "dev:sandbox": "NIGHT_WATCH_HOME=/tmp/nw-sandbox tsx src/cli.ts",
23
+ "dev:sandbox:inspect": "sqlite3 /tmp/nw-sandbox/state.db",
24
+ "dev:sandbox:reset": "rm -rf /tmp/nw-sandbox && echo 'Sandbox cleared'",
22
25
  "dev:web": "concurrently --names \"api,vite\" --prefix-colors \"cyan,magenta\" \"tsx src/cli.ts serve\" \"yarn --cwd web dev\"",
23
26
  "prepublishOnly": "npm run build && npm test",
24
27
  "publish:npm": "npm publish --access public",
@@ -54,6 +57,7 @@
54
57
  "url": "https://github.com/jonit-dev/night-watch-cli/issues"
55
58
  },
56
59
  "dependencies": {
60
+ "better-sqlite3": "^12.6.2",
57
61
  "blessed": "^0.1.81",
58
62
  "chalk": "^5.6.2",
59
63
  "cli-table3": "^0.6.5",
@@ -66,10 +70,11 @@
66
70
  },
67
71
  "devDependencies": {
68
72
  "@eslint/js": "^10.0.1",
73
+ "@types/better-sqlite3": "^7.6.13",
69
74
  "@types/blessed": "^0.1.27",
70
75
  "@types/cors": "^2.8.19",
71
76
  "@types/express": "^5.0.6",
72
- "@types/node": "^20.11.0",
77
+ "@types/node": "^22.0.0",
73
78
  "@types/supertest": "^6.0.3",
74
79
  "concurrently": "^9.2.1",
75
80
  "eslint": "^10.0.0",
@@ -77,9 +82,9 @@
77
82
  "tsx": "^4.7.0",
78
83
  "typescript": "^5.3.0",
79
84
  "typescript-eslint": "^8.56.0",
80
- "vitest": "^1.2.0"
85
+ "vitest": "^4.0.0"
81
86
  },
82
87
  "engines": {
83
- "node": ">=18.0.0"
88
+ "node": ">=22.0.0"
84
89
  }
85
90
  }
@@ -84,6 +84,48 @@ else
84
84
  BOOKKEEP_PRD_DIR="${BOOKKEEP_WORKTREE_DIR}/${PRD_DIR_REL}"
85
85
  fi
86
86
 
87
+ count_prs_for_branch() {
88
+ local pr_state="${1:?pr_state required}"
89
+ local branch_name="${2:?branch_name required}"
90
+ local count
91
+ count=$(
92
+ { gh pr list --state "${pr_state}" --json headRefName --jq '.[].headRefName' 2>/dev/null || true; } \
93
+ | { grep -xF "${branch_name}" || true; } \
94
+ | wc -l \
95
+ | tr -d '[:space:]'
96
+ )
97
+ echo "${count:-0}"
98
+ }
99
+
100
+ finalize_prd_done() {
101
+ local reason="${1:?reason required}"
102
+
103
+ release_claim "${PRD_DIR}" "${ELIGIBLE_PRD}"
104
+ # NOTE: PRDs are moved to done/ immediately when a PR is opened (or already merged)
105
+ # rather than waiting for reviewer/merge loops.
106
+ if prepare_detached_worktree "${PROJECT_DIR}" "${BOOKKEEP_WORKTREE_DIR}" "${DEFAULT_BRANCH}" "${LOG_FILE}"; then
107
+ if mark_prd_done "${BOOKKEEP_PRD_DIR}" "${ELIGIBLE_PRD}"; then
108
+ night_watch_history record "${PROJECT_DIR}" "${ELIGIBLE_PRD}" success --exit-code 0 2>/dev/null || true
109
+ if [[ "${PRD_DIR_REL}" = /* ]]; then
110
+ git -C "${BOOKKEEP_WORKTREE_DIR}" add -A "${PRD_DIR_REL}" || true
111
+ else
112
+ git -C "${BOOKKEEP_WORKTREE_DIR}" add -A "${PRD_DIR_REL}/" || true
113
+ fi
114
+ git -C "${BOOKKEEP_WORKTREE_DIR}" commit -m "chore: mark ${ELIGIBLE_PRD} as done (${reason})
115
+
116
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>" || true
117
+ git -C "${BOOKKEEP_WORKTREE_DIR}" push origin "HEAD:${DEFAULT_BRANCH}" || true
118
+ log "DONE: ${ELIGIBLE_PRD} ${reason}, PRD moved to done/"
119
+ return 0
120
+ fi
121
+ log "WARN: Failed to move ${ELIGIBLE_PRD} to done/ in bookkeeping worktree"
122
+ return 1
123
+ fi
124
+
125
+ log "WARN: Unable to prepare bookkeeping worktree for ${ELIGIBLE_PRD}"
126
+ return 1
127
+ }
128
+
87
129
  log "START: Processing ${ELIGIBLE_PRD} on branch ${BRANCH_NAME} (worktree: ${WORKTREE_DIR})"
88
130
 
89
131
  PROMPT="Implement the PRD at docs/PRDs/night-watch/${ELIGIBLE_PRD}
@@ -127,6 +169,17 @@ if [ "${NW_DRY_RUN:-0}" = "1" ]; then
127
169
  exit 0
128
170
  fi
129
171
 
172
+ # If this PRD already has a merged PR for its branch, finalize it immediately.
173
+ MERGED_PR_COUNT=$(count_prs_for_branch merged "${BRANCH_NAME}")
174
+ if [ "${MERGED_PR_COUNT}" -gt 0 ]; then
175
+ log "INFO: Found merged PR for ${BRANCH_NAME}; skipping provider run"
176
+ if finalize_prd_done "already merged on ${BRANCH_NAME}"; then
177
+ exit 0
178
+ fi
179
+ night_watch_history record "${PROJECT_DIR}" "${ELIGIBLE_PRD}" failure --exit-code 1 2>/dev/null || true
180
+ exit 1
181
+ fi
182
+
130
183
  if ! prepare_branch_worktree "${PROJECT_DIR}" "${WORKTREE_DIR}" "${BRANCH_NAME}" "${DEFAULT_BRANCH}" "${LOG_FILE}"; then
131
184
  log "FAIL: Unable to create isolated worktree ${WORKTREE_DIR} for ${BRANCH_NAME}"
132
185
  night_watch_history record "${PROJECT_DIR}" "${ELIGIBLE_PRD}" failure --exit-code 1 2>/dev/null || true
@@ -203,33 +256,21 @@ while [ "${ATTEMPT}" -lt "${MAX_RETRIES}" ]; do
203
256
  done
204
257
 
205
258
  if [ ${EXIT_CODE} -eq 0 ]; then
206
- PR_EXISTS=$(gh pr list --state open --json headRefName --jq '.[].headRefName' 2>/dev/null | grep -cF "${BRANCH_NAME}" || echo "0")
207
- if [ "${PR_EXISTS}" -gt 0 ]; then
208
- release_claim "${PRD_DIR}" "${ELIGIBLE_PRD}"
209
- # NOTE: PRDs are moved to done/ immediately when a PR is opened rather than waiting for
210
- # the PR to merge. This is intentional — once a PR exists, the agent's implementation
211
- # work is complete and it should not pick up this PRD again. Human review takes it from here.
212
- if prepare_detached_worktree "${PROJECT_DIR}" "${BOOKKEEP_WORKTREE_DIR}" "${DEFAULT_BRANCH}" "${LOG_FILE}"; then
213
- if mark_prd_done "${BOOKKEEP_PRD_DIR}" "${ELIGIBLE_PRD}"; then
214
- night_watch_history record "${PROJECT_DIR}" "${ELIGIBLE_PRD}" success --exit-code 0 2>/dev/null || true
215
- if [[ "${PRD_DIR_REL}" = /* ]]; then
216
- git -C "${BOOKKEEP_WORKTREE_DIR}" add -A "${PRD_DIR_REL}" || true
217
- else
218
- git -C "${BOOKKEEP_WORKTREE_DIR}" add -A "${PRD_DIR_REL}/" || true
219
- fi
220
- git -C "${BOOKKEEP_WORKTREE_DIR}" commit -m "chore: mark ${ELIGIBLE_PRD} as done (PR opened on ${BRANCH_NAME})
221
-
222
- Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>" || true
223
- git -C "${BOOKKEEP_WORKTREE_DIR}" push origin "HEAD:${DEFAULT_BRANCH}" || true
224
- log "DONE: ${ELIGIBLE_PRD} implemented, PR opened, PRD moved to done/"
225
- else
226
- log "WARN: Failed to move ${ELIGIBLE_PRD} to done/ in bookkeeping worktree"
259
+ OPEN_PR_COUNT=$(count_prs_for_branch open "${BRANCH_NAME}")
260
+ if [ "${OPEN_PR_COUNT}" -gt 0 ]; then
261
+ if ! finalize_prd_done "implemented, PR opened on ${BRANCH_NAME}"; then
262
+ night_watch_history record "${PROJECT_DIR}" "${ELIGIBLE_PRD}" failure --exit-code 1 2>/dev/null || true
263
+ fi
264
+ else
265
+ MERGED_PR_COUNT=$(count_prs_for_branch merged "${BRANCH_NAME}")
266
+ if [ "${MERGED_PR_COUNT}" -gt 0 ]; then
267
+ if ! finalize_prd_done "already merged on ${BRANCH_NAME}"; then
268
+ night_watch_history record "${PROJECT_DIR}" "${ELIGIBLE_PRD}" failure --exit-code 1 2>/dev/null || true
227
269
  fi
228
270
  else
229
- log "WARN: Unable to prepare bookkeeping worktree for ${ELIGIBLE_PRD}"
271
+ log "WARN: ${PROVIDER_CMD} exited 0 but no open/merged PR found on ${BRANCH_NAME} — recording cooldown to avoid repeated stuck runs"
272
+ night_watch_history record "${PROJECT_DIR}" "${ELIGIBLE_PRD}" failure --exit-code 1 2>/dev/null || true
230
273
  fi
231
- else
232
- log "WARN: ${PROVIDER_CMD} exited 0 but no PR found on ${BRANCH_NAME} — PRD NOT moved to done"
233
274
  fi
234
275
  elif [ ${EXIT_CODE} -eq 124 ]; then
235
276
  log "TIMEOUT: Night watch killed after ${MAX_RUNTIME}s while processing ${ELIGIBLE_PRD}"
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # Night Watch Slicer Cron Runner (project-agnostic)
5
+ # Usage: night-watch-slicer-cron.sh /path/to/project
6
+ #
7
+ # This is a thin wrapper that acquires a lock and calls `night-watch slice`.
8
+ # The CLI command handles all the logic directly in TypeScript.
9
+ #
10
+ # NOTE: This script expects environment variables to be set by the caller.
11
+ # The Node.js CLI will inject config values via environment variables.
12
+ # Required env vars (with defaults shown):
13
+ # NW_SLICER_MAX_RUNTIME=600 - Maximum runtime in seconds (10 minutes)
14
+ # NW_PROVIDER_CMD=claude - AI provider CLI to use (claude, codex, etc.)
15
+ # NW_DRY_RUN=0 - Set to 1 for dry-run mode (prints diagnostics only)
16
+
17
+ PROJECT_DIR="${1:?Usage: $0 /path/to/project}"
18
+ PROJECT_NAME=$(basename "${PROJECT_DIR}")
19
+ LOG_DIR="${PROJECT_DIR}/logs"
20
+ LOG_FILE="${LOG_DIR}/night-watch-slicer.log"
21
+ LOCK_FILE=""
22
+ MAX_RUNTIME="${NW_SLICER_MAX_RUNTIME:-600}" # 10 minutes
23
+ MAX_LOG_SIZE="524288" # 512 KB
24
+ PROVIDER_CMD="${NW_PROVIDER_CMD:-claude}"
25
+
26
+ # Ensure NVM / Node / Night Watch CLI are on PATH
27
+ export NVM_DIR="${HOME}/.nvm"
28
+ [ -s "${NVM_DIR}/nvm.sh" ] && . "${NVM_DIR}/nvm.sh"
29
+
30
+ mkdir -p "${LOG_DIR}"
31
+
32
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
33
+ # shellcheck source=night-watch-helpers.sh
34
+ source "${SCRIPT_DIR}/night-watch-helpers.sh"
35
+ PROJECT_RUNTIME_KEY=$(project_runtime_key "${PROJECT_DIR}")
36
+ LOCK_FILE="/tmp/night-watch-slicer-${PROJECT_RUNTIME_KEY}.lock"
37
+
38
+ # Validate provider
39
+ if ! validate_provider "${PROVIDER_CMD}"; then
40
+ echo "ERROR: Unknown provider: ${PROVIDER_CMD}" >&2
41
+ exit 1
42
+ fi
43
+
44
+ rotate_log
45
+
46
+ if ! acquire_lock "${LOCK_FILE}"; then
47
+ exit 0
48
+ fi
49
+
50
+ cleanup_on_exit() {
51
+ rm -f "${LOCK_FILE}"
52
+ }
53
+
54
+ trap cleanup_on_exit EXIT
55
+
56
+ log "START: Running roadmap slicer for ${PROJECT_DIR}"
57
+
58
+ # Dry-run mode: print diagnostics and exit
59
+ if [ "${NW_DRY_RUN:-0}" = "1" ]; then
60
+ echo "=== Dry Run: Roadmap Slicer ==="
61
+ echo "Provider: ${PROVIDER_CMD}"
62
+ echo "Project Dir: ${PROJECT_DIR}"
63
+ echo "Timeout: ${MAX_RUNTIME}s"
64
+ exit 0
65
+ fi
66
+
67
+ # Resolve night-watch CLI
68
+ CLI_BIN=""
69
+ if ! CLI_BIN=$(resolve_night_watch_cli); then
70
+ log "ERROR: Could not resolve night-watch CLI"
71
+ exit 1
72
+ fi
73
+
74
+ # Run the slice command with timeout
75
+ EXIT_CODE=0
76
+ if timeout "${MAX_RUNTIME}" "${CLI_BIN}" slice >> "${LOG_FILE}" 2>&1; then
77
+ EXIT_CODE=0
78
+ else
79
+ EXIT_CODE=$?
80
+ fi
81
+
82
+ if [ ${EXIT_CODE} -eq 0 ]; then
83
+ log "DONE: Slicer completed successfully"
84
+ elif [ ${EXIT_CODE} -eq 124 ]; then
85
+ log "TIMEOUT: Slicer killed after ${MAX_RUNTIME}s"
86
+ else
87
+ log "FAIL: Slicer exited with code ${EXIT_CODE}"
88
+ fi
89
+
90
+ exit ${EXIT_CODE}
@@ -0,0 +1,219 @@
1
+ You are a **PRD Creator Agent**. Your job: analyze the codebase and write a complete Product Requirements Document (PRD) for a feature.
2
+
3
+ When this activates: `PRD Creator: Initializing`
4
+
5
+ ---
6
+
7
+ ## Input
8
+
9
+ You are creating a PRD for the following roadmap item:
10
+
11
+ **Section:** {{SECTION}}
12
+ **Title:** {{TITLE}}
13
+ **Description:** {{DESCRIPTION}}
14
+
15
+ The PRD must be written to this exact file path:
16
+ **Output File:** `{{OUTPUT_FILE_PATH}}`
17
+
18
+ The PRD directory is: `{{PRD_DIR}}`
19
+
20
+ ---
21
+
22
+ ## Your Task
23
+
24
+ 1. **Explore the Codebase** - Read relevant existing files to understand the project structure, patterns, and conventions. Look for:
25
+ - CLAUDE.md or similar AI assistant documentation files
26
+ - Existing code patterns in the area you'll be modifying
27
+ - Related features or modules that this feature interacts with
28
+ - Test patterns and verification commands
29
+
30
+ 2. **Assess Complexity** - Score the complexity using the rubric below and determine whether this is LOW, MEDIUM, or HIGH complexity.
31
+
32
+ 3. **Write a Complete PRD** - Create a full PRD following the template structure below. The PRD must be actionable, with concrete file paths, implementation steps, and test specifications.
33
+
34
+ 4. **Write the PRD File** - Use the Write tool to create the PRD file at the exact path specified in `{{OUTPUT_FILE_PATH}}`.
35
+
36
+ ---
37
+
38
+ ## Complexity Scoring
39
+
40
+ ```
41
+ COMPLEXITY SCORE (sum all that apply):
42
+ +1 Touches 1-5 files
43
+ +2 Touches 6-10 files
44
+ +3 Touches 10+ files
45
+ +2 New system/module from scratch
46
+ +2 Complex state logic / concurrency
47
+ +2 Multi-package changes
48
+ +1 Database schema changes
49
+ +1 External API integration
50
+
51
+ | Score | Level | Template Mode |
52
+ | ----- | ------ | ----------------------------------------------- |
53
+ | 1-3 | LOW | Minimal (skip sections marked with MEDIUM/HIGH) |
54
+ | 4-6 | MEDIUM | Standard (all sections) |
55
+ | 7+ | HIGH | Full + mandatory checkpoints every phase |
56
+ ```
57
+
58
+ ---
59
+
60
+ ## PRD Template Structure
61
+
62
+ Your PRD MUST follow this exact structure:
63
+
64
+ ```markdown
65
+ # PRD: [Title from roadmap item]
66
+
67
+ **Depends on:** [List any prerequisite PRDs/files, or omit if none]
68
+
69
+ **Complexity: [SCORE] → [LEVEL] mode**
70
+
71
+ - [Complexity breakdown as bullet list]
72
+
73
+ ---
74
+
75
+ ## 1. Context
76
+
77
+ **Problem:** [1-2 sentences describing the issue being solved]
78
+
79
+ **Files Analyzed:**
80
+ - `path/to/file.ts` — [what the file does]
81
+ - [List all files you inspected before planning]
82
+
83
+ **Current Behavior:**
84
+ - [3-5 bullets describing current state]
85
+
86
+ ### Integration Points Checklist
87
+
88
+ **How will this feature be reached?**
89
+ - [ ] Entry point identified: [e.g., route, event, cron, CLI command]
90
+ - [ ] Caller file identified: [file that will invoke this new code]
91
+ - [ ] Registration/wiring needed: [e.g., add route to router, register handler, add menu item]
92
+
93
+ **Is this user-facing?**
94
+ - [ ] YES → UI components required (list them)
95
+ - [ ] NO → Internal/background feature (explain how it's triggered)
96
+
97
+ **Full user flow:**
98
+ 1. User does: [action]
99
+ 2. Triggers: [what code path]
100
+ 3. Reaches new feature via: [specific connection point]
101
+ 4. Result displayed in: [where user sees outcome]
102
+
103
+ ---
104
+
105
+ ## 2. Solution
106
+
107
+ **Approach:**
108
+ - [3-5 bullets explaining the chosen solution]
109
+
110
+ **Architecture Diagram** <!-- (MEDIUM/HIGH complexity) -->:
111
+
112
+ ```mermaid
113
+ flowchart LR
114
+ A[Component A] --> B[Component B] --> C[Component C]
115
+ ```
116
+
117
+ **Key Decisions:**
118
+ - [Library/framework choices, error-handling strategy, reused utilities]
119
+
120
+ **Data Changes:** [New schemas/migrations, or "None"]
121
+
122
+ ---
123
+
124
+ ## 3. Sequence Flow <!-- (MEDIUM/HIGH complexity) -->
125
+
126
+ ```mermaid
127
+ sequenceDiagram
128
+ participant A as Component A
129
+ participant B as Component B
130
+ A->>B: methodName(args)
131
+ alt Error case
132
+ B-->>A: ErrorType
133
+ else Success
134
+ B-->>A: Response
135
+ end
136
+ ```
137
+
138
+ ---
139
+
140
+ ## 4. Execution Phases
141
+
142
+ **CRITICAL RULES:**
143
+ 1. Each phase = ONE user-testable vertical slice
144
+ 2. Max 5 files per phase (split if larger)
145
+ 3. Each phase MUST include concrete tests
146
+ 4. Checkpoint after each phase (automated ALWAYS required)
147
+
148
+ ### Phase 1: [Name] — [User-visible outcome in 1 sentence]
149
+
150
+ **Files (max 5):**
151
+ - `src/path/file.ts` — [what changes]
152
+
153
+ **Implementation:**
154
+ - [ ] Step 1
155
+ - [ ] Step 2
156
+
157
+ **Tests Required:**
158
+ | Test File | Test Name | Assertion |
159
+ |-----------|-----------|-----------|
160
+ | `src/__tests__/feature.test.ts` | `should do X when Y` | `expect(result).toBe(Z)` |
161
+
162
+ **Verification Plan:**
163
+ 1. **Unit Tests:** File and test names
164
+ 2. **Integration Test:** (if applicable)
165
+ 3. **User Verification:**
166
+ - Action: [what to do]
167
+ - Expected: [what should happen]
168
+
169
+ **Checkpoint:** Run automated review after this phase completes.
170
+
171
+ ---
172
+
173
+ [Repeat for additional phases as needed]
174
+
175
+ ---
176
+
177
+ ## 5. Acceptance Criteria
178
+
179
+ - [ ] All phases complete
180
+ - [ ] All specified tests pass
181
+ - [ ] Verification commands pass
182
+ - [ ] All automated checkpoint reviews passed
183
+ - [ ] Feature is reachable (entry point connected, not orphaned code)
184
+ - [ ] [additional criterion specific to this feature]
185
+ - [ ] [additional criterion specific to this feature]
186
+ ```
187
+
188
+ ---
189
+
190
+ ## Critical Instructions
191
+
192
+ 1. **Read all relevant existing files BEFORE writing any code**
193
+ 2. **Follow existing patterns in the codebase**
194
+ 3. **Write the PRD with concrete file paths and implementation details**
195
+ 4. **Include specific test names and assertions**
196
+ 5. **Use the Write tool to create the PRD file at `{{OUTPUT_FILE_PATH}}`**
197
+ 6. **The PRD must be complete and actionable - no TODO placeholders**
198
+
199
+ DO NOT leave placeholder text like "[Name]" or "[description]" in the final PRD.
200
+ DO NOT skip any sections.
201
+ DO NOT forget to write the file.
202
+
203
+ ---
204
+
205
+ ## Output
206
+
207
+ After writing the PRD file, report:
208
+
209
+ ```markdown
210
+ ## PRD Creation Complete
211
+
212
+ **File:** {{OUTPUT_FILE_PATH}}
213
+ **Title:** [PRD title]
214
+ **Complexity:** [score] → [level]
215
+ **Phases:** [count]
216
+
217
+ ### Summary
218
+ [1-2 sentences summarizing the PRD content]
219
+ ```
@@ -5,6 +5,7 @@
5
5
  "provider": "claude",
6
6
  "reviewerEnabled": true,
7
7
  "prdDir": "docs/PRDs/night-watch",
8
+ "templatesDir": ".night-watch/templates",
8
9
  "maxRuntime": 7200,
9
10
  "reviewerMaxRuntime": 3600,
10
11
  "branchPrefix": "night-watch",